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()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||||
}
|
|
||||||
|
|
||||||
public override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let size = self.bounds.size
|
|
||||||
|
|
||||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
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.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
|
self.updateInternalLayout(size)
|
||||||
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@objc private func buttonPressed() {
|
@objc private func buttonPressed() {
|
||||||
if let item = self.item {
|
if let item = self.item {
|
||||||
item.action()
|
item.action()
|
||||||
|
@ -213,14 +213,8 @@ public class BotCheckoutPaymentMethodItemNode: ActionSheetItemNode {
|
|||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||||
}
|
|
||||||
|
|
||||||
public override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let size = self.bounds.size
|
|
||||||
|
|
||||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
@ -242,6 +236,9 @@ public class BotCheckoutPaymentMethodItemNode: ActionSheetItemNode {
|
|||||||
if let image = self.checkNode.image {
|
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.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() {
|
@objc func buttonPressed() {
|
||||||
|
@ -190,15 +190,9 @@ public class BotCheckoutPaymentShippingOptionItemNode: ActionSheetItemNode {
|
|||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||||
}
|
|
||||||
|
|
||||||
public override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let size = self.bounds.size
|
|
||||||
|
|
||||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
var checkInset: CGFloat = 15.0
|
var checkInset: CGFloat = 15.0
|
||||||
@ -214,6 +208,9 @@ public class BotCheckoutPaymentShippingOptionItemNode: ActionSheetItemNode {
|
|||||||
if let image = self.checkNode.image {
|
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.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() {
|
@objc func buttonPressed() {
|
||||||
|
@ -128,14 +128,13 @@ private final class DateSelectionActionSheetItemNode: ActionSheetItemNode {
|
|||||||
self.pickerView.addTarget(self, action: #selector(self.datePickerUpdated), for: .valueChanged)
|
self.pickerView.addTarget(self, action: #selector(self.datePickerUpdated), for: .valueChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 216.0)
|
let size = CGSize(width: constrainedSize.width, height: 216.0)
|
||||||
}
|
|
||||||
|
self.pickerView.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
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() {
|
@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 textSize = self.textNode.updateLayout(CGSize(width: constrainedSize.width - 20.0, height: .greatestFiniteMagnitude))
|
||||||
|
|
||||||
let topInset: CGFloat = 16.0
|
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)
|
let size = CGSize(width: constrainedSize.width, height: topInset + avatarSize + textSpacing + textSize.height + bottomInset)
|
||||||
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
|
self.updateInternalLayout(size)
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
override func layout() {
|
|
||||||
super.layout()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -152,20 +152,17 @@ public class ActionSheetButtonNode: ActionSheetItemNode {
|
|||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||||
}
|
|
||||||
|
|
||||||
public override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let size = self.bounds.size
|
|
||||||
|
|
||||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
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))
|
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.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.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
|
self.updateInternalLayout(size)
|
||||||
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func buttonPressed() {
|
@objc func buttonPressed() {
|
||||||
|
@ -136,15 +136,9 @@ public class ActionSheetCheckboxItemNode: ActionSheetItemNode {
|
|||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||||
}
|
|
||||||
|
|
||||||
public override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let size = self.bounds.size
|
|
||||||
|
|
||||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
var titleOrigin: CGFloat = 50.0
|
var titleOrigin: CGFloat = 50.0
|
||||||
@ -164,6 +158,9 @@ public class ActionSheetCheckboxItemNode: ActionSheetItemNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
|
self.updateInternalLayout(size)
|
||||||
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func buttonPressed() {
|
@objc func buttonPressed() {
|
||||||
|
@ -61,7 +61,7 @@ final class ActionSheetControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
self.itemGroupsContainerNode = ActionSheetItemGroupsContainerNode(theme: self.theme)
|
self.itemGroupsContainerNode = ActionSheetItemGroupsContainerNode(theme: self.theme)
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.scrollView.delegate = self
|
self.scrollView.delegate = self
|
||||||
|
|
||||||
self.addSubnode(self.scrollNode)
|
self.addSubnode(self.scrollNode)
|
||||||
@ -78,6 +78,12 @@ final class ActionSheetControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
self.scrollNode.addSubnode(self.itemGroupsContainerNode)
|
self.scrollNode.addSubnode(self.itemGroupsContainerNode)
|
||||||
|
|
||||||
self.updateTheme()
|
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() {
|
func updateTheme() {
|
||||||
@ -107,9 +113,9 @@ final class ActionSheetControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
self.scrollView.frame = CGRect(origin: CGPoint(), size: layout.size)
|
self.scrollView.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||||
self.dismissTapView.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
|
insets.bottom -= lastGroupHeight + containerInsets.bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,8 +123,7 @@ final class ActionSheetControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
if !self.allowInputInset {
|
if !self.allowInputInset {
|
||||||
transition = .immediate
|
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))
|
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.itemGroupsContainerNode.updateLayout(transition: transition)
|
|
||||||
|
|
||||||
self.updateScrollDimViews(size: layout.size, insets: insets, transition: transition)
|
self.updateScrollDimViews(size: layout.size, insets: insets, transition: transition)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,9 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
|
|
||||||
private var itemNodes: [ActionSheetItemNode] = []
|
private var itemNodes: [ActionSheetItemNode] = []
|
||||||
private var leadingVisibleNodeCount: CGFloat = 100.0
|
private var leadingVisibleNodeCount: CGFloat = 100.0
|
||||||
|
|
||||||
|
private var validLayout: CGSize?
|
||||||
|
|
||||||
init(theme: ActionSheetControllerTheme) {
|
init(theme: ActionSheetControllerTheme) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
|
||||||
@ -81,45 +83,8 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
self.leadingVisibleNodeCount = leadingVisibleNodeCount
|
self.leadingVisibleNodeCount = leadingVisibleNodeCount
|
||||||
self.invalidateCalculatedLayout()
|
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 itemNodesHeight: CGFloat = 0.0
|
||||||
var leadingVisibleNodeSize: CGFloat = 0.0
|
var leadingVisibleNodeSize: CGFloat = 0.0
|
||||||
|
|
||||||
@ -130,24 +95,42 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
itemNodesHeight += UIScreenPixel
|
itemNodesHeight += UIScreenPixel
|
||||||
}
|
}
|
||||||
previousHadSeparator = node.hasSeparator
|
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(i).isLessThanOrEqualTo(leadingVisibleNodeCount) {
|
||||||
if CGFloat(0.0).isLess(than: leadingVisibleNodeSize), node.hasSeparator {
|
if CGFloat(0.0).isLess(than: leadingVisibleNodeSize), node.hasSeparator {
|
||||||
leadingVisibleNodeSize += UIScreenPixel
|
leadingVisibleNodeSize += UIScreenPixel
|
||||||
}
|
}
|
||||||
let factor: CGFloat = min(1.0, leadingVisibleNodeCount - CGFloat(i))
|
let factor: CGFloat = min(1.0, leadingVisibleNodeCount - CGFloat(i))
|
||||||
leadingVisibleNodeSize += node.calculatedSize.height * factor
|
leadingVisibleNodeSize += nodeSize.height * factor
|
||||||
}
|
}
|
||||||
i += 1
|
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) {
|
if !self.scrollNode.view.contentSize.equalTo(scrollViewContentSize) {
|
||||||
self.scrollNode.view.contentSize = 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 {
|
if self.scrollNode.view.contentInset != scrollViewContentInsets {
|
||||||
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.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 {
|
private func currentVerticalOverscroll() -> CGFloat {
|
||||||
@ -180,11 +165,11 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
return verticalOverscroll
|
return verticalOverscroll
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateOverscroll(transition: ContainedViewLayoutTransition) {
|
private func updateOverscroll(size: CGSize, transition: ContainedViewLayoutTransition) {
|
||||||
let verticalOverscroll = self.currentVerticalOverscroll()
|
let verticalOverscroll = self.currentVerticalOverscroll()
|
||||||
|
|
||||||
self.clippingNode.layer.sublayerTransform = CATransform3DMakeTranslation(0.0, min(0.0, verticalOverscroll), 0.0)
|
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) {
|
if !self.clippingNode.frame.equalTo(clippingNodeFrame) {
|
||||||
transition.updateFrame(node: self.clippingNode, frame: clippingNodeFrame)
|
transition.updateFrame(node: self.clippingNode, frame: clippingNodeFrame)
|
||||||
|
|
||||||
@ -195,7 +180,9 @@ final class ActionSheetItemGroupNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
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? {
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||||
|
@ -14,6 +14,8 @@ final class ActionSheetItemGroupsContainerNode: ASDisplayNode {
|
|||||||
private var groups: [ActionSheetItemGroup] = []
|
private var groups: [ActionSheetItemGroup] = []
|
||||||
var groupNodes: [ActionSheetItemGroupNode] = []
|
var groupNodes: [ActionSheetItemGroupNode] = []
|
||||||
|
|
||||||
|
var requestLayout: (() -> Void)?
|
||||||
|
|
||||||
init(theme: ActionSheetControllerTheme) {
|
init(theme: ActionSheetControllerTheme) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
|
||||||
@ -30,46 +32,49 @@ final class ActionSheetItemGroupsContainerNode: ASDisplayNode {
|
|||||||
|
|
||||||
for group in groups {
|
for group in groups {
|
||||||
let groupNode = ActionSheetItemGroupNode(theme: self.theme)
|
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.groupNodes.append(groupNode)
|
||||||
self.addSubnode(groupNode)
|
self.addSubnode(groupNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
var groupsHeight: CGFloat = 0.0
|
var groupsHeight: CGFloat = 0.0
|
||||||
|
|
||||||
|
var calculatedSizes: [CGSize] = []
|
||||||
for groupNode in self.groupNodes.reversed() {
|
for groupNode in self.groupNodes.reversed() {
|
||||||
if CGFloat(0.0).isLess(than: groupsHeight) {
|
if CGFloat(0.0).isLess(than: groupsHeight) {
|
||||||
groupsHeight += groupSpacing
|
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
|
groupsHeight += size.height
|
||||||
}
|
}
|
||||||
|
|
||||||
return CGSize(width: constrainedSize.width, height: min(groupsHeight, constrainedSize.height))
|
var itemGroupsHeight: CGFloat = 0.0
|
||||||
}
|
|
||||||
|
|
||||||
func updateLayout(transition: ContainedViewLayoutTransition) {
|
|
||||||
var groupsHeight: CGFloat = 0.0
|
|
||||||
for i in 0 ..< self.groupNodes.count {
|
for i in 0 ..< self.groupNodes.count {
|
||||||
let groupNode = self.groupNodes[i]
|
let groupNode = self.groupNodes[i]
|
||||||
|
|
||||||
let size = groupNode.calculatedSize
|
let size = calculatedSizes[i]
|
||||||
|
|
||||||
if i != 0 {
|
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))
|
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))
|
||||||
}
|
}
|
||||||
|
transition.updateFrame(node: groupNode, frame: CGRect(origin: CGPoint(x: 0.0, y: itemGroupsHeight), size: size))
|
||||||
groupNode.updateLayout(transition: transition)
|
|
||||||
transition.updateFrame(node: groupNode, frame: CGRect(origin: CGPoint(x: 0.0, y: groupsHeight), size: size))
|
|
||||||
|
|
||||||
transition.updateFrame(view: groupNode.trailingDimView, frame: CGRect())
|
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? {
|
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
|
||||||
|
@ -26,13 +26,15 @@ open class ActionSheetItemNode: ASDisplayNode {
|
|||||||
self.addSubnode(self.overflowSeparatorNode)
|
self.addSubnode(self.overflowSeparatorNode)
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
open func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||||
|
self.updateInternalLayout(size)
|
||||||
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
open override func layout() {
|
public func updateInternalLayout(_ calculatedSize: CGSize) {
|
||||||
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: self.calculatedSize)
|
self.backgroundNode.frame = CGRect(origin: CGPoint(), size: calculatedSize)
|
||||||
self.overflowSeparatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: self.calculatedSize.height), size: CGSize(width: self.calculatedSize.width, height: UIScreenPixel))
|
self.overflowSeparatorNode.frame = CGRect(origin: CGPoint(x: 0.0, y: calculatedSize.height), size: CGSize(width: calculatedSize.width, height: UIScreenPixel))
|
||||||
self.overflowSeparatorNode.isHidden = !self.hasSeparator
|
self.overflowSeparatorNode.isHidden = !self.hasSeparator
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,15 +103,9 @@ public class ActionSheetSwitchNode: ActionSheetItemNode {
|
|||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||||
}
|
|
||||||
|
|
||||||
public override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let size = self.bounds.size
|
|
||||||
|
|
||||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
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))
|
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.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.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
|
self.updateInternalLayout(size)
|
||||||
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func buttonPressed() {
|
@objc func buttonPressed() {
|
||||||
|
@ -69,19 +69,15 @@ public class ActionSheetTextNode: ActionSheetItemNode {
|
|||||||
self.setNeedsLayout()
|
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))
|
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))
|
let size = 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))
|
|
||||||
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.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.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 {
|
} else {
|
||||||
isGroup = true
|
isGroup = true
|
||||||
}
|
}
|
||||||
let controller = InviteLinkQRCodeController(context: context, invite: invite, isGroup: isGroup)
|
Queue.mainQueue().after(0.2) {
|
||||||
presentControllerImpl?(controller, nil)
|
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()
|
timer.start()
|
||||||
|
|
||||||
let previousRevokedInvites = Atomic<PeerExportedInvitationsState?>(value: nil)
|
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())
|
let signal = combineLatest(context.sharedContext.presentationData, peerView, importersContext, importersState.get(), invitesContext.state, revokedInvitesContext.state, creators, timerPromise.get())
|
||||||
|> deliverOnMainQueue
|
|> deliverOnMainQueue
|
||||||
|> map { presentationData, view, importersContext, importers, invites, revokedInvites, creators, tick -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
|> map { presentationData, view, importersContext, importers, invites, revokedInvites, creators, tick -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||||
let previousRevokedInvites = previousRevokedInvites.swap(invites)
|
let previousRevokedInvites = previousRevokedInvites.swap(invites)
|
||||||
|
let previousCreators = previousCreators.swap(creators)
|
||||||
|
|
||||||
var crossfade = false
|
var crossfade = false
|
||||||
if (previousRevokedInvites?.hasLoadedOnce ?? false) != (revokedInvites.hasLoadedOnce) {
|
if (previousRevokedInvites?.hasLoadedOnce ?? false) != (revokedInvites.hasLoadedOnce) {
|
||||||
crossfade = true
|
crossfade = true
|
||||||
}
|
}
|
||||||
|
if (previousCreators?.count ?? 0) != creators.count {
|
||||||
|
crossfade = true
|
||||||
|
}
|
||||||
|
|
||||||
let title: ItemListControllerTitle
|
let title: ItemListControllerTitle
|
||||||
if let admin = admin, let peer = admin.peer.peer {
|
if let admin = admin, let peer = admin.peer.peer {
|
||||||
|
@ -45,6 +45,8 @@ private struct InviteLinkViewTransaction {
|
|||||||
let insertions: [ListViewInsertItem]
|
let insertions: [ListViewInsertItem]
|
||||||
let updates: [ListViewUpdateItem]
|
let updates: [ListViewUpdateItem]
|
||||||
let isLoading: Bool
|
let isLoading: Bool
|
||||||
|
let animated: Bool
|
||||||
|
let crossfade: Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum InviteLinkViewEntryId: Hashable {
|
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 (deleteIndices, indicesAndItems, updateIndices) = mergeListsStableWithUpdates(leftList: fromEntries, rightList: toEntries)
|
||||||
|
|
||||||
let deletions = deleteIndices.map { ListViewDeleteItem(index: $0, directionHint: nil) }
|
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 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) }
|
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)
|
private let titleFont = Font.bold(17.0)
|
||||||
@ -535,6 +537,8 @@ public final class InviteLinkViewController: ViewController {
|
|||||||
})
|
})
|
||||||
|
|
||||||
let previousEntries = Atomic<[InviteLinkViewEntry]?>(value: nil)
|
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)
|
let creatorPeer = context.account.postbox.loadedPeerWithId(invite.adminId)
|
||||||
self.disposable = (combineLatest(self.presentationDataPromise.get(), self.importersContext.state, creatorPeer)
|
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))
|
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
|
var index: Int32 = 0
|
||||||
if state.importers.isEmpty && state.isLoadingMore {
|
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: [])
|
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))
|
entries.append(.importer(Int32(i), presentationData.theme, presentationData.dateTimeFormat, fakeUser, 0, true))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
count = min(4, Int32(state.importers.count))
|
||||||
|
loading = false
|
||||||
for importer in state.importers {
|
for importer in state.importers {
|
||||||
if let peer = importer.peer.peer {
|
if let peer = importer.peer.peer {
|
||||||
entries.append(.importer(index, presentationData.theme, presentationData.dateTimeFormat, peer, importer.date, false))
|
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 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)
|
strongSelf.enqueueTransition(transition)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -700,7 +723,11 @@ public final class InviteLinkViewController: ViewController {
|
|||||||
}
|
}
|
||||||
self.enqueuedTransitions.remove(at: 0)
|
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.offsetContainerNode = ASDisplayNode()
|
||||||
|
|
||||||
self.iconBackgroundNode = ASImageNode()
|
self.iconBackgroundNode = ASDisplayNode()
|
||||||
self.iconBackgroundNode.setLayerBlock { () -> CALayer in
|
self.iconBackgroundNode.setLayerBlock { () -> CALayer in
|
||||||
return CAShapeLayer()
|
return CAShapeLayer()
|
||||||
}
|
}
|
||||||
|
@ -163,19 +163,13 @@ private final class OpenInActionSheetItemNode: ActionSheetItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 148.0)
|
let size = CGSize(width: constrainedSize.width, height: 148.0)
|
||||||
}
|
|
||||||
|
let titleSize = self.titleNode.measure(size)
|
||||||
override func layout() {
|
self.titleNode.frame = CGRect(origin: CGPoint(x: 0.0, y: 16.0), size: CGSize(width: size.width, height: titleSize.height))
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let bounds = self.bounds
|
self.scrollNode.frame = CGRect(origin: CGPoint(x: 0, y: 36.0), size: CGSize(width: size.width, height: size.height - 36.0))
|
||||||
|
|
||||||
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))
|
|
||||||
|
|
||||||
let nodeInset: CGFloat = 2.0
|
let nodeInset: CGFloat = 2.0
|
||||||
let nodeSize = CGSize(width: 80.0, height: 112.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.scrollNode.view.contentSize = contentSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.updateInternalLayout(size)
|
||||||
|
return size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ private final class ChannelDiscussionGroupActionSheetItemNode: ActionSheetItemNo
|
|||||||
self.textNode.attributedText = attributedText
|
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 textSize = self.textNode.updateLayout(CGSize(width: constrainedSize.width - 20.0, height: .greatestFiniteMagnitude))
|
||||||
|
|
||||||
let topInset: CGFloat = 16.0
|
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)
|
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)
|
let size = CGSize(width: constrainedSize.width, height: topInset + avatarSize + textSpacing + textSize.height + bottomInset)
|
||||||
}
|
|
||||||
|
self.updateInternalLayout(size)
|
||||||
override func layout() {
|
return size
|
||||||
super.layout()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,14 +111,13 @@ private final class PeerBanTimeoutActionSheetItemNode: ActionSheetItemNode {
|
|||||||
self.pickerView.addTarget(self, action: #selector(self.datePickerUpdated), for: .valueChanged)
|
self.pickerView.addTarget(self, action: #selector(self.datePickerUpdated), for: .valueChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 216.0)
|
let size = CGSize(width: constrainedSize.width, height: 216.0)
|
||||||
}
|
|
||||||
|
|
||||||
override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
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() {
|
@objc private func datePickerUpdated() {
|
||||||
|
@ -152,11 +152,11 @@ public func peerReportOptionsController(context: AccountContext, subject: PeerRe
|
|||||||
case .copyright:
|
case .copyright:
|
||||||
reportReason = .copyright
|
reportReason = .copyright
|
||||||
case .other:
|
case .other:
|
||||||
break
|
reportReason = .custom
|
||||||
}
|
}
|
||||||
if let reportReason = reportReason {
|
if let reportReason = reportReason {
|
||||||
var passthrough = passthrough
|
var passthrough = passthrough
|
||||||
if case .fake = reportReason {
|
if [.fake, .custom].contains(reportReason) {
|
||||||
passthrough = false
|
passthrough = false
|
||||||
}
|
}
|
||||||
switch subject {
|
switch subject {
|
||||||
@ -169,7 +169,7 @@ public func peerReportOptionsController(context: AccountContext, subject: PeerRe
|
|||||||
if let path = getAppBundle().path(forResource: "PoliceCar", ofType: "tgs") {
|
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)
|
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):
|
case let .messages(messageIds):
|
||||||
@ -181,7 +181,7 @@ public func peerReportOptionsController(context: AccountContext, subject: PeerRe
|
|||||||
if let path = getAppBundle().path(forResource: "PoliceCar", ofType: "tgs") {
|
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)
|
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()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 36.0 * CGFloat(self.fieldNodes.count) + 12.0)
|
let size = CGSize(width: constrainedSize.width, height: 36.0 * CGFloat(self.fieldNodes.count) + 12.0)
|
||||||
}
|
|
||||||
|
|
||||||
override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let size = self.bounds.size
|
|
||||||
|
|
||||||
var offset: CGFloat = 15.0
|
var offset: CGFloat = 15.0
|
||||||
for (lhs, rhs) in self.fieldNodes {
|
for (lhs, rhs) in self.fieldNodes {
|
||||||
@ -261,6 +255,9 @@ private final class ProxyServerInfoItemNode: ActionSheetItemNode {
|
|||||||
|
|
||||||
offset += 36.0
|
offset += 36.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.updateInternalLayout(size)
|
||||||
|
return size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,14 +357,8 @@ private final class ProxyServerActionItemNode: ActionSheetItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||||
}
|
|
||||||
|
|
||||||
override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let size = self.bounds.size
|
|
||||||
|
|
||||||
self.buttonNode.frame = CGRect(origin: CGPoint(), size: size)
|
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))
|
let activitySize = self.activityIndicator.measure(CGSize(width: 100.0, height: 100.0))
|
||||||
self.titleNode.frame = titleFrame
|
self.titleNode.frame = titleFrame
|
||||||
self.activityIndicator.frame = CGRect(origin: CGPoint(x: 14.0, y: titleFrame.minY - 0.0), size: activitySize)
|
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() {
|
@objc private func buttonPressed() {
|
||||||
let proxyServerSettings = self.server
|
let proxyServerSettings = self.server
|
||||||
let _ = (self.accountManager.transaction { transaction -> ProxySettings in
|
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)
|
self.pickerView.addTarget(self, action: #selector(self.datePickerUpdated), for: .valueChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 216.0)
|
let size = CGSize(width: constrainedSize.width, height: 216.0)
|
||||||
}
|
|
||||||
|
|
||||||
override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
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() {
|
@objc private func datePickerUpdated() {
|
||||||
|
@ -112,14 +112,8 @@ public class LocationBroadcastActionSheetItemNode: ActionSheetItemNode {
|
|||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||||
}
|
|
||||||
|
|
||||||
public override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let size = self.bounds.size
|
|
||||||
|
|
||||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
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)
|
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.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() {
|
@objc func buttonPressed() {
|
||||||
|
@ -136,14 +136,8 @@ public class CallRouteActionSheetItemNode: ActionSheetItemNode {
|
|||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
public override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 57.0)
|
let size = CGSize(width: constrainedSize.width, height: 57.0)
|
||||||
}
|
|
||||||
|
|
||||||
public override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
let size = self.bounds.size
|
|
||||||
|
|
||||||
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
self.button.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
@ -157,6 +151,9 @@ public class CallRouteActionSheetItemNode: ActionSheetItemNode {
|
|||||||
if let image = self.checkNode.image {
|
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.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() {
|
@objc func buttonPressed() {
|
||||||
|
@ -39,7 +39,7 @@ public func dismissServerProvidedSuggestion(account: Account, suggestion: Server
|
|||||||
|
|
||||||
|
|
||||||
public enum PeerSpecificServerProvidedSuggestion: String {
|
public enum PeerSpecificServerProvidedSuggestion: String {
|
||||||
case convertToGigagroup = "CONVERT_TO_GIGAGROUP"
|
case convertToGigagroup = "CONVERT_GIGAGROUP"
|
||||||
}
|
}
|
||||||
|
|
||||||
public func getPeerSpecificServerProvidedSuggestions(postbox: Postbox, peerId: PeerId) -> Signal<[PeerSpecificServerProvidedSuggestion], NoError> {
|
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 {
|
if value < 60 {
|
||||||
return strings.MessageTimer_Seconds(max(1, value))
|
return strings.MessageTimer_Seconds(max(1, value))
|
||||||
} else if value < 60 * 60 {
|
} 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 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 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()
|
controller?.dismiss()
|
||||||
|
|
||||||
|
let _ = dismissPeerSpecificServerProvidedSuggestion(account: context.account, peerId: peerId, suggestion: .convertToGigagroup).start()
|
||||||
|
|
||||||
let _ = (convertGroupToGigagroup(account: context.account, peerId: peerId)
|
let _ = (convertGroupToGigagroup(account: context.account, peerId: peerId)
|
||||||
|> deliverOnMainQueue).start(completed: {
|
|> deliverOnMainQueue).start(completed: {
|
||||||
|
|
||||||
@ -10395,7 +10399,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
strongController.dismiss()
|
strongController.dismiss()
|
||||||
} else if peerId == strongSelf.context.account.peerId {
|
} else if peerId == strongSelf.context.account.peerId {
|
||||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
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
|
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messages.map { message -> EnqueueMessage in
|
||||||
return .forward(source: message.id, grouping: .auto, attributes: [])
|
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)
|
self.pickerView.addTarget(self, action: #selector(self.pickerChanged), for: .valueChanged)
|
||||||
}
|
}
|
||||||
|
|
||||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 157.0)
|
let size = CGSize(width: constrainedSize.width, height: 157.0)
|
||||||
}
|
|
||||||
|
|
||||||
override func layout() {
|
|
||||||
super.layout()
|
|
||||||
|
|
||||||
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() {
|
@objc func pickerChanged() {
|
||||||
|
@ -150,10 +150,6 @@ private final class AutoremoveTimeoutSelectorItemNode: ActionSheetItemNode, UIPi
|
|||||||
self.pickerView.selectRow(index, inComponent: 0, animated: false)
|
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 {
|
func numberOfComponents(in pickerView: UIPickerView) -> Int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@ -178,9 +174,12 @@ private final class AutoremoveTimeoutSelectorItemNode: ActionSheetItemNode, UIPi
|
|||||||
self.valueChanged(self.timeoutValues[row])
|
self.valueChanged(self.timeoutValues[row])
|
||||||
}
|
}
|
||||||
|
|
||||||
override func layout() {
|
public override func updateLayout(constrainedSize: CGSize, transition: ContainedViewLayoutTransition) -> CGSize {
|
||||||
super.layout()
|
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
|
let invitesText: String
|
||||||
if let count = data.invitations?.count, count > 0 {
|
if let count = data.invitations?.count, count > 0 {
|
||||||
invitesText = "\(count)"
|
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
|
let invitesText: String
|
||||||
if let count = data.invitations?.count, count > 0 {
|
if let count = data.invitations?.count, count > 0 {
|
||||||
invitesText = "\(count)"
|
invitesText = "\(count)"
|
||||||
@ -1438,17 +1438,19 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
|||||||
activePermissionCount = count
|
activePermissionCount = count
|
||||||
}
|
}
|
||||||
|
|
||||||
let invitesText: String
|
if (group.addressName?.isEmpty ?? true) {
|
||||||
if let count = data.invitations?.count, count > 0 {
|
let invitesText: String
|
||||||
invitesText = "\(count)"
|
if let count = data.invitations?.count, count > 0 {
|
||||||
} else {
|
invitesText = "\(count)"
|
||||||
invitesText = ""
|
} 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: {
|
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()
|
interaction.openPermissions()
|
||||||
}))
|
}))
|
||||||
|
@ -53,19 +53,18 @@ private final class ReportPeerDetailsActionSheetItemNode: ActionSheetItemNode {
|
|||||||
self.inputFieldNode.updateText = { text in
|
self.inputFieldNode.updateText = { text in
|
||||||
textUpdated(text)
|
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)
|
let inputHeight = self.inputFieldNode.updateLayout(width: constrainedSize.width, transition: .immediate)
|
||||||
self.inputFieldNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: constrainedSize.width, height: inputHeight))
|
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)
|
self.updateInternalLayout(size)
|
||||||
}
|
return size
|
||||||
|
|
||||||
override func layout() {
|
|
||||||
super.layout()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ private final class ReportPeerHeaderActionSheetItemNode: ActionSheetItemNode {
|
|||||||
self.accessibilityArea.accessibilityTraits = .staticText
|
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 textSize = self.textNode.updateLayout(CGSize(width: constrainedSize.width - 120.0, height: .greatestFiniteMagnitude))
|
||||||
|
|
||||||
let topInset: CGFloat = 26.0
|
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)
|
let size = CGSize(width: constrainedSize.width, height: topInset + iconSize.height + textSpacing + textSize.height + bottomInset)
|
||||||
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
self.accessibilityArea.frame = CGRect(origin: CGPoint(), size: size)
|
||||||
|
|
||||||
|
self.updateInternalLayout(size)
|
||||||
return size
|
return size
|
||||||
}
|
}
|
||||||
|
|
||||||
override func layout() {
|
|
||||||
super.layout()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user