mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
f1d322a717
commit
3b155f9d52
@ -136,14 +136,8 @@ public class ActionSheetPeerItemNode: ActionSheetItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
||||
}
|
||||
|
||||
public override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||
|
||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
@ -160,8 +154,12 @@ public class ActionSheetPeerItemNode: ActionSheetItemNode {
|
||||
}
|
||||
|
||||
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
|
||||
@objc private func buttonPressed() {
|
||||
if let item = self.item {
|
||||
item.action()
|
||||
|
@ -213,14 +213,8 @@ public class BotCheckoutPaymentMethodItemNode: ActionSheetItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
||||
}
|
||||
|
||||
public override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||
|
||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
@ -242,6 +236,9 @@ public class BotCheckoutPaymentMethodItemNode: ActionSheetItemNode {
|
||||
if let image = self.checkNode.image {
|
||||
self.checkNode.frame = CGRect(origin: CGPoint(x: floor((44.0 - image.size.width) / 2.0), y: floor((size.height - image.size.height) / 2.0)), size: image.size)
|
||||
}
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
|
@ -190,15 +190,9 @@ public class BotCheckoutPaymentShippingOptionItemNode: ActionSheetItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
||||
}
|
||||
|
||||
public override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||
|
||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
var checkInset: CGFloat = 15.0
|
||||
@ -214,6 +208,9 @@ public class BotCheckoutPaymentShippingOptionItemNode: ActionSheetItemNode {
|
||||
if let image = self.checkNode.image {
|
||||
self.checkNode.frame = CGRect(origin: CGPoint(x: floor((44.0 - image.size.width) / 2.0), y: floor((size.height - image.size.height) / 2.0)), size: image.size)
|
||||
}
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
|
@ -128,14 +128,13 @@ private final class DateSelectionActionSheetItemNode: ActionSheetItemNode {
|
||||
self.pickerView.addTarget(self, action: #selector(self.datePickerUpdated), for: .valueChanged)
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 216.0)
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 216.0)
|
||||
|
||||
self.pickerView.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
self.pickerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: self.bounds.size.width, height: 216.0))
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc private func datePickerUpdated() {
|
||||
|
@ -152,7 +152,7 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let textSize = self.textNode.updateLayout(CGSize(width: constrainedSize.width - 20.0, height: .greatestFiniteMagnitude))
|
||||
|
||||
let topInset: CGFloat = 16.0
|
||||
@ -166,10 +166,7 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode {
|
||||
let size = CGSize(width: constrainedSize.width, height: topInset + avatarSize + textSpacing + textSize.height + bottomInset)
|
||||
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
}
|
||||
}
|
||||
|
@ -152,20 +152,17 @@ public class ActionSheetButtonNode: ActionSheetItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
||||
}
|
||||
|
||||
public override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||
|
||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
let labelSize = self.label.updateLayout(CGSize(width: max(1.0, size.width - 10.0), height: size.height))
|
||||
self.label.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - labelSize.width) / 2.0), y: floorToScreenPixels((size.height - labelSize.height) / 2.0)), size: labelSize)
|
||||
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
|
@ -136,15 +136,9 @@ public class ActionSheetCheckboxItemNode: ActionSheetItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
||||
}
|
||||
|
||||
public override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||
|
||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
var titleOrigin: CGFloat = 50.0
|
||||
@ -164,6 +158,9 @@ public class ActionSheetCheckboxItemNode: ActionSheetItemNode {
|
||||
}
|
||||
|
||||
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
|
@ -61,7 +61,7 @@ final class ActionSheetControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.itemGroupsContainerNode = ActionSheetItemGroupsContainerNode(theme: self.theme)
|
||||
|
||||
super.init()
|
||||
|
||||
|
||||
self.scrollView.delegate = self
|
||||
|
||||
self.addSubnode(self.scrollNode)
|
||||
@ -78,6 +78,12 @@ final class ActionSheetControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.scrollNode.addSubnode(self.itemGroupsContainerNode)
|
||||
|
||||
self.updateTheme()
|
||||
|
||||
self.itemGroupsContainerNode.requestLayout = { [weak self] in
|
||||
if let strongSelf = self, let layout = strongSelf.validLayout {
|
||||
strongSelf.containerLayoutUpdated(layout, transition: .animated(duration: 0.2, curve: .easeInOut))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func updateTheme() {
|
||||
@ -107,9 +113,9 @@ final class ActionSheetControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.scrollView.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||
self.dismissTapView.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||
|
||||
self.itemGroupsContainerNode.measure(CGSize(width: layout.size.width - containerInsets.left - containerInsets.right - insets.left - insets.right, height: layout.size.height - containerInsets.top - containerInsets.bottom - insets.top - insets.bottom))
|
||||
let itemGroupsContainerSize = self.itemGroupsContainerNode.updateLayout(constrainedSize: CGSize(width: layout.size.width - containerInsets.left - containerInsets.right - insets.left - insets.right, height: layout.size.height - containerInsets.top - containerInsets.bottom - insets.top - insets.bottom), transition: transition)
|
||||
|
||||
if self.allowInputInset, let inputHeight = layout.inputHeight, inputHeight > 0.0, self.itemGroupsContainerNode.groupNodes.count > 1, let lastGroupHeight = self.itemGroupsContainerNode.groupNodes.last?.calculatedSize.height {
|
||||
if self.allowInputInset, let inputHeight = layout.inputHeight, inputHeight > 0.0, self.itemGroupsContainerNode.groupNodes.count > 1, let lastGroupHeight = self.itemGroupsContainerNode.groupNodes.last?.frame.height {
|
||||
insets.bottom -= lastGroupHeight + containerInsets.bottom
|
||||
}
|
||||
|
||||
@ -117,8 +123,7 @@ final class ActionSheetControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
if !self.allowInputInset {
|
||||
transition = .immediate
|
||||
}
|
||||
transition.updateFrame(node: self.itemGroupsContainerNode, frame: CGRect(origin: CGPoint(x: insets.left + containerInsets.left, y: layout.size.height - insets.bottom - containerInsets.bottom - self.itemGroupsContainerNode.calculatedSize.height), size: self.itemGroupsContainerNode.calculatedSize))
|
||||
self.itemGroupsContainerNode.updateLayout(transition: transition)
|
||||
transition.updateFrame(node: self.itemGroupsContainerNode, frame: CGRect(origin: CGPoint(x: insets.left + containerInsets.left, y: layout.size.height - insets.bottom - containerInsets.bottom - itemGroupsContainerSize.height), size: itemGroupsContainerSize))
|
||||
|
||||
self.updateScrollDimViews(size: layout.size, insets: insets, transition: transition)
|
||||
}
|
||||
|
@ -15,7 +15,9 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
|
||||
private var itemNodes: [ActionSheetItemNode] = []
|
||||
private var leadingVisibleNodeCount: CGFloat = 100.0
|
||||
|
||||
|
||||
private var validLayout: CGSize?
|
||||
|
||||
init(theme: ActionSheetControllerTheme) {
|
||||
self.theme = theme
|
||||
|
||||
@ -81,45 +83,8 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.leadingVisibleNodeCount = leadingVisibleNodeCount
|
||||
self.invalidateCalculatedLayout()
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
var itemNodesHeight: CGFloat = 0.0
|
||||
var leadingVisibleNodeSize: CGFloat = 0.0
|
||||
|
||||
var i = 0
|
||||
for node in self.itemNodes {
|
||||
if CGFloat(0.0).isLess(than: itemNodesHeight), node.hasSeparator {
|
||||
itemNodesHeight += UIScreenPixel
|
||||
}
|
||||
let size = node.measure(constrainedSize)
|
||||
itemNodesHeight += size.height
|
||||
|
||||
if ceil(CGFloat(i)).isLessThanOrEqualTo(leadingVisibleNodeCount) {
|
||||
if CGFloat(0.0).isLess(than: leadingVisibleNodeSize), node.hasSeparator {
|
||||
leadingVisibleNodeSize += UIScreenPixel
|
||||
}
|
||||
let factor: CGFloat = min(1.0, leadingVisibleNodeCount - CGFloat(i))
|
||||
leadingVisibleNodeSize += size.height * factor
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
|
||||
return CGSize(width: constrainedSize.width, height: min(floorToScreenPixels(itemNodesHeight), constrainedSize.height))
|
||||
}
|
||||
|
||||
func updateLayout(transition: ContainedViewLayoutTransition) {
|
||||
let scrollViewFrame = CGRect(origin: CGPoint(), size: self.calculatedSize)
|
||||
var updateOffset = false
|
||||
if !self.scrollNode.frame.equalTo(scrollViewFrame) {
|
||||
self.scrollNode.frame = scrollViewFrame
|
||||
updateOffset = true
|
||||
}
|
||||
|
||||
let backgroundEffectViewFrame = CGRect(origin: CGPoint(), size: self.calculatedSize)
|
||||
if !self.backgroundEffectView.frame.equalTo(backgroundEffectViewFrame) {
|
||||
transition.updateFrame(view: self.backgroundEffectView, frame: backgroundEffectViewFrame)
|
||||
}
|
||||
|
||||
func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
var itemNodesHeight: CGFloat = 0.0
|
||||
var leadingVisibleNodeSize: CGFloat = 0.0
|
||||
|
||||
@ -130,24 +95,42 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
itemNodesHeight += UIScreenPixel
|
||||
}
|
||||
previousHadSeparator = node.hasSeparator
|
||||
node.frame = CGRect(origin: CGPoint(x: 0.0, y: itemNodesHeight), size: node.calculatedSize)
|
||||
itemNodesHeight += node.calculatedSize.height
|
||||
|
||||
let nodeSize = node.updateLayout(constrainedSize: CGSize(width: constrainedSize.width, height: constrainedSize.height - itemNodesHeight), transition: transition)
|
||||
node.frame = CGRect(origin: CGPoint(x: 0.0, y: itemNodesHeight), size: nodeSize)
|
||||
|
||||
itemNodesHeight += nodeSize.height
|
||||
|
||||
if CGFloat(i).isLessThanOrEqualTo(leadingVisibleNodeCount) {
|
||||
if CGFloat(0.0).isLess(than: leadingVisibleNodeSize), node.hasSeparator {
|
||||
leadingVisibleNodeSize += UIScreenPixel
|
||||
}
|
||||
let factor: CGFloat = min(1.0, leadingVisibleNodeCount - CGFloat(i))
|
||||
leadingVisibleNodeSize += node.calculatedSize.height * factor
|
||||
leadingVisibleNodeSize += nodeSize.height * factor
|
||||
}
|
||||
i += 1
|
||||
}
|
||||
|
||||
let scrollViewContentSize = CGSize(width: self.calculatedSize.width, height: itemNodesHeight)
|
||||
let size = CGSize(width: constrainedSize.width, height: min(floorToScreenPixels(itemNodesHeight), constrainedSize.height))
|
||||
self.validLayout = size
|
||||
|
||||
let scrollViewFrame = CGRect(origin: CGPoint(), size: size)
|
||||
var updateOffset = false
|
||||
if !self.scrollNode.frame.equalTo(scrollViewFrame) {
|
||||
self.scrollNode.frame = scrollViewFrame
|
||||
updateOffset = true
|
||||
}
|
||||
|
||||
let backgroundEffectViewFrame = CGRect(origin: CGPoint(), size: size)
|
||||
if !self.backgroundEffectView.frame.equalTo(backgroundEffectViewFrame) {
|
||||
transition.updateFrame(view: self.backgroundEffectView, frame: backgroundEffectViewFrame)
|
||||
}
|
||||
|
||||
let scrollViewContentSize = CGSize(width: size.width, height: itemNodesHeight)
|
||||
if !self.scrollNode.view.contentSize.equalTo(scrollViewContentSize) {
|
||||
self.scrollNode.view.contentSize = scrollViewContentSize
|
||||
}
|
||||
let scrollViewContentInsets = UIEdgeInsets(top: max(0.0, self.calculatedSize.height - leadingVisibleNodeSize), left: 0.0, bottom: 0.0, right: 0.0)
|
||||
let scrollViewContentInsets = UIEdgeInsets(top: max(0.0, size.height - leadingVisibleNodeSize), left: 0.0, bottom: 0.0, right: 0.0)
|
||||
|
||||
if self.scrollNode.view.contentInset != scrollViewContentInsets {
|
||||
self.scrollNode.view.contentInset = scrollViewContentInsets
|
||||
@ -157,7 +140,9 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
self.scrollNode.view.contentOffset = CGPoint(x: 0.0, y: -scrollViewContentInsets.top)
|
||||
}
|
||||
|
||||
self.updateOverscroll(transition: transition)
|
||||
self.updateOverscroll(size: size, transition: transition)
|
||||
|
||||
return size
|
||||
}
|
||||
|
||||
private func currentVerticalOverscroll() -> CGFloat {
|
||||
@ -180,11 +165,11 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
return verticalOverscroll
|
||||
}
|
||||
|
||||
private func updateOverscroll(transition: ContainedViewLayoutTransition) {
|
||||
private func updateOverscroll(size: CGSize, transition: ContainedViewLayoutTransition) {
|
||||
let verticalOverscroll = self.currentVerticalOverscroll()
|
||||
|
||||
self.clippingNode.layer.sublayerTransform = CATransform3DMakeTranslation(0.0, min(0.0, verticalOverscroll), 0.0)
|
||||
let clippingNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: max(0.0, -verticalOverscroll)), size: CGSize(width: self.calculatedSize.width, height: self.calculatedSize.height - abs(verticalOverscroll)))
|
||||
let clippingNodeFrame = CGRect(origin: CGPoint(x: 0.0, y: max(0.0, -verticalOverscroll)), size: CGSize(width: size.width, height: size.height - abs(verticalOverscroll)))
|
||||
if !self.clippingNode.frame.equalTo(clippingNodeFrame) {
|
||||
transition.updateFrame(node: self.clippingNode, frame: clippingNodeFrame)
|
||||
|
||||
@ -195,7 +180,9 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
}
|
||||
|
||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
self.updateOverscroll(transition: .immediate)
|
||||
if let size = self.validLayout {
|
||||
self.updateOverscroll(size: size, transition: .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
|
@ -14,6 +14,8 @@ final class ActionSheetItemGroupsContainerNode: ASDisplayNode {
|
||||
private var groups: [ActionSheetItemGroup] = []
|
||||
var groupNodes: [ActionSheetItemGroupNode] = []
|
||||
|
||||
var requestLayout: (() -> Void)?
|
||||
|
||||
init(theme: ActionSheetControllerTheme) {
|
||||
self.theme = theme
|
||||
|
||||
@ -30,46 +32,49 @@ final class ActionSheetItemGroupsContainerNode: ASDisplayNode {
|
||||
|
||||
for group in groups {
|
||||
let groupNode = ActionSheetItemGroupNode(theme: self.theme)
|
||||
groupNode.updateItemNodes(group.items.map({ $0.node(theme: self.theme) }), leadingVisibleNodeCount: group.leadingVisibleNodeCount ?? 1000.0)
|
||||
let itemNodes = group.items.map({ $0.node(theme: self.theme) })
|
||||
|
||||
for node in itemNodes {
|
||||
node.requestLayout = { [weak self] in
|
||||
self?.requestLayout?()
|
||||
}
|
||||
}
|
||||
groupNode.updateItemNodes(itemNodes, leadingVisibleNodeCount: group.leadingVisibleNodeCount ?? 1000.0)
|
||||
self.groupNodes.append(groupNode)
|
||||
self.addSubnode(groupNode)
|
||||
}
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
var groupsHeight: CGFloat = 0.0
|
||||
|
||||
var calculatedSizes: [CGSize] = []
|
||||
for groupNode in self.groupNodes.reversed() {
|
||||
if CGFloat(0.0).isLess(than: groupsHeight) {
|
||||
groupsHeight += groupSpacing
|
||||
}
|
||||
|
||||
let size = groupNode.measure(CGSize(width: constrainedSize.width, height: max(0.0, constrainedSize.height - groupsHeight)))
|
||||
let size = groupNode.updateLayout(constrainedSize: CGSize(width: constrainedSize.width, height: max(0.0, constrainedSize.height - groupsHeight)), transition: transition)
|
||||
calculatedSizes.insert(size, at: 0)
|
||||
|
||||
groupsHeight += size.height
|
||||
}
|
||||
|
||||
return CGSize(width: constrainedSize.width, height: min(groupsHeight, constrainedSize.height))
|
||||
}
|
||||
|
||||
func updateLayout(transition: ContainedViewLayoutTransition) {
|
||||
var groupsHeight: CGFloat = 0.0
|
||||
var itemGroupsHeight: CGFloat = 0.0
|
||||
for i in 0 ..< self.groupNodes.count {
|
||||
let groupNode = self.groupNodes[i]
|
||||
|
||||
let size = groupNode.calculatedSize
|
||||
|
||||
|
||||
let size = calculatedSizes[i]
|
||||
if i != 0 {
|
||||
groupsHeight += groupSpacing
|
||||
itemGroupsHeight += groupSpacing
|
||||
transition.updateFrame(view: self.groupNodes[i - 1].trailingDimView, frame: CGRect(x: 0.0, y: groupNodes[i - 1].bounds.size.height, width: size.width, height: groupSpacing))
|
||||
}
|
||||
|
||||
groupNode.updateLayout(transition: transition)
|
||||
transition.updateFrame(node: groupNode, frame: CGRect(origin: CGPoint(x: 0.0, y: groupsHeight), size: size))
|
||||
|
||||
transition.updateFrame(node: groupNode, frame: CGRect(origin: CGPoint(x: 0.0, y: itemGroupsHeight), size: size))
|
||||
transition.updateFrame(view: groupNode.trailingDimView, frame: CGRect())
|
||||
|
||||
groupsHeight += size.height
|
||||
itemGroupsHeight += size.height
|
||||
}
|
||||
return CGSize(width: constrainedSize.width, height: min(groupsHeight, constrainedSize.height))
|
||||
}
|
||||
|
||||
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||
|
@ -26,13 +26,15 @@ open class ActionSheetItemNode: ASDisplayNode {
|
||||
self.addSubnode(self.overflowSeparatorNode)
|
||||
}
|
||||
|
||||
open override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
||||
open func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
open override func layout() {
|
||||
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: self.calculatedSize)
|
||||
self.overflowSeparatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: self.calculatedSize.height), size: CGSize(width: self.calculatedSize.width, height: UIScreenPixel))
|
||||
public func updateInternalLayout(_ calculatedSize: CGSize) {
|
||||
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: calculatedSize)
|
||||
self.overflowSeparatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: calculatedSize.height), size: CGSize(width: calculatedSize.width, height: UIScreenPixel))
|
||||
self.overflowSeparatorNode.isHidden = !self.hasSeparator
|
||||
}
|
||||
}
|
||||
|
@ -103,15 +103,9 @@ public class ActionSheetSwitchNode: ActionSheetItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
||||
}
|
||||
|
||||
public override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||
|
||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
let labelSize = self.label.updateLayout(CGSize(width: max(1.0, size.width - 51.0 - 16.0 * 2.0), height: size.height))
|
||||
@ -121,6 +115,9 @@ public class ActionSheetSwitchNode: ActionSheetItemNode {
|
||||
self.switchNode.frame = CGRect(origin: CGPoint(x: size.width - 16.0 - switchSize.width, y: floor((size.height - switchSize.height) / 2.0)), size: switchSize)
|
||||
|
||||
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
|
@ -69,19 +69,15 @@ public class ActionSheetTextNode: ActionSheetItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let labelSize = self.label.updateLayout(CGSize(width: max(1.0, constrainedSize.width - 20.0), height: constrainedSize.height))
|
||||
return CGSize(width: constrainedSize.width, height: max(57.0, labelSize.height + 32.0))
|
||||
}
|
||||
|
||||
public override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
|
||||
let labelSize = self.label.updateLayout(CGSize(width: max(1.0, size.width - 20.0), height: size.height))
|
||||
let size = CGSize(width: constrainedSize.width, height: max(57.0, labelSize.height + 32.0))
|
||||
|
||||
self.label.frame = CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - labelSize.width) / 2.0), y: floorToScreenPixels((size.height - labelSize.height) / 2.0)), size: labelSize)
|
||||
|
||||
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
@ -585,8 +585,10 @@ public func inviteLinkListController(context: AccountContext, peerId: PeerId, ad
|
||||
} else {
|
||||
isGroup = true
|
||||
}
|
||||
let controller = InviteLinkQRCodeController(context: context, invite: invite, isGroup: isGroup)
|
||||
presentControllerImpl?(controller, nil)
|
||||
Queue.mainQueue().after(0.2) {
|
||||
let controller = InviteLinkQRCodeController(context: context, invite: invite, isGroup: isGroup)
|
||||
presentControllerImpl?(controller, nil)
|
||||
}
|
||||
})
|
||||
})))
|
||||
|
||||
@ -727,15 +729,21 @@ public func inviteLinkListController(context: AccountContext, peerId: PeerId, ad
|
||||
timer.start()
|
||||
|
||||
let previousRevokedInvites = Atomic<PeerExportedInvitationsState?>(value: nil)
|
||||
let previousCreators = Atomic<[ExportedInvitationCreator]?>(value: nil)
|
||||
|
||||
let signal = combineLatest(context.sharedContext.presentationData, peerView, importersContext, importersState.get(), invitesContext.state, revokedInvitesContext.state, creators, timerPromise.get())
|
||||
|> deliverOnMainQueue
|
||||
|> map { presentationData, view, importersContext, importers, invites, revokedInvites, creators, tick -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||
let previousRevokedInvites = previousRevokedInvites.swap(invites)
|
||||
let previousCreators = previousCreators.swap(creators)
|
||||
|
||||
var crossfade = false
|
||||
if (previousRevokedInvites?.hasLoadedOnce ?? false) != (revokedInvites.hasLoadedOnce) {
|
||||
crossfade = true
|
||||
}
|
||||
if (previousCreators?.count ?? 0) != creators.count {
|
||||
crossfade = true
|
||||
}
|
||||
|
||||
let title: ItemListControllerTitle
|
||||
if let admin = admin, let peer = admin.peer.peer {
|
||||
|
@ -45,6 +45,8 @@ private struct InviteLinkViewTransaction {
|
||||
let insertions: [ListViewInsertItem]
|
||||
let updates: [ListViewUpdateItem]
|
||||
let isLoading: Bool
|
||||
let animated: Bool
|
||||
let crossfade: Bool
|
||||
}
|
||||
|
||||
private enum InviteLinkViewEntryId: Hashable {
|
||||
@ -195,14 +197,14 @@ private enum InviteLinkViewEntry: Comparable, Identifiable {
|
||||
}
|
||||
}
|
||||
|
||||
private func preparedTransition(from fromEntries: [InviteLinkViewEntry], to toEntries: [InviteLinkViewEntry], isLoading: Bool, account: Account, presentationData: PresentationData, interaction: InviteLinkViewInteraction) -> InviteLinkViewTransaction {
|
||||
private func preparedTransition(from fromEntries: [InviteLinkViewEntry], to toEntries: [InviteLinkViewEntry], isLoading: Bool, animated: Bool, crossfade: Bool, account: Account, presentationData: PresentationData, interaction: InviteLinkViewInteraction) -> InviteLinkViewTransaction {
|
||||
let (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
||||
|
||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
||||
let insertions = indicesAndItems.map { ListViewInsertItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, presentationData: presentationData, interaction: interaction), directionHint: nil) }
|
||||
let updates = updateIndices.map { ListViewUpdateItem(index: $0.0, previousIndex: $0.2, item: $0.1.item(account: account, presentationData: presentationData, interaction: interaction), directionHint: nil) }
|
||||
|
||||
return InviteLinkViewTransaction(deletions: deletions, insertions: insertions, updates: updates, isLoading: isLoading)
|
||||
return InviteLinkViewTransaction(deletions: deletions, insertions: insertions, updates: updates, isLoading: isLoading, animated: animated, crossfade: crossfade)
|
||||
}
|
||||
|
||||
private let titleFont = Font.bold(17.0)
|
||||
@ -535,6 +537,8 @@ public final class InviteLinkViewController: ViewController {
|
||||
})
|
||||
|
||||
let previousEntries = Atomic<[InviteLinkViewEntry]?>(value: nil)
|
||||
let previousCount = Atomic<Int32?>(value: nil)
|
||||
let previousLoading = Atomic<Bool?>(value: nil)
|
||||
|
||||
let creatorPeer = context.account.postbox.loadedPeerWithId(invite.adminId)
|
||||
self.disposable = (combineLatest(self.presentationDataPromise.get(), self.importersContext.state, creatorPeer)
|
||||
@ -561,13 +565,20 @@ public final class InviteLinkViewController: ViewController {
|
||||
entries.append(.importerHeader(presentationData.theme, presentationData.strings.InviteLink_PeopleJoined(Int32(state.count)).uppercased(), subtitle, subtitleExpired))
|
||||
}
|
||||
|
||||
let count: Int32
|
||||
let loading: Bool
|
||||
|
||||
var index: Int32 = 0
|
||||
if state.importers.isEmpty && state.isLoadingMore {
|
||||
count = min(4, state.count)
|
||||
loading = true
|
||||
let fakeUser = TelegramUser(id: PeerId(namespace: -1, id: 0), accessHash: nil, firstName: "", lastName: "", username: nil, phone: nil, photo: [], botInfo: nil, restrictionInfo: nil, flags: [])
|
||||
for i in 0 ..< min(4, state.count) {
|
||||
for i in 0 ..< count {
|
||||
entries.append(.importer(Int32(i), presentationData.theme, presentationData.dateTimeFormat, fakeUser, 0, true))
|
||||
}
|
||||
} else {
|
||||
count = min(4, Int32(state.importers.count))
|
||||
loading = false
|
||||
for importer in state.importers {
|
||||
if let peer = importer.peer.peer {
|
||||
entries.append(.importer(index, presentationData.theme, presentationData.dateTimeFormat, peer, importer.date, false))
|
||||
@ -576,9 +587,21 @@ public final class InviteLinkViewController: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
let previousCount = previousCount.swap(count)
|
||||
let previousLoading = previousLoading.swap(loading)
|
||||
|
||||
var animated = false
|
||||
var crossfade = false
|
||||
if let previousCount = previousCount, let previousLoading = previousLoading {
|
||||
if (previousCount == count || previousCount >= 4) && previousLoading && !loading {
|
||||
crossfade = true
|
||||
} else if previousCount < 4 && previousCount != count && !loading {
|
||||
animated = true
|
||||
}
|
||||
}
|
||||
let previousEntries = previousEntries.swap(entries)
|
||||
|
||||
let transition = preparedTransition(from: previousEntries ?? [], to: entries, isLoading: false, account: context.account, presentationData: presentationData, interaction: strongSelf.interaction!)
|
||||
let transition = preparedTransition(from: previousEntries ?? [], to: entries, isLoading: false, animated: animated, crossfade: crossfade, account: context.account, presentationData: presentationData, interaction: strongSelf.interaction!)
|
||||
strongSelf.enqueueTransition(transition)
|
||||
}
|
||||
})
|
||||
@ -700,7 +723,11 @@ public final class InviteLinkViewController: ViewController {
|
||||
}
|
||||
self.enqueuedTransitions.remove(at: 0)
|
||||
|
||||
self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: ListViewDeleteAndInsertOptions(), updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { _ in
|
||||
var options = ListViewDeleteAndInsertOptions()
|
||||
if transition.animated {
|
||||
options.insert(.AnimateInsertion)
|
||||
}
|
||||
self.listNode.transaction(deleteIndices: transition.deletions, insertIndicesAndItems: transition.insertions, updateIndicesAndItems: transition.updates, options: options, updateSizeAndInsets: nil, updateOpaqueState: nil, completion: { _ in
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -195,7 +195,7 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode {
|
||||
|
||||
self.offsetContainerNode = ASDisplayNode()
|
||||
|
||||
self.iconBackgroundNode = ASImageNode()
|
||||
self.iconBackgroundNode = ASDisplayNode()
|
||||
self.iconBackgroundNode.setLayerBlock { () -> CALayer in
|
||||
return CAShapeLayer()
|
||||
}
|
||||
|
@ -163,19 +163,13 @@ private final class OpenInActionSheetItemNode: ActionSheetItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 148.0)
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 148.0)
|
||||
|
||||
let titleSize = self.titleNode.measure(size)
|
||||
self.titleNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 16.0), size: CGSize(width: size.width, height: titleSize.height))
|
||||
|
||||
let bounds = self.bounds
|
||||
|
||||
let titleSize = self.titleNode.measure(bounds.size)
|
||||
self.titleNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 16.0), size: CGSize(width: bounds.size.width, height: titleSize.height))
|
||||
|
||||
self.scrollNode.frame = CGRect(origin: CGPoint(x: 0, y: 36.0), size: CGSize(width: bounds.size.width, height: bounds.height - 36.0))
|
||||
self.scrollNode.frame = CGRect(origin: CGPoint(x: 0, y: 36.0), size: CGSize(width: size.width, height: size.height - 36.0))
|
||||
|
||||
let nodeInset: CGFloat = 2.0
|
||||
let nodeSize = CGSize(width: 80.0, height: 112.0)
|
||||
@ -192,6 +186,9 @@ private final class OpenInActionSheetItemNode: ActionSheetItemNode {
|
||||
self.scrollNode.view.contentSize = contentSize
|
||||
}
|
||||
}
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ private final class ChannelDiscussionGroupActionSheetItemNode: ActionSheetItemNo
|
||||
self.textNode.attributedText = attributedText
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let textSize = self.textNode.updateLayout(CGSize(width: constrainedSize.width - 20.0, height: .greatestFiniteMagnitude))
|
||||
|
||||
let topInset: CGFloat = 16.0
|
||||
@ -105,10 +105,9 @@ private final class ChannelDiscussionGroupActionSheetItemNode: ActionSheetItemNo
|
||||
|
||||
self.textNode.frame = CGRect(origin: CGPoint(x: floor((constrainedSize.width - textSize.width) / 2.0), y: topInset + avatarSize + textSpacing), size: textSize)
|
||||
|
||||
return CGSize(width: constrainedSize.width, height: topInset + avatarSize + textSpacing + textSize.height + bottomInset)
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
let size = CGSize(width: constrainedSize.width, height: topInset + avatarSize + textSpacing + textSize.height + bottomInset)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
@ -111,14 +111,13 @@ private final class PeerBanTimeoutActionSheetItemNode: ActionSheetItemNode {
|
||||
self.pickerView.addTarget(self, action: #selector(self.datePickerUpdated), for: .valueChanged)
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 216.0)
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 216.0)
|
||||
|
||||
self.pickerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: self.bounds.size.width, height: 216.0))
|
||||
self.pickerView.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc private func datePickerUpdated() {
|
||||
|
@ -152,11 +152,11 @@ public func peerReportOptionsController(context: AccountContext, subject: PeerRe
|
||||
case .copyright:
|
||||
reportReason = .copyright
|
||||
case .other:
|
||||
break
|
||||
reportReason = .custom
|
||||
}
|
||||
if let reportReason = reportReason {
|
||||
var passthrough = passthrough
|
||||
if case .fake = reportReason {
|
||||
if [.fake, .custom].contains(reportReason) {
|
||||
passthrough = false
|
||||
}
|
||||
switch subject {
|
||||
@ -169,7 +169,7 @@ public func peerReportOptionsController(context: AccountContext, subject: PeerRe
|
||||
if let path = getAppBundle().path(forResource: "PoliceCar", ofType: "tgs") {
|
||||
present(UndoOverlayController(presentationData: presentationData, content: .emoji(path: path, text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), nil)
|
||||
}
|
||||
completion(reportReason, true)
|
||||
completion(nil, false)
|
||||
})
|
||||
}
|
||||
case let .messages(messageIds):
|
||||
@ -181,7 +181,7 @@ public func peerReportOptionsController(context: AccountContext, subject: PeerRe
|
||||
if let path = getAppBundle().path(forResource: "PoliceCar", ofType: "tgs") {
|
||||
present(UndoOverlayController(presentationData: presentationData, content: .emoji(path: path, text: presentationData.strings.Report_Succeed), elevatedLayout: false, action: { _ in return false }), nil)
|
||||
}
|
||||
completion(reportReason, true)
|
||||
completion(nil, false)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -242,14 +242,8 @@ private final class ProxyServerInfoItemNode: ActionSheetItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 36.0 * CGFloat(self.fieldNodes.count) + 12.0)
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 36.0 * CGFloat(self.fieldNodes.count) + 12.0)
|
||||
|
||||
var offset: CGFloat = 15.0
|
||||
for (lhs, rhs) in self.fieldNodes {
|
||||
@ -261,6 +255,9 @@ private final class ProxyServerInfoItemNode: ActionSheetItemNode {
|
||||
|
||||
offset += 36.0
|
||||
}
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
||||
@ -360,14 +357,8 @@ private final class ProxyServerActionItemNode: ActionSheetItemNode {
|
||||
}
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||
|
||||
self.buttonNode.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
@ -376,8 +367,11 @@ private final class ProxyServerActionItemNode: ActionSheetItemNode {
|
||||
let activitySize = self.activityIndicator.measure(CGSize(width: 100.0, height: 100.0))
|
||||
self.titleNode.frame = titleFrame
|
||||
self.activityIndicator.frame = CGRect(origin: CGPoint(x: 14.0, y: titleFrame.minY - 0.0), size: activitySize)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
|
||||
@objc private func buttonPressed() {
|
||||
let proxyServerSettings = self.server
|
||||
let _ = (self.accountManager.transaction { transaction -> ProxySettings in
|
||||
|
@ -115,14 +115,13 @@ private final class ThemeAutoNightTimeSelectionActionSheetItemNode: ActionSheetI
|
||||
self.pickerView.addTarget(self, action: #selector(self.datePickerUpdated), for: .valueChanged)
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 216.0)
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 216.0)
|
||||
|
||||
self.pickerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: self.bounds.size.width, height: 216.0))
|
||||
self.pickerView.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc private func datePickerUpdated() {
|
||||
|
@ -112,14 +112,8 @@ public class LocationBroadcastActionSheetItemNode: ActionSheetItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
||||
}
|
||||
|
||||
public override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||
|
||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
@ -133,6 +127,9 @@ public class LocationBroadcastActionSheetItemNode: ActionSheetItemNode {
|
||||
|
||||
let timerSize = CGSize(width: 28.0, height: 28.0)
|
||||
self.timerNode.frame = CGRect(origin: CGPoint(x: size.width - 16.0 - timerSize.width, y: floorToScreenPixels((size.height - timerSize.height) / 2.0)), size: timerSize)
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
|
@ -136,14 +136,8 @@ public class CallRouteActionSheetItemNode: ActionSheetItemNode {
|
||||
self.setNeedsLayout()
|
||||
}
|
||||
|
||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
||||
}
|
||||
|
||||
public override func layout() {
|
||||
super.layout()
|
||||
|
||||
let size = self.bounds.size
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||
|
||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
@ -157,6 +151,9 @@ public class CallRouteActionSheetItemNode: ActionSheetItemNode {
|
||||
if let image = self.checkNode.image {
|
||||
self.checkNode.frame = CGRect(origin: CGPoint(x: size.width - image.size.width - 13.0, y: floor((size.height - image.size.height) / 2.0)), size: image.size)
|
||||
}
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc func buttonPressed() {
|
||||
|
@ -39,7 +39,7 @@ public func dismissServerProvidedSuggestion(account: Account, suggestion: Server
|
||||
|
||||
|
||||
public enum PeerSpecificServerProvidedSuggestion: String {
|
||||
case convertToGigagroup = "CONVERT_TO_GIGAGROUP"
|
||||
case convertToGigagroup = "CONVERT_GIGAGROUP"
|
||||
}
|
||||
|
||||
public func getPeerSpecificServerProvidedSuggestions(postbox: Postbox, peerId: PeerId) -> Signal<[PeerSpecificServerProvidedSuggestion], NoError> {
|
||||
|
@ -37,7 +37,7 @@ public func presentationStringsFormattedNumber(_ count: Int32, _ groupingSeparat
|
||||
}
|
||||
}
|
||||
|
||||
public func timeIntervalString(strings: PresentationStrings, value: Int32) -> String {
|
||||
public func timeIntervalString(strings: PresentationStrings, value: Int32, roundToNearest: Bool = false) -> String {
|
||||
if value < 60 {
|
||||
return strings.MessageTimer_Seconds(max(1, value))
|
||||
} else if value < 60 * 60 {
|
||||
|
@ -1515,7 +1515,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: savedMessages, text: text), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -7080,9 +7080,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(13.0), textColor: presentationData.theme.actionSheet.primaryTextColor)
|
||||
let attributedText = parseMarkdownIntoAttributedString(presentationData.strings.BroadcastGroups_ConfirmationAlert_Text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in return nil }), textAlignment: .center)
|
||||
|
||||
let alertController = richTextAlertController(context: context, title: attributedTitle, text: attributedText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .defaultAction, title: presentationData.strings.BroadcastGroups_ConfirmationAlert_Convert, action: { [weak controller] in
|
||||
let alertController = richTextAlertController(context: context, title: attributedTitle, text: attributedText, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||
let _ = dismissPeerSpecificServerProvidedSuggestion(account: context.account, peerId: peerId, suggestion: .convertToGigagroup).start()
|
||||
}), TextAlertAction(type: .defaultAction, title: presentationData.strings.BroadcastGroups_ConfirmationAlert_Convert, action: { [weak controller] in
|
||||
controller?.dismiss()
|
||||
|
||||
let _ = dismissPeerSpecificServerProvidedSuggestion(account: context.account, peerId: peerId, suggestion: .convertToGigagroup).start()
|
||||
|
||||
let _ = (convertGroupToGigagroup(account: context.account, peerId: peerId)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
|
||||
@ -10395,7 +10399,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
strongController.dismiss()
|
||||
} else if peerId == strongSelf.context.account.peerId {
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .forward(savedMessages: true, text: messages.count == 1 ? presentationData.strings.Conversation_ForwardTooltip_SavedMessages_One : presentationData.strings.Conversation_ForwardTooltip_SavedMessages_Many), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||
|
||||
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messages.map { message -> EnqueueMessage in
|
||||
return .forward(source: message.id, grouping: .auto, attributes: [])
|
||||
|
@ -103,14 +103,13 @@ private final class ChatDateSelectorItemNode: ActionSheetItemNode {
|
||||
self.pickerView.addTarget(self, action: #selector(self.pickerChanged), for: .valueChanged)
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 157.0)
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 157.0)
|
||||
|
||||
self.pickerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: self.bounds.size.width, height: 180.0))
|
||||
self.pickerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: 180.0))
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
@objc func pickerChanged() {
|
||||
|
@ -150,10 +150,6 @@ private final class AutoremoveTimeoutSelectorItemNode: ActionSheetItemNode, UIPi
|
||||
self.pickerView.selectRow(index, inComponent: 0, animated: false)
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
return CGSize(width: constrainedSize.width, height: 180.0)
|
||||
}
|
||||
|
||||
func numberOfComponents(in pickerView: UIPickerView) -> Int {
|
||||
return 1
|
||||
}
|
||||
@ -178,9 +174,12 @@ private final class AutoremoveTimeoutSelectorItemNode: ActionSheetItemNode, UIPi
|
||||
self.valueChanged(self.timeoutValues[row])
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let size = CGSize(width: constrainedSize.width, height: 180.0)
|
||||
|
||||
self.pickerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: self.bounds.size.width, height: 180.0))
|
||||
self.pickerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: 180.0))
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
@ -1201,7 +1201,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
||||
}))
|
||||
}
|
||||
|
||||
if channel.flags.contains(.isCreator) || (channel.adminRights?.flags.contains(.canInviteUsers) == true) {
|
||||
if (channel.flags.contains(.isCreator) && (channel.username?.isEmpty ?? true)) || (channel.adminRights?.flags.contains(.canInviteUsers) == true) {
|
||||
let invitesText: String
|
||||
if let count = data.invitations?.count, count > 0 {
|
||||
invitesText = "\(count)"
|
||||
@ -1340,7 +1340,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
||||
}
|
||||
}
|
||||
|
||||
if isCreator || (channel.adminRights?.flags.contains(.canInviteUsers) == true) {
|
||||
if (isCreator && (channel.username?.isEmpty ?? true)) || (channel.adminRights?.flags.contains(.canInviteUsers) == true) {
|
||||
let invitesText: String
|
||||
if let count = data.invitations?.count, count > 0 {
|
||||
invitesText = "\(count)"
|
||||
@ -1438,17 +1438,19 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
||||
activePermissionCount = count
|
||||
}
|
||||
|
||||
let invitesText: String
|
||||
if let count = data.invitations?.count, count > 0 {
|
||||
invitesText = "\(count)"
|
||||
} else {
|
||||
invitesText = ""
|
||||
if (group.addressName?.isEmpty ?? true) {
|
||||
let invitesText: String
|
||||
if let count = data.invitations?.count, count > 0 {
|
||||
invitesText = "\(count)"
|
||||
} else {
|
||||
invitesText = ""
|
||||
}
|
||||
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemInviteLinks, label: .text(invitesText), text: presentationData.strings.GroupInfo_InviteLinks, icon: UIImage(bundleImageName: "Chat/Info/GroupLinksIcon"), action: {
|
||||
interaction.editingOpenInviteLinksSetup()
|
||||
}))
|
||||
}
|
||||
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemInviteLinks, label: .text(invitesText), text: presentationData.strings.GroupInfo_InviteLinks, icon: UIImage(bundleImageName: "Chat/Info/GroupLinksIcon"), action: {
|
||||
interaction.editingOpenInviteLinksSetup()
|
||||
}))
|
||||
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPermissions, label: .text(activePermissionCount.flatMap({ "\($0)/\(allGroupPermissionList.count)" }) ?? ""), text: presentationData.strings.GroupInfo_Permissions, icon: UIImage(bundleImageName: "Settings/MenuIcons/SetPasscode"), action: {
|
||||
interaction.openPermissions()
|
||||
}))
|
||||
|
@ -53,19 +53,18 @@ private final class ReportPeerDetailsActionSheetItemNode: ActionSheetItemNode {
|
||||
self.inputFieldNode.updateText = { text in
|
||||
textUpdated(text)
|
||||
}
|
||||
self.inputFieldNode.updateHeight = {
|
||||
|
||||
self.inputFieldNode.updateHeight = { [weak self] in
|
||||
self?.requestLayout?()
|
||||
}
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let inputHeight = self.inputFieldNode.updateLayout(width: constrainedSize.width, transition: .immediate)
|
||||
self.inputFieldNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: constrainedSize.width, height: inputHeight))
|
||||
|
||||
let size = CGSize(width: constrainedSize.width, height: inputHeight)
|
||||
|
||||
return CGSize(width: constrainedSize.width, height: inputHeight)
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ private final class ReportPeerHeaderActionSheetItemNode: ActionSheetItemNode {
|
||||
self.accessibilityArea.accessibilityTraits = .staticText
|
||||
}
|
||||
|
||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||
let textSize = self.textNode.updateLayout(CGSize(width: constrainedSize.width - 120.0, height: .greatestFiniteMagnitude))
|
||||
|
||||
let topInset: CGFloat = 26.0
|
||||
@ -84,11 +84,8 @@ private final class ReportPeerHeaderActionSheetItemNode: ActionSheetItemNode {
|
||||
|
||||
let size = CGSize(width: constrainedSize.width, height: topInset + iconSize.height + textSpacing + textSize.height + bottomInset)
|
||||
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||
|
||||
|
||||
self.updateInternalLayout(size)
|
||||
return size
|
||||
}
|
||||
|
||||
override func layout() {
|
||||
super.layout()
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user