mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-07-24 04:00:45 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
f362ce9fc6
@ -22,6 +22,7 @@ swift_library(
|
||||
"//submodules/CountrySelectionUI:CountrySelectionUI",
|
||||
"//submodules/AppBundle:AppBundle",
|
||||
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
||||
"//submodules/OverlayStatusController:OverlayStatusController",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -138,6 +138,11 @@ final class BotCheckoutActionButton: HighlightableButtonNode {
|
||||
|
||||
self.progressBackgroundNode.layer.add(basicAnimation, forKey: "progressRotation")
|
||||
case let .active(title):
|
||||
if let applePayButton = self.applePayButton {
|
||||
self.applePayButton = nil
|
||||
applePayButton.removeFromSuperview()
|
||||
}
|
||||
|
||||
if case .active = previousState {
|
||||
let makeLayout = TextNode.asyncLayout(self.labelNode)
|
||||
let (labelLayout, labelApply) = makeLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: title, font: titleFont, textColor: self.foregroundColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: validLayout, alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
@ -52,7 +52,7 @@ public final class BotCheckoutController: ViewController {
|
||||
}
|
||||
|
||||
override public func loadDisplayNode() {
|
||||
let displayNode = BotCheckoutControllerNode(controller: nil, navigationBar: self.navigationBar!, updateNavigationOffset: { [weak self] offset in
|
||||
let displayNode = BotCheckoutControllerNode(controller: self, navigationBar: self.navigationBar!, updateNavigationOffset: { [weak self] offset in
|
||||
if let strongSelf = self {
|
||||
strongSelf.navigationOffset = offset
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ import TelegramStringFormatting
|
||||
import PasswordSetupUI
|
||||
import Stripe
|
||||
import LocalAuth
|
||||
import OverlayStatusController
|
||||
|
||||
final class BotCheckoutControllerArguments {
|
||||
fileprivate let account: Account
|
||||
@ -25,13 +26,15 @@ final class BotCheckoutControllerArguments {
|
||||
fileprivate let openPaymentMethod: () -> Void
|
||||
fileprivate let openShippingMethod: () -> Void
|
||||
fileprivate let updateTip: (Int64) -> Void
|
||||
fileprivate let ensureTipInputVisible: () -> Void
|
||||
|
||||
fileprivate init(account: Account, openInfo: @escaping (BotCheckoutInfoControllerFocus) -> Void, openPaymentMethod: @escaping () -> Void, openShippingMethod: @escaping () -> Void, updateTip: @escaping (Int64) -> Void) {
|
||||
fileprivate init(account: Account, openInfo: @escaping (BotCheckoutInfoControllerFocus) -> Void, openPaymentMethod: @escaping () -> Void, openShippingMethod: @escaping () -> Void, updateTip: @escaping (Int64) -> Void, ensureTipInputVisible: @escaping () -> Void) {
|
||||
self.account = account
|
||||
self.openInfo = openInfo
|
||||
self.openPaymentMethod = openPaymentMethod
|
||||
self.openShippingMethod = openShippingMethod
|
||||
self.updateTip = updateTip
|
||||
self.ensureTipInputVisible = ensureTipInputVisible
|
||||
}
|
||||
}
|
||||
|
||||
@ -197,6 +200,10 @@ enum BotCheckoutEntry: ItemListNodeEntry {
|
||||
case let .tip(_, _, text, currency, value, numericValue, maxValue, variants):
|
||||
return BotCheckoutTipItem(theme: presentationData.theme, strings: presentationData.strings, title: text, currency: currency, value: value, numericValue: numericValue, maxValue: maxValue, availableVariants: variants, sectionId: self.section, updateValue: { value in
|
||||
arguments.updateTip(value)
|
||||
}, updatedFocus: { isFocused in
|
||||
if isFocused {
|
||||
arguments.ensureTipInputVisible()
|
||||
}
|
||||
})
|
||||
case let .paymentMethod(_, text, value):
|
||||
return ItemListDisclosureItem(presentationData: presentationData, title: text, label: value, sectionId: self.section, style: .blocks, disclosureStyle: .arrow, action: {
|
||||
@ -428,6 +435,7 @@ private func availablePaymentMethods(form: BotPaymentForm, current: BotCheckoutP
|
||||
}
|
||||
|
||||
final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthorizationViewControllerDelegate {
|
||||
private weak var controller: BotCheckoutController?
|
||||
private let context: AccountContext
|
||||
private let messageId: MessageId
|
||||
private let present: (ViewController, Any?) -> Void
|
||||
@ -452,13 +460,15 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
private let actionButtonPanelSeparator: ASDisplayNode
|
||||
private let actionButton: BotCheckoutActionButton
|
||||
private let inProgressDimNode: ASDisplayNode
|
||||
private var statusController: ViewController?
|
||||
|
||||
private let payDisposable = MetaDisposable()
|
||||
private let paymentAuthDisposable = MetaDisposable()
|
||||
private var applePayAuthrorizationCompletion: ((PKPaymentAuthorizationStatus) -> Void)?
|
||||
private var applePayController: PKPaymentAuthorizationViewController?
|
||||
|
||||
init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId, present: @escaping (ViewController, Any?) -> Void, dismissAnimated: @escaping () -> Void) {
|
||||
init(controller: BotCheckoutController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, invoice: TelegramMediaInvoice, messageId: MessageId, present: @escaping (ViewController, Any?) -> Void, dismissAnimated: @escaping () -> Void) {
|
||||
self.controller = controller
|
||||
self.context = context
|
||||
self.messageId = messageId
|
||||
self.present = present
|
||||
@ -470,6 +480,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
var updateTipImpl: ((Int64) -> Void)?
|
||||
var openPaymentMethodImpl: (() -> Void)?
|
||||
var openShippingMethodImpl: (() -> Void)?
|
||||
var ensureTipInputVisibleImpl: (() -> Void)?
|
||||
|
||||
let arguments = BotCheckoutControllerArguments(account: context.account, openInfo: { item in
|
||||
openInfoImpl?(item)
|
||||
@ -479,6 +490,8 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
openShippingMethodImpl?()
|
||||
}, updateTip: { value in
|
||||
updateTipImpl?(value)
|
||||
}, ensureTipInputVisible: {
|
||||
ensureTipInputVisibleImpl?()
|
||||
})
|
||||
|
||||
let signal: Signal<(ItemListPresentationData, (ItemListNodeState, Any)), NoError> = combineLatest(context.sharedContext.presentationData, self.state.get(), paymentFormAndInfo.get(), context.account.postbox.loadedPeerWithId(messageId.peerId))
|
||||
@ -503,7 +516,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
self.inProgressDimNode.isUserInteractionEnabled = false
|
||||
self.inProgressDimNode.backgroundColor = self.presentationData.theme.list.plainBackgroundColor.withAlphaComponent(0.5)
|
||||
|
||||
super.init(controller: controller, navigationBar: navigationBar, updateNavigationOffset: updateNavigationOffset, state: signal)
|
||||
super.init(controller: nil, navigationBar: navigationBar, updateNavigationOffset: updateNavigationOffset, state: signal)
|
||||
|
||||
self.arguments = arguments
|
||||
|
||||
@ -519,8 +532,9 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
updatedCurrentShippingOptionId = currentShippingOptionId
|
||||
}
|
||||
}
|
||||
|
||||
strongSelf.paymentFormAndInfo.set(.single((paymentFormValue, formInfo, validatedInfo, updatedCurrentShippingOptionId, strongSelf.currentPaymentMethod, strongSelf.currentTipAmount)))
|
||||
|
||||
|
||||
strongSelf.updateActionButton()
|
||||
}
|
||||
}), ViewControllerPresentationArguments(presentationAnimation: .modalSheet))
|
||||
@ -762,6 +776,23 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
|
||||
strongSelf.updateActionButton()
|
||||
}
|
||||
|
||||
ensureTipInputVisibleImpl = { [weak self] in
|
||||
self?.afterLayout({
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
var selectedItemNode: ListViewItemNode?
|
||||
strongSelf.listNode.forEachItemNode { itemNode in
|
||||
if let itemNode = itemNode as? BotCheckoutTipItemNode {
|
||||
selectedItemNode = itemNode
|
||||
}
|
||||
}
|
||||
if let selectedItemNode = selectedItemNode {
|
||||
strongSelf.listNode.ensureItemNodeVisible(selectedItemNode, atTop: true)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
openPaymentMethodImpl = { [weak self] in
|
||||
if let strongSelf = self, let paymentForm = strongSelf.paymentFormValue {
|
||||
@ -811,6 +842,9 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
|
||||
self.formRequestDisposable = (formAndMaybeValidatedInfo |> deliverOnMainQueue).start(next: { [weak self] form, validatedInfo in
|
||||
if let strongSelf = self {
|
||||
UIView.transition(with: strongSelf.view, duration: 0.25, options: UIView.AnimationOptions.transitionCrossDissolve, animations: {
|
||||
}, completion: nil)
|
||||
|
||||
let savedInfo: BotPaymentRequestedInfo
|
||||
if let current = form.savedInfo {
|
||||
savedInfo = current
|
||||
@ -868,13 +902,26 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
}
|
||||
self.actionButtonPanelNode.isHidden = false
|
||||
}
|
||||
|
||||
private func updateIsInProgress(_ value: Bool) {
|
||||
if value {
|
||||
if self.statusController == nil {
|
||||
let statusController = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
|
||||
self.statusController = statusController
|
||||
self.controller?.present(statusController, in: .window(.root))
|
||||
}
|
||||
} else if let statusController = self.statusController {
|
||||
self.statusController = nil
|
||||
statusController.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
override func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition, additionalInsets: UIEdgeInsets) {
|
||||
var updatedInsets = layout.intrinsicInsets
|
||||
|
||||
let bottomPanelHorizontalInset: CGFloat = 16.0
|
||||
let bottomPanelVerticalInset: CGFloat = 16.0
|
||||
let bottomPanelHeight = updatedInsets.bottom + bottomPanelVerticalInset * 2.0 + BotCheckoutActionButton.height
|
||||
let bottomPanelHeight = max(updatedInsets.bottom, layout.inputHeight ?? 0.0) + bottomPanelVerticalInset * 2.0 + BotCheckoutActionButton.height
|
||||
|
||||
transition.updateFrame(node: self.actionButtonPanelNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - bottomPanelHeight), size: CGSize(width: layout.size.width, height: bottomPanelHeight)))
|
||||
transition.updateFrame(node: self.actionButtonPanelSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: UIScreenPixel)))
|
||||
@ -1088,11 +1135,19 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
self.inProgressDimNode.alpha = 1.0
|
||||
self.actionButton.isEnabled = false
|
||||
self.updateActionButton()
|
||||
self.payDisposable.set((sendBotPaymentForm(account: self.context.account, messageId: self.messageId, formId: paymentForm.id, validatedInfoId: self.currentValidatedFormInfo?.id, shippingOptionId: self.currentShippingOptionId, tipAmount: self.currentTipAmount, credentials: credentials) |> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
self.updateIsInProgress(true)
|
||||
|
||||
var tipAmount = self.currentTipAmount
|
||||
if tipAmount == nil, let _ = paymentForm.invoice.tip {
|
||||
tipAmount = 0
|
||||
}
|
||||
|
||||
self.payDisposable.set((sendBotPaymentForm(account: self.context.account, messageId: self.messageId, formId: paymentForm.id, validatedInfoId: self.currentValidatedFormInfo?.id, shippingOptionId: self.currentShippingOptionId, tipAmount: tipAmount, credentials: credentials) |> deliverOnMainQueue).start(next: { [weak self] result in
|
||||
if let strongSelf = self {
|
||||
strongSelf.inProgressDimNode.isUserInteractionEnabled = false
|
||||
strongSelf.inProgressDimNode.alpha = 0.0
|
||||
strongSelf.actionButton.isEnabled = true
|
||||
strongSelf.updateIsInProgress(false)
|
||||
if let applePayAuthrorizationCompletion = strongSelf.applePayAuthrorizationCompletion {
|
||||
strongSelf.applePayAuthrorizationCompletion = nil
|
||||
applePayAuthrorizationCompletion(.success)
|
||||
@ -1124,6 +1179,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
strongSelf.inProgressDimNode.alpha = 0.0
|
||||
strongSelf.actionButton.isEnabled = true
|
||||
strongSelf.updateActionButton()
|
||||
strongSelf.updateIsInProgress(false)
|
||||
if let applePayAuthrorizationCompletion = strongSelf.applePayAuthrorizationCompletion {
|
||||
strongSelf.applePayAuthrorizationCompletion = nil
|
||||
applePayAuthrorizationCompletion(.failure)
|
||||
|
@ -18,12 +18,13 @@ class BotCheckoutTipItem: ListViewItem, ItemListItem {
|
||||
let maxValue: Int64
|
||||
let availableVariants: [(String, Int64)]
|
||||
let updateValue: (Int64) -> Void
|
||||
let updatedFocus: (Bool) -> Void
|
||||
|
||||
let sectionId: ItemListSectionId
|
||||
|
||||
let requestsNoInset: Bool = true
|
||||
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, title: String, currency: String, value: String, numericValue: Int64, maxValue: Int64, availableVariants: [(String, Int64)], sectionId: ItemListSectionId, updateValue: @escaping (Int64) -> Void) {
|
||||
init(theme: PresentationTheme, strings: PresentationStrings, title: String, currency: String, value: String, numericValue: Int64, maxValue: Int64, availableVariants: [(String, Int64)], sectionId: ItemListSectionId, updateValue: @escaping (Int64) -> Void, updatedFocus: @escaping (Bool) -> Void) {
|
||||
self.theme = theme
|
||||
self.strings = strings
|
||||
self.title = title
|
||||
@ -33,6 +34,7 @@ class BotCheckoutTipItem: ListViewItem, ItemListItem {
|
||||
self.maxValue = maxValue
|
||||
self.availableVariants = availableVariants
|
||||
self.updateValue = updateValue
|
||||
self.updatedFocus = updatedFocus
|
||||
self.sectionId = sectionId
|
||||
}
|
||||
|
||||
@ -264,6 +266,18 @@ class BotCheckoutTipItemNode: ListViewItemNode, UITextFieldDelegate {
|
||||
|
||||
strongSelf.textNode.clipsToBounds = true
|
||||
strongSelf.textNode.textField.delegate = strongSelf.formatterDelegate
|
||||
|
||||
/*let toolbar: UIToolbar = UIToolbar()
|
||||
toolbar.tintColor = item.theme.rootController.navigationBar.accentTextColor
|
||||
toolbar.barTintColor = item.theme.rootController.navigationBar.backgroundColor
|
||||
toolbar.barStyle = .default
|
||||
toolbar.items = [
|
||||
UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil),
|
||||
UIBarButtonItem(title: item.strings.Common_Done, style: .done, target: strongSelf, action: #selector(strongSelf.dismissKeyboard))
|
||||
]
|
||||
toolbar.sizeToFit()
|
||||
|
||||
strongSelf.textNode.textField.inputAccessoryView = toolbar*/
|
||||
}
|
||||
|
||||
strongSelf.textNode.textField.typingAttributes = [NSAttributedString.Key.font: titleFont]
|
||||
@ -273,6 +287,7 @@ class BotCheckoutTipItemNode: ListViewItemNode, UITextFieldDelegate {
|
||||
strongSelf.textNode.textField.textAlignment = .right
|
||||
strongSelf.textNode.textField.keyboardAppearance = item.theme.rootController.keyboardColor.keyboardAppearance
|
||||
strongSelf.textNode.textField.keyboardType = .decimalPad
|
||||
strongSelf.textNode.textField.returnKeyType = .next
|
||||
strongSelf.textNode.textField.tintColor = item.theme.list.itemAccentColor
|
||||
|
||||
var textInputFrame = CGRect(origin: CGPoint(x: params.width - leftInset - 150.0, y: -2.0), size: CGSize(width: 150.0, height: labelsContentHeight))
|
||||
@ -370,6 +385,10 @@ class BotCheckoutTipItemNode: ListViewItemNode, UITextFieldDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func dismissKeyboard() {
|
||||
self.textNode.textField.resignFirstResponder()
|
||||
}
|
||||
|
||||
@objc private func textFieldTextChanged(_ textField: UITextField) {
|
||||
let text = textField.text ?? ""
|
||||
self.labelNode.isHidden = !text.isEmpty
|
||||
@ -419,6 +438,8 @@ class BotCheckoutTipItemNode: ListViewItemNode, UITextFieldDelegate {
|
||||
|
||||
@objc public func textFieldDidBeginEditing(_ textField: UITextField) {
|
||||
textField.selectedTextRange = textField.textRange(from: textField.endOfDocument, to: textField.endOfDocument)
|
||||
|
||||
self.item?.updatedFocus(true)
|
||||
}
|
||||
|
||||
@objc public func textFieldDidChangeSelection(_ textField: UITextField) {
|
||||
|
@ -276,7 +276,9 @@ final class BotReceiptControllerNode: ItemListControllerNode {
|
||||
|
||||
private let receiptData = Promise<(BotPaymentInvoice, BotPaymentRequestedInfo?, BotPaymentShippingOption?, String?, TelegramMediaInvoice, Int64?)?>(nil)
|
||||
private var dataRequestDisposable: Disposable?
|
||||
|
||||
|
||||
private let actionButtonPanelNode: ASDisplayNode
|
||||
private let actionButtonPanelSeparator: ASDisplayNode
|
||||
private let actionButton: BotCheckoutActionButton
|
||||
|
||||
init(controller: ItemListController?, navigationBar: NavigationBar, updateNavigationOffset: @escaping (CGFloat) -> Void, context: AccountContext, messageId: MessageId, dismissAnimated: @escaping () -> Void) {
|
||||
@ -293,6 +295,12 @@ final class BotReceiptControllerNode: ItemListControllerNode {
|
||||
|
||||
return (ItemListPresentationData(presentationData), (nodeState, arguments))
|
||||
}
|
||||
|
||||
self.actionButtonPanelNode = ASDisplayNode()
|
||||
self.actionButtonPanelNode.backgroundColor = self.presentationData.theme.rootController.navigationBar.backgroundColor
|
||||
|
||||
self.actionButtonPanelSeparator = ASDisplayNode()
|
||||
self.actionButtonPanelSeparator.backgroundColor = self.presentationData.theme.rootController.navigationBar.separatorColor
|
||||
|
||||
self.actionButton = BotCheckoutActionButton(inactiveFillColor: self.presentationData.theme.list.plainBackgroundColor, activeFillColor: self.presentationData.theme.list.itemAccentColor, foregroundColor: self.presentationData.theme.list.plainBackgroundColor)
|
||||
self.actionButton.setState(.active(self.presentationData.strings.Common_Done))
|
||||
@ -301,12 +309,18 @@ final class BotReceiptControllerNode: ItemListControllerNode {
|
||||
|
||||
self.dataRequestDisposable = (requestBotPaymentReceipt(account: context.account, messageId: messageId) |> deliverOnMainQueue).start(next: { [weak self] receipt in
|
||||
if let strongSelf = self {
|
||||
UIView.transition(with: strongSelf.view, duration: 0.25, options: UIView.AnimationOptions.transitionCrossDissolve, animations: {
|
||||
}, completion: nil)
|
||||
|
||||
strongSelf.receiptData.set(.single((receipt.invoice, receipt.info, receipt.shippingOption, receipt.credentialsTitle, receipt.invoiceMedia, receipt.tipAmount)))
|
||||
}
|
||||
})
|
||||
|
||||
self.actionButton.addTarget(self, action: #selector(self.actionButtonPressed), forControlEvents: .touchUpInside)
|
||||
self.addSubnode(self.actionButton)
|
||||
|
||||
self.addSubnode(self.actionButtonPanelNode)
|
||||
self.actionButtonPanelNode.addSubnode(self.actionButtonPanelSeparator)
|
||||
self.actionButtonPanelNode.addSubnode(self.actionButton)
|
||||
}
|
||||
|
||||
deinit {
|
||||
@ -315,13 +329,21 @@ final class BotReceiptControllerNode: ItemListControllerNode {
|
||||
|
||||
override func containerLayoutUpdated(_ layout: ContainerViewLayout, navigationBarHeight: CGFloat, transition: ContainedViewLayoutTransition, additionalInsets: UIEdgeInsets) {
|
||||
var updatedInsets = layout.intrinsicInsets
|
||||
updatedInsets.bottom += BotCheckoutActionButton.height + 16.0 * 2.0
|
||||
|
||||
super.containerLayoutUpdated(ContainerViewLayout(size: layout.size, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, intrinsicInsets: updatedInsets, safeInsets: layout.safeInsets, additionalInsets: layout.additionalInsets, statusBarHeight: layout.statusBarHeight, inputHeight: layout.inputHeight, inputHeightIsInteractivellyChanging: layout.inputHeightIsInteractivellyChanging, inVoiceOver: layout.inVoiceOver), navigationBarHeight: navigationBarHeight, transition: transition, additionalInsets: additionalInsets)
|
||||
|
||||
let actionButtonFrame = CGRect(origin: CGPoint(x: 16.0, y: layout.size.height - 16.0 - BotCheckoutActionButton.height - layout.intrinsicInsets.bottom), size: CGSize(width: layout.size.width - 16.0 * 2.0, height: BotCheckoutActionButton.height))
|
||||
let bottomPanelHorizontalInset: CGFloat = 16.0
|
||||
let bottomPanelVerticalInset: CGFloat = 16.0
|
||||
let bottomPanelHeight = max(updatedInsets.bottom, layout.inputHeight ?? 0.0) + bottomPanelVerticalInset * 2.0 + BotCheckoutActionButton.height
|
||||
|
||||
transition.updateFrame(node: self.actionButtonPanelNode, frame: CGRect(origin: CGPoint(x: 0.0, y: layout.size.height - bottomPanelHeight), size: CGSize(width: layout.size.width, height: bottomPanelHeight)))
|
||||
transition.updateFrame(node: self.actionButtonPanelSeparator, frame: CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: CGSize(width: layout.size.width, height: UIScreenPixel)))
|
||||
|
||||
let actionButtonFrame = CGRect(origin: CGPoint(x: bottomPanelHorizontalInset, y: bottomPanelVerticalInset), size: CGSize(width: layout.size.width - bottomPanelHorizontalInset * 2.0, height: BotCheckoutActionButton.height))
|
||||
transition.updateFrame(node: self.actionButton, frame: actionButtonFrame)
|
||||
self.actionButton.updateLayout(size: actionButtonFrame.size, transition: transition)
|
||||
|
||||
updatedInsets.bottom = bottomPanelHeight
|
||||
|
||||
super.containerLayoutUpdated(ContainerViewLayout(size: layout.size, metrics: layout.metrics, deviceMetrics: layout.deviceMetrics, intrinsicInsets: updatedInsets, safeInsets: layout.safeInsets, additionalInsets: layout.additionalInsets, statusBarHeight: layout.statusBarHeight, inputHeight: layout.inputHeight, inputHeightIsInteractivellyChanging: layout.inputHeightIsInteractivellyChanging, inVoiceOver: layout.inVoiceOver), navigationBarHeight: navigationBarHeight, transition: transition, additionalInsets: additionalInsets)
|
||||
}
|
||||
|
||||
@objc func actionButtonPressed() {
|
||||
|
@ -4024,13 +4024,21 @@ open class ListView: ASDisplayNode, UIScrollViewAccessibilityDelegate, UIGesture
|
||||
}
|
||||
}
|
||||
|
||||
public func ensureItemNodeVisible(_ node: ListViewItemNode, animated: Bool = true, overflow: CGFloat = 0.0, allowIntersection: Bool = false, curve: ListViewAnimationCurve = .Default(duration: 0.25)) {
|
||||
public func ensureItemNodeVisible(_ node: ListViewItemNode, animated: Bool = true, overflow: CGFloat = 0.0, allowIntersection: Bool = false, atTop: Bool = false, curve: ListViewAnimationCurve = .Default(duration: 0.25)) {
|
||||
if let index = node.index {
|
||||
if node.apparentHeight > self.visibleSize.height - self.insets.top - self.insets.bottom {
|
||||
if node.frame.maxY > self.visibleSize.height - self.insets.bottom {
|
||||
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.bottom(-overflow), animated: animated, curve: curve, directionHint: ListViewScrollToItemDirectionHint.Down), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
} else if node.frame.minY < self.insets.top && overflow > 0.0 {
|
||||
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.top(-overflow), animated: animated, curve: curve, directionHint: ListViewScrollToItemDirectionHint.Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
if atTop {
|
||||
if node.frame.maxY > self.visibleSize.height - self.insets.bottom {
|
||||
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.top(-overflow), animated: animated, curve: curve, directionHint: ListViewScrollToItemDirectionHint.Down), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
} else if node.frame.minY < self.insets.top && overflow > 0.0 {
|
||||
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.top(-overflow), animated: animated, curve: curve, directionHint: ListViewScrollToItemDirectionHint.Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
}
|
||||
} else {
|
||||
if node.frame.maxY > self.visibleSize.height - self.insets.bottom {
|
||||
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.bottom(-overflow), animated: animated, curve: curve, directionHint: ListViewScrollToItemDirectionHint.Down), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
} else if node.frame.minY < self.insets.top && overflow > 0.0 {
|
||||
self.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: ListViewDeleteAndInsertOptions(), scrollToItem: ListViewScrollToItem(index: index, position: ListViewScrollPosition.top(-overflow), animated: animated, curve: curve, directionHint: ListViewScrollToItemDirectionHint.Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if self.experimentalSnapScrollToItem {
|
||||
|
@ -79,7 +79,7 @@ public enum GetCurrentGroupCallError {
|
||||
case generic
|
||||
}
|
||||
|
||||
public func getCurrentGroupCall(account: Account, callId: Int64, accessHash: Int64) -> Signal<GroupCallSummary?, GetCurrentGroupCallError> {
|
||||
public func getCurrentGroupCall(account: Account, callId: Int64, accessHash: Int64, peerId: PeerId? = nil) -> Signal<GroupCallSummary?, GetCurrentGroupCallError> {
|
||||
return account.network.request(Api.functions.phone.getGroupCall(call: .inputGroupCall(id: callId, accessHash: accessHash)))
|
||||
|> mapError { _ -> GetCurrentGroupCallError in
|
||||
return .generic
|
||||
@ -92,6 +92,7 @@ public func getCurrentGroupCall(account: Account, callId: Int64, accessHash: Int
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
var peers: [Peer] = []
|
||||
var peerPresences: [PeerId: PeerPresence] = [:]
|
||||
|
||||
@ -108,6 +109,17 @@ public func getCurrentGroupCall(account: Account, callId: Int64, accessHash: Int
|
||||
peers.append(peer)
|
||||
}
|
||||
}
|
||||
if let peerId = peerId {
|
||||
transaction.updatePeerCachedData(peerIds: [peerId], update: { _, current in
|
||||
if let cachedData = current as? CachedChannelData {
|
||||
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall.init(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: cachedData.activeCall?.subscribedToScheduled ?? false))
|
||||
} else if let cachedData = current as? CachedGroupData {
|
||||
return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: cachedData.activeCall?.subscribedToScheduled ?? false))
|
||||
} else {
|
||||
return current
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
updatePeers(transaction: transaction, peers: peers, update: { _, updated -> Peer in
|
||||
return updated
|
||||
|
Loading…
x
Reference in New Issue
Block a user