mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
a288c543f2
@ -7778,6 +7778,7 @@ Sorry for the inconvenience.";
|
||||
"WebApp.Settings" = "Settings";
|
||||
|
||||
"Bot.AccepRecurrentInfo" = "I accept the [Terms of Service]() of **%1$@**";
|
||||
"Bot.AcceptTermsInfo" = "I accept the [Terms of Service]() of **%1$@**";
|
||||
|
||||
"Chat.AudioTranscriptionRateAction" = "Rate Transcription";
|
||||
"Chat.AudioTranscriptionFeedbackTip" = "Thank you for your feedback.";
|
||||
|
@ -559,7 +559,7 @@ private final class RecurrentConfirmationNode: ASDisplayNode {
|
||||
return super.hitTest(point, with: event)
|
||||
}
|
||||
|
||||
func update(presentationData: PresentationData, botName: String, width: CGFloat, sideInset: CGFloat) -> CGFloat {
|
||||
func update(presentationData: PresentationData, botName: String, isRecurrent: Bool, width: CGFloat, sideInset: CGFloat) -> CGFloat {
|
||||
let spacing: CGFloat = 16.0
|
||||
let topInset: CGFloat = 8.0
|
||||
|
||||
@ -580,7 +580,7 @@ private final class RecurrentConfirmationNode: ASDisplayNode {
|
||||
self.textNode.linkHighlightColor = presentationData.theme.list.itemAccentColor.withAlphaComponent(0.2)
|
||||
|
||||
let attributedText = parseMarkdownIntoAttributedString(
|
||||
presentationData.strings.Bot_AccepRecurrentInfo(botName).string,
|
||||
isRecurrent ? presentationData.strings.Bot_AccepRecurrentInfo(botName).string : presentationData.strings.Bot_AcceptTermsInfo(botName).string,
|
||||
attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: Font.regular(13.0), textColor: presentationData.theme.list.freeTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(13.0), textColor: presentationData.theme.list.freeTextColor),
|
||||
@ -619,7 +619,7 @@ private final class ActionButtonPanelNode: ASDisplayNode {
|
||||
var height = max(layout.intrinsicInsets.bottom, layout.inputHeight ?? 0.0) + bottomPanelVerticalInset * 2.0 + BotCheckoutActionButton.height
|
||||
var actionButtonOffset: CGFloat = bottomPanelVerticalInset
|
||||
|
||||
if let invoice = invoice, let recurrentInfo = invoice.recurrentInfo, let botName = botName {
|
||||
if let invoice = invoice, let termsInfo = invoice.termsInfo, let botName = botName {
|
||||
let recurrentConfirmationNode: RecurrentConfirmationNode
|
||||
if let current = self.recurrentConfirmationNode {
|
||||
recurrentConfirmationNode = current
|
||||
@ -637,9 +637,7 @@ private final class ActionButtonPanelNode: ASDisplayNode {
|
||||
self.addSubnode(recurrentConfirmationNode)
|
||||
}
|
||||
|
||||
let _ = recurrentInfo
|
||||
|
||||
let recurrentConfirmationHeight = recurrentConfirmationNode.update(presentationData: presentationData, botName: botName, width: layout.size.width, sideInset: layout.safeInsets.left + 33.0)
|
||||
let recurrentConfirmationHeight = recurrentConfirmationNode.update(presentationData: presentationData, botName: botName, isRecurrent: termsInfo.isRecurrent, width: layout.size.width, sideInset: layout.safeInsets.left + 33.0)
|
||||
recurrentConfirmationNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: layout.size.width, height: recurrentConfirmationHeight))
|
||||
|
||||
actionButtonOffset += recurrentConfirmationHeight
|
||||
@ -776,10 +774,10 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
}
|
||||
|
||||
self.actionButtonPanelNode.openRecurrentTerms = { [weak self] in
|
||||
guard let strongSelf = self, let paymentForm = strongSelf.paymentFormValue, let recurrentInfo = paymentForm.invoice.recurrentInfo else {
|
||||
guard let strongSelf = self, let paymentForm = strongSelf.paymentFormValue, let termsInfo = paymentForm.invoice.termsInfo else {
|
||||
return
|
||||
}
|
||||
strongSelf.context.sharedContext.openExternalUrl(context: strongSelf.context, urlContext: .generic, url: recurrentInfo.termsUrl, forceExternal: true, presentationData: context.sharedContext.currentPresentationData.with { $0 }, navigationController: nil, dismissInput: {
|
||||
strongSelf.context.sharedContext.openExternalUrl(context: strongSelf.context, urlContext: .generic, url: termsInfo.termsUrl, forceExternal: true, presentationData: context.sharedContext.currentPresentationData.with { $0 }, navigationController: nil, dismissInput: {
|
||||
self?.view.endEditing(true)
|
||||
})
|
||||
}
|
||||
@ -1191,7 +1189,7 @@ final class BotCheckoutControllerNode: ItemListControllerNode, PKPaymentAuthoriz
|
||||
if let paymentForm = self.paymentFormValue, totalAmount > 0 {
|
||||
payString = self.presentationData.strings.Checkout_PayPrice(formatCurrencyAmount(totalAmount, currency: paymentForm.invoice.currency)).string
|
||||
|
||||
if let _ = paymentForm.invoice.recurrentInfo {
|
||||
if let _ = paymentForm.invoice.termsInfo {
|
||||
if !self.actionButtonPanelNode.isAccepted {
|
||||
isButtonEnabled = false
|
||||
}
|
||||
|
@ -1288,7 +1288,9 @@ public final class ChatListNode: ListView {
|
||||
|
||||
super.init()
|
||||
|
||||
//self.useMainQueueTransactions = true
|
||||
if case .internal = context.sharedContext.applicationBindings.appBuildType {
|
||||
self.useMainQueueTransactions = true
|
||||
}
|
||||
|
||||
self.verticalScrollIndicatorColor = theme.list.scrollIndicatorColor
|
||||
self.verticalScrollIndicatorFollowsOverscroll = true
|
||||
|
@ -225,14 +225,19 @@ public final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelega
|
||||
return
|
||||
}
|
||||
|
||||
topController.viewWillDisappear(true)
|
||||
topController.beginAppearanceTransition(false, animated: true)
|
||||
//topController.viewWillDisappear(true)
|
||||
|
||||
let topNode = topController.displayNode
|
||||
var bottomControllerLayout = layout
|
||||
if bottomController.view.disableAutomaticKeyboardHandling.isEmpty {
|
||||
bottomControllerLayout = bottomControllerLayout.withUpdatedInputHeight(nil)
|
||||
}
|
||||
bottomController.containerLayoutUpdated(bottomControllerLayout, transition: .immediate)
|
||||
bottomController.viewWillAppear(true)
|
||||
|
||||
bottomController.beginAppearanceTransition(true, animated: true)
|
||||
//bottomController.viewWillAppear(true)
|
||||
|
||||
let bottomNode = bottomController.displayNode
|
||||
|
||||
let navigationTransitionCoordinator = NavigationTransitionCoordinator(transition: .Pop, isInteractive: true, isFlat: self.isFlat, container: self, topNode: topNode, topNavigationBar: topController.transitionNavigationBar, bottomNode: bottomNode, bottomNavigationBar: bottomController.transitionNavigationBar, didUpdateProgress: { [weak self, weak bottomController] progress, transition, topFrame, bottomFrame in
|
||||
@ -291,9 +296,12 @@ public final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelega
|
||||
return
|
||||
}
|
||||
strongSelf.state.transition = nil
|
||||
|
||||
top.value.viewDidAppear(true)
|
||||
transition.previous.value.viewDidDisappear(true)
|
||||
|
||||
top.value.endAppearanceTransition()
|
||||
//top.value.viewDidAppear(true)
|
||||
|
||||
transition.previous.value.endAppearanceTransition()
|
||||
//transition.previous.value.viewDidDisappear(true)
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -452,8 +460,13 @@ public final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelega
|
||||
}
|
||||
|
||||
fromValue.value.viewWillLeaveNavigation()
|
||||
fromValue.value.viewWillDisappear(true)
|
||||
toValue.value.viewWillAppear(true)
|
||||
|
||||
fromValue.value.beginAppearanceTransition(false, animated: true)
|
||||
//fromValue.value.viewWillDisappear(true)
|
||||
|
||||
toValue.value.beginAppearanceTransition(true, animated: true)
|
||||
//toValue.value.viewWillAppear(true)
|
||||
|
||||
toValue.value.setIgnoreAppearanceMethodInvocations(true)
|
||||
if let layout = self.state.layout {
|
||||
toValue.value.displayNode.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||
@ -517,11 +530,16 @@ public final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelega
|
||||
topTransition.previous.value.displayNode.removeFromSupernode()
|
||||
topTransition.previous.value.setIgnoreAppearanceMethodInvocations(false)
|
||||
}
|
||||
topTransition.previous.value.viewDidDisappear(true)
|
||||
|
||||
topTransition.previous.value.endAppearanceTransition()
|
||||
//topTransition.previous.value.viewDidDisappear(true)
|
||||
|
||||
if let toValue = strongSelf.state.top, let layout = strongSelf.state.layout {
|
||||
toValue.value.displayNode.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||
strongSelf.applyLayout(layout: layout, to: toValue, isMaster: true, transition: .immediate)
|
||||
toValue.value.viewDidAppear(true)
|
||||
|
||||
toValue.value.endAppearanceTransition()
|
||||
//toValue.value.viewDidAppear(true)
|
||||
}
|
||||
|
||||
strongSelf.ignoreInputHeight = false
|
||||
@ -533,24 +551,33 @@ public final class NavigationContainer: ASDisplayNode, UIGestureRecognizerDelega
|
||||
}
|
||||
|
||||
fromValue.value.viewWillLeaveNavigation()
|
||||
fromValue.value.viewWillDisappear(false)
|
||||
|
||||
fromValue.value.beginAppearanceTransition(false, animated: false)
|
||||
//fromValue.value.viewWillDisappear(false)
|
||||
|
||||
self.keyboardViewManager?.dismissEditingWithoutAnimation(view: fromValue.value.view)
|
||||
|
||||
fromValue.value.setIgnoreAppearanceMethodInvocations(true)
|
||||
fromValue.value.displayNode.removeFromSupernode()
|
||||
fromValue.value.setIgnoreAppearanceMethodInvocations(false)
|
||||
fromValue.value.viewDidDisappear(false)
|
||||
|
||||
fromValue.value.endAppearanceTransition()
|
||||
//fromValue.value.viewDidDisappear(false)
|
||||
}
|
||||
if let toValue = toValue {
|
||||
self.applyLayout(layout: layout, to: toValue, isMaster: true, transition: .immediate)
|
||||
toValue.value.displayNode.frame = CGRect(origin: CGPoint(), size: layout.size)
|
||||
toValue.value.viewWillAppear(false)
|
||||
|
||||
toValue.value.beginAppearanceTransition(true, animated: false)
|
||||
//toValue.value.viewWillAppear(false)
|
||||
|
||||
toValue.value.setIgnoreAppearanceMethodInvocations(true)
|
||||
self.addSubnode(toValue.value.displayNode)
|
||||
toValue.value.setIgnoreAppearanceMethodInvocations(false)
|
||||
toValue.value.displayNode.recursivelyEnsureDisplaySynchronously(true)
|
||||
toValue.value.viewDidAppear(false)
|
||||
|
||||
toValue.value.endAppearanceTransition()
|
||||
//toValue.value.viewDidAppear(false)
|
||||
}
|
||||
self.ignoreInputHeight = false
|
||||
}
|
||||
|
@ -1188,13 +1188,13 @@ public class Account {
|
||||
},
|
||||
self.pendingPeerMediaUploadManager.uploadingPeerMedia |> map { uploadingPeerMedia in
|
||||
if !uploadingPeerMedia.isEmpty {
|
||||
print("updatingMessageMedia: true")
|
||||
print("uploadingPeerMedia: true")
|
||||
}
|
||||
return !uploadingPeerMedia.isEmpty ? AccountRunningImportantTasks.pendingMessages : []
|
||||
},
|
||||
self.accountPresenceManager.isPerformingUpdate() |> map { presenceUpdate in
|
||||
if presenceUpdate {
|
||||
print("updatingMessageMedia: true")
|
||||
print("accountPresenceManager isPerformingUpdate: true")
|
||||
return []
|
||||
}
|
||||
return presenceUpdate ? AccountRunningImportantTasks.other : []
|
||||
|
@ -47,6 +47,7 @@ public struct BotPaymentInvoice : Equatable {
|
||||
|
||||
public struct RecurrentInfo: Equatable {
|
||||
public var termsUrl: String
|
||||
public var isRecurrent: Bool
|
||||
}
|
||||
|
||||
public let isTest: Bool
|
||||
@ -54,7 +55,7 @@ public struct BotPaymentInvoice : Equatable {
|
||||
public let currency: String
|
||||
public let prices: [BotPaymentPrice]
|
||||
public let tip: Tip?
|
||||
public let recurrentInfo: RecurrentInfo?
|
||||
public let termsInfo: RecurrentInfo?
|
||||
}
|
||||
|
||||
public struct BotPaymentNativeProvider : Equatable {
|
||||
@ -144,7 +145,7 @@ public enum BotPaymentFormRequestError {
|
||||
extension BotPaymentInvoice {
|
||||
init(apiInvoice: Api.Invoice) {
|
||||
switch apiInvoice {
|
||||
case let .invoice(flags, currency, prices, maxTipAmount, suggestedTipAmounts, recurrentTermsUrl):
|
||||
case let .invoice(flags, currency, prices, maxTipAmount, suggestedTipAmounts, termsUrl):
|
||||
var fields = BotPaymentInvoiceFields()
|
||||
if (flags & (1 << 1)) != 0 {
|
||||
fields.insert(.name)
|
||||
@ -167,9 +168,10 @@ extension BotPaymentInvoice {
|
||||
if (flags & (1 << 7)) != 0 {
|
||||
fields.insert(.emailAvailableToProvider)
|
||||
}
|
||||
var recurrentInfo: BotPaymentInvoice.RecurrentInfo?
|
||||
if let recurrentTermsUrl = recurrentTermsUrl {
|
||||
recurrentInfo = BotPaymentInvoice.RecurrentInfo(termsUrl: recurrentTermsUrl)
|
||||
let isRecurrent = (flags & (1 << 9)) != 0
|
||||
var termsInfo: BotPaymentInvoice.RecurrentInfo?
|
||||
if let termsUrl = termsUrl {
|
||||
termsInfo = BotPaymentInvoice.RecurrentInfo(termsUrl: termsUrl, isRecurrent: isRecurrent)
|
||||
}
|
||||
var parsedTip: BotPaymentInvoice.Tip?
|
||||
if let maxTipAmount = maxTipAmount, let suggestedTipAmounts = suggestedTipAmounts {
|
||||
@ -180,7 +182,7 @@ extension BotPaymentInvoice {
|
||||
case let .labeledPrice(label, amount):
|
||||
return BotPaymentPrice(label: label, amount: amount)
|
||||
}
|
||||
}, tip: parsedTip, recurrentInfo: recurrentInfo)
|
||||
}, tip: parsedTip, termsInfo: termsInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -381,6 +381,8 @@ private final class StoryContainerScreenComponent: Component {
|
||||
|
||||
private let sharedViewListsContext = StoryItemSetViewListComponent.SharedListsContext()
|
||||
|
||||
private var didAnimateIn: Bool = false
|
||||
|
||||
private var isAnimatingOut: Bool = false
|
||||
private var didAnimateOut: Bool = false
|
||||
private var isDismissedExlusively: Bool = false
|
||||
@ -429,25 +431,6 @@ private final class StoryContainerScreenComponent: Component {
|
||||
})
|
||||
self.addGestureRecognizer(horizontalPanRecognizer)
|
||||
|
||||
//TODO:move dismiss pan
|
||||
/*let verticalPanRecognizer = InteractiveTransitionGestureRecognizer(target: self, action: #selector(self.dismissPanGesture(_:)), allowedDirections: { [weak self] point in
|
||||
guard let self, let component = self.component, let stateValue = self.stateValue, let slice = stateValue.slice, let itemSetView = self.visibleItemSetViews[slice.peer.id], let itemSetComponentView = itemSetView.view.view as? StoryItemSetContainerComponent.View else {
|
||||
return []
|
||||
}
|
||||
if let environment = self.environment, case .regular = environment.metrics.widthClass {
|
||||
} else {
|
||||
if !itemSetComponentView.isPointInsideContentArea(point: self.convert(point, to: itemSetComponentView)) {
|
||||
return []
|
||||
}
|
||||
}
|
||||
if !itemSetComponentView.allowsVerticalPanGesture() {
|
||||
return []
|
||||
}
|
||||
|
||||
return [.down]
|
||||
})
|
||||
self.addGestureRecognizer(verticalPanRecognizer)*/
|
||||
|
||||
let longPressRecognizer = StoryLongPressRecognizer(target: self, action: #selector(self.longPressGesture(_:)))
|
||||
longPressRecognizer.delegate = self
|
||||
longPressRecognizer.updateIsTracking = { [weak self] point in
|
||||
@ -809,74 +792,6 @@ private final class StoryContainerScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
/*@objc private func dismissPanGesture(_ recognizer: UIPanGestureRecognizer) {
|
||||
switch recognizer.state {
|
||||
case .began:
|
||||
self.dismissAllTooltips()
|
||||
|
||||
if let component = self.component, let stateValue = self.stateValue, let slice = stateValue.slice, let itemSetView = self.visibleItemSetViews[slice.peer.id] {
|
||||
if let itemSetComponentView = itemSetView.view.view as? StoryItemSetContainerComponent.View {
|
||||
if itemSetComponentView.hasActiveDeactivateableInput() {
|
||||
itemSetComponentView.deactivateInput()
|
||||
recognizer.isEnabled = false
|
||||
recognizer.isEnabled = true
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.verticalPanState = ItemSetPanState(fraction: 0.0, didBegin: true)
|
||||
self.state?.updated(transition: .immediate)
|
||||
case .changed:
|
||||
let translation = recognizer.translation(in: self)
|
||||
self.verticalPanState = ItemSetPanState(fraction: max(-1.0, min(1.0, translation.y / self.bounds.height)), didBegin: true)
|
||||
self.state?.updated(transition: .immediate)
|
||||
|
||||
if translation.y < -40.0 {
|
||||
if let component = self.component, let stateValue = self.stateValue, let slice = stateValue.slice, let itemSetView = self.visibleItemSetViews[slice.peer.id] {
|
||||
if let itemSetComponentView = itemSetView.view.view as? StoryItemSetContainerComponent.View {
|
||||
if let activateInputWhileDragging = itemSetComponentView.activateInputWhileDragging() {
|
||||
activateInputWhileDragging()
|
||||
|
||||
self.verticalPanState = nil
|
||||
recognizer.state = .cancelled
|
||||
self.state?.updated(transition: Transition(animation: .curve(duration: 0.3, curve: .spring)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case .cancelled, .ended:
|
||||
if self.verticalPanState != nil {
|
||||
let translation = recognizer.translation(in: self)
|
||||
let velocity = recognizer.velocity(in: self)
|
||||
|
||||
self.verticalPanState = nil
|
||||
var updateState = true
|
||||
|
||||
if translation.y > 200.0 || (translation.y > 5.0 && velocity.y > 200.0) {
|
||||
self.state?.updated(transition: Transition(animation: .curve(duration: 0.3, curve: .spring)))
|
||||
self.environment?.controller()?.dismiss()
|
||||
} else if translation.y < -200.0 || (translation.y < -100.0 && velocity.y < -100.0) {
|
||||
if let component = self.component, let stateValue = self.stateValue, let slice = stateValue.slice, let itemSetView = self.visibleItemSetViews[slice.peer.id] {
|
||||
if let itemSetComponentView = itemSetView.view.view as? StoryItemSetContainerComponent.View {
|
||||
if itemSetComponentView.activateInput() {
|
||||
updateState = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if updateState || "".isEmpty {
|
||||
self.state?.updated(transition: Transition(animation: .curve(duration: 0.3, curve: .spring)))
|
||||
}
|
||||
} else {
|
||||
self.state?.updated(transition: Transition(animation: .curve(duration: 0.3, curve: .spring)))
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
}*/
|
||||
|
||||
@objc private func longPressGesture(_ recognizer: StoryLongPressRecognizer) {
|
||||
switch recognizer.state {
|
||||
case .began:
|
||||
@ -963,13 +878,33 @@ private final class StoryContainerScreenComponent: Component {
|
||||
|
||||
if let transitionIn = self.component?.transitionIn, let stateValue = self.stateValue, let slice = stateValue.slice, let itemSetView = self.visibleItemSetViews[slice.peer.id] {
|
||||
if let itemSetComponentView = itemSetView.view.view as? StoryItemSetContainerComponent.View {
|
||||
itemSetComponentView.animateIn(transitionIn: transitionIn)
|
||||
itemSetComponentView.animateIn(transitionIn: transitionIn, completion: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
self.didAnimateIn = true
|
||||
self.state?.updated(transition: .immediate)
|
||||
})
|
||||
} else {
|
||||
self.didAnimateIn = true
|
||||
self.state?.updated(transition: .immediate)
|
||||
}
|
||||
} else {
|
||||
self.didAnimateIn = true
|
||||
self.state?.updated(transition: .immediate)
|
||||
}
|
||||
} else {
|
||||
self.layer.allowsGroupOpacity = true
|
||||
self.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, completion: { [weak self] _ in
|
||||
self?.layer.allowsGroupOpacity = false
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
self.layer.allowsGroupOpacity = false
|
||||
|
||||
self.didAnimateIn = true
|
||||
self.state?.updated(transition: .immediate)
|
||||
})
|
||||
}
|
||||
|
||||
@ -1416,6 +1351,15 @@ private final class StoryContainerScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
if self.didAnimateIn && self.itemSetPanState == nil {
|
||||
if i == focusedIndex - 1 {
|
||||
isItemVisible = true
|
||||
}
|
||||
if i == focusedIndex + 1 {
|
||||
isItemVisible = true
|
||||
}
|
||||
}
|
||||
|
||||
if isItemVisible {
|
||||
validIds.append(slice.peer.id)
|
||||
|
||||
@ -1449,6 +1393,8 @@ private final class StoryContainerScreenComponent: Component {
|
||||
}
|
||||
|
||||
itemSetView.view.parentState = self.state
|
||||
|
||||
let startTime = CFAbsoluteTimeGetCurrent()
|
||||
let _ = itemSetView.view.update(
|
||||
transition: itemSetTransition,
|
||||
component: AnyComponent(StoryItemSetContainerComponent(
|
||||
@ -1592,6 +1538,7 @@ private final class StoryContainerScreenComponent: Component {
|
||||
if let itemSetComponentView = itemSetView.view.view as? StoryItemSetContainerComponent.View {
|
||||
if itemSetView.superview == nil {
|
||||
self.addSubview(itemSetView)
|
||||
print("init time: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
|
||||
}
|
||||
if itemSetComponentView.superview == nil {
|
||||
itemSetView.tintLayer.isDoubleSided = false
|
||||
|
@ -1937,7 +1937,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
return nil
|
||||
}
|
||||
|
||||
func animateIn(transitionIn: StoryContainerScreen.TransitionIn) {
|
||||
func animateIn(transitionIn: StoryContainerScreen.TransitionIn, completion: @escaping () -> Void) {
|
||||
if let inputPanelView = self.inputPanel.view {
|
||||
inputPanelView.layer.animatePosition(
|
||||
from: CGPoint(x: 0.0, y: self.bounds.height - inputPanelView.frame.minY),
|
||||
@ -1998,7 +1998,9 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
if let closeFriendIcon = self.privacyIcon?.view {
|
||||
closeFriendIcon.layer.animateAlpha(from: 0.0, to: closeFriendIcon.alpha, duration: 0.25)
|
||||
}
|
||||
self.closeButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25)
|
||||
self.closeButton.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.25, completion: { _ in
|
||||
completion()
|
||||
})
|
||||
|
||||
self.topContentGradientView.layer.animateAlpha(from: 0.0, to: self.topContentGradientView.alpha, duration: 0.25)
|
||||
|
||||
@ -2057,6 +2059,8 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
)
|
||||
visibleItemView.layer.animateScale(from: innerScale, to: 1.0, duration: 0.3, timingFunction: kCAMediaTimingFunctionSpring)
|
||||
}
|
||||
} else {
|
||||
completion()
|
||||
}
|
||||
}
|
||||
|
||||
@ -3998,6 +4002,13 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
self.captionItem = captionItem
|
||||
}
|
||||
|
||||
var enableEntities = true
|
||||
if case .user = component.slice.peer {
|
||||
if !component.slice.peer.isService && !component.slice.peer.isPremium {
|
||||
enableEntities = false
|
||||
}
|
||||
}
|
||||
|
||||
let captionSize = captionItem.view.update(
|
||||
transition: captionItemTransition,
|
||||
component: AnyComponent(StoryContentCaptionComponent(
|
||||
@ -4006,7 +4017,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
strings: component.strings,
|
||||
theme: component.theme,
|
||||
text: component.slice.item.storyItem.text,
|
||||
entities: component.slice.peer.isPremium ? component.slice.item.storyItem.entities : [],
|
||||
entities: enableEntities ? component.slice.item.storyItem.entities : [],
|
||||
entityFiles: component.slice.item.entityFiles,
|
||||
action: { [weak self] action in
|
||||
guard let self, let component = self.component else {
|
||||
|
@ -1476,6 +1476,15 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
||||
|
||||
let _ = self.urlSession(identifier: "\(baseAppBundleId).backroundSession")
|
||||
|
||||
var previousReportedMemoryConsumption = 0
|
||||
let _ = Foundation.Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true, block: { _ in
|
||||
let value = getMemoryConsumption()
|
||||
if abs(value - previousReportedMemoryConsumption) > 1 * 1024 * 1024 {
|
||||
previousReportedMemoryConsumption = value
|
||||
Logger.shared.log("App \(self.episodeId)", "Memory consumption: \(value / (1024 * 1024)) MB")
|
||||
}
|
||||
})
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@ -2834,3 +2843,22 @@ private func downloadHTTPData(url: URL) -> Signal<Data, DownloadFileError> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func getMemoryConsumption() -> Int {
|
||||
guard let memory_offset = MemoryLayout.offset(of: \task_vm_info_data_t.min_address) else {
|
||||
return 0
|
||||
}
|
||||
let TASK_VM_INFO_COUNT = mach_msg_type_number_t(MemoryLayout<task_vm_info_data_t>.size / MemoryLayout<integer_t>.size)
|
||||
let TASK_VM_INFO_REV1_COUNT = mach_msg_type_number_t(memory_offset / MemoryLayout<integer_t>.size)
|
||||
var info = task_vm_info_data_t()
|
||||
var count = TASK_VM_INFO_COUNT
|
||||
let kr = withUnsafeMutablePointer(to: &info) { infoPtr in
|
||||
infoPtr.withMemoryRebound(to: integer_t.self, capacity: Int(count)) { intPtr in
|
||||
task_info(mach_task_self_, task_flavor_t(TASK_VM_INFO), intPtr, &count)
|
||||
}
|
||||
}
|
||||
guard kr == KERN_SUCCESS, count >= TASK_VM_INFO_REV1_COUNT else {
|
||||
return 0
|
||||
}
|
||||
return Int(info.phys_footprint)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user