mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Gift improvements
This commit is contained in:
parent
75e9a0adba
commit
f08fef3991
@ -1041,7 +1041,7 @@ public protocol SharedAccountContext: AnyObject {
|
||||
func makeMiniAppListScreenInitialData(context: AccountContext) -> Signal<MiniAppListScreenInitialData, NoError>
|
||||
func makeMiniAppListScreen(context: AccountContext, initialData: MiniAppListScreenInitialData) -> ViewController
|
||||
|
||||
func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: EnginePeer, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool)
|
||||
func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: EnginePeer, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?)
|
||||
|
||||
func makeDebugSettingsController(context: AccountContext?) -> ViewController?
|
||||
|
||||
|
@ -3672,7 +3672,8 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
url: "",
|
||||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true
|
||||
skipTermsOfService: true,
|
||||
payload: nil
|
||||
)
|
||||
} else {
|
||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(
|
||||
|
@ -74,6 +74,7 @@ final class GiftSetupScreenComponent: Component {
|
||||
private let scrollView: ScrollView
|
||||
|
||||
private let navigationTitle = ComponentView<Empty>()
|
||||
private let remainingCount = ComponentView<Empty>()
|
||||
private let introContent = ComponentView<Empty>()
|
||||
private let introSection = ComponentView<Empty>()
|
||||
private let hideSection = ComponentView<Empty>()
|
||||
@ -301,6 +302,10 @@ final class GiftSetupScreenComponent: Component {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
self.inProgress = true
|
||||
self.state?.updated()
|
||||
|
||||
let entities = generateChatInputTextEntities(self.textInputState.text)
|
||||
let source: BotPaymentInvoiceSource = .starGift(hideName: self.hideName, peerId: component.peerId, giftId: starGift.id, text: self.textInputState.text.string, entities: entities)
|
||||
|
||||
@ -558,6 +563,43 @@ final class GiftSetupScreenComponent: Component {
|
||||
contentHeight += environment.navigationHeight
|
||||
contentHeight += 26.0
|
||||
|
||||
if case let .starGift(starGift) = component.subject, let availability = starGift.availability {
|
||||
//TODO:localize
|
||||
let remains: Int32 = Int32(CGFloat(availability.remains) * 0.66)
|
||||
let position = CGFloat(remains) / CGFloat(availability.total)
|
||||
let remainsString = "\(remains)" //presentationStringsFormattedNumber(remains, environment.dateTimeFormat.groupingSeparator)
|
||||
let totalString = presentationStringsFormattedNumber(availability.total, environment.dateTimeFormat.groupingSeparator)
|
||||
let remainingCountSize = self.remainingCount.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(RemainingCountComponent(
|
||||
inactiveColor: environment.theme.list.itemBlocksSeparatorColor.withAlphaComponent(0.3),
|
||||
activeColors: [UIColor(rgb: 0x5bc2ff), UIColor(rgb: 0x2d9eff)],
|
||||
inactiveTitle: "Limited",
|
||||
inactiveValue: "",
|
||||
inactiveTitleColor: environment.theme.list.itemSecondaryTextColor,
|
||||
activeTitle: "",
|
||||
activeValue: totalString,
|
||||
activeTitleColor: .white,
|
||||
badgeText: "\(remainsString)",
|
||||
badgePosition: position,
|
||||
badgeGraphPosition: position,
|
||||
invertProgress: true
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - sideInset * 2.0, height: 10000.0)
|
||||
)
|
||||
let remainingCountFrame = CGRect(origin: CGPoint(x: sideInset, y: contentHeight - 36.0), size: remainingCountSize)
|
||||
if let remainingCountView = self.remainingCount.view {
|
||||
if remainingCountView.superview == nil {
|
||||
self.scrollView.addSubview(remainingCountView)
|
||||
}
|
||||
transition.setFrame(view: remainingCountView, frame: remainingCountFrame)
|
||||
}
|
||||
contentHeight += remainingCountSize.height
|
||||
contentHeight -= 36.0
|
||||
contentHeight += sectionSpacing
|
||||
}
|
||||
|
||||
let giftConfiguration = GiftConfiguration.with(appConfiguration: component.context.currentAppConfiguration.with { $0 })
|
||||
|
||||
var introSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
@ -648,14 +690,7 @@ final class GiftSetupScreenComponent: Component {
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: environment.strings.Gift_Send_Customize_Title,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
maximumNumberOfLines: 0
|
||||
)),
|
||||
header: nil,
|
||||
footer: introFooter,
|
||||
items: introSectionItems
|
||||
)),
|
||||
|
@ -0,0 +1,827 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import Display
|
||||
import AsyncDisplayKit
|
||||
import TelegramCore
|
||||
import SwiftSignalKit
|
||||
import AccountContext
|
||||
import TelegramPresentationData
|
||||
import PresentationDataUtils
|
||||
import ComponentFlow
|
||||
import MultilineTextComponent
|
||||
import Markdown
|
||||
import TextFormat
|
||||
import RoundedRectWithTailPath
|
||||
|
||||
public class RemainingCountComponent: Component {
|
||||
private let inactiveColor: UIColor
|
||||
private let activeColors: [UIColor]
|
||||
private let inactiveTitle: String
|
||||
private let inactiveValue: String
|
||||
private let inactiveTitleColor: UIColor
|
||||
private let activeTitle: String
|
||||
private let activeValue: String
|
||||
private let activeTitleColor: UIColor
|
||||
private let badgeText: String?
|
||||
private let badgePosition: CGFloat
|
||||
private let badgeGraphPosition: CGFloat
|
||||
private let invertProgress: Bool
|
||||
|
||||
public init(
|
||||
inactiveColor: UIColor,
|
||||
activeColors: [UIColor],
|
||||
inactiveTitle: String,
|
||||
inactiveValue: String,
|
||||
inactiveTitleColor: UIColor,
|
||||
activeTitle: String,
|
||||
activeValue: String,
|
||||
activeTitleColor: UIColor,
|
||||
badgeText: String?,
|
||||
badgePosition: CGFloat,
|
||||
badgeGraphPosition: CGFloat,
|
||||
invertProgress: Bool = false
|
||||
) {
|
||||
self.inactiveColor = inactiveColor
|
||||
self.activeColors = activeColors
|
||||
self.inactiveTitle = inactiveTitle
|
||||
self.inactiveValue = inactiveValue
|
||||
self.inactiveTitleColor = inactiveTitleColor
|
||||
self.activeTitle = activeTitle
|
||||
self.activeValue = activeValue
|
||||
self.activeTitleColor = activeTitleColor
|
||||
self.badgeText = badgeText
|
||||
self.badgePosition = badgePosition
|
||||
self.badgeGraphPosition = badgeGraphPosition
|
||||
self.invertProgress = invertProgress
|
||||
}
|
||||
|
||||
public static func ==(lhs: RemainingCountComponent, rhs: RemainingCountComponent) -> Bool {
|
||||
if lhs.inactiveColor != rhs.inactiveColor {
|
||||
return false
|
||||
}
|
||||
if lhs.activeColors != rhs.activeColors {
|
||||
return false
|
||||
}
|
||||
if lhs.inactiveTitle != rhs.inactiveTitle {
|
||||
return false
|
||||
}
|
||||
if lhs.inactiveValue != rhs.inactiveValue {
|
||||
return false
|
||||
}
|
||||
if lhs.inactiveTitleColor != rhs.inactiveTitleColor {
|
||||
return false
|
||||
}
|
||||
if lhs.activeTitle != rhs.activeTitle {
|
||||
return false
|
||||
}
|
||||
if lhs.activeValue != rhs.activeValue {
|
||||
return false
|
||||
}
|
||||
if lhs.activeTitleColor != rhs.activeTitleColor {
|
||||
return false
|
||||
}
|
||||
if lhs.badgeText != rhs.badgeText {
|
||||
return false
|
||||
}
|
||||
if lhs.badgePosition != rhs.badgePosition {
|
||||
return false
|
||||
}
|
||||
if lhs.badgeGraphPosition != rhs.badgeGraphPosition {
|
||||
return false
|
||||
}
|
||||
if lhs.invertProgress != rhs.invertProgress {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
public final class View: UIView {
|
||||
private var component: RemainingCountComponent?
|
||||
|
||||
private let container: UIView
|
||||
private let inactiveBackground: SimpleLayer
|
||||
|
||||
private let inactiveTitleLabel = ComponentView<Empty>()
|
||||
private let inactiveValueLabel = ComponentView<Empty>()
|
||||
|
||||
private let innerLeftTitleLabel = ComponentView<Empty>()
|
||||
private let innerRightTitleLabel = ComponentView<Empty>()
|
||||
|
||||
private let activeContainer: UIView
|
||||
private let activeBackground: SimpleLayer
|
||||
|
||||
private let activeTitleLabel = ComponentView<Empty>()
|
||||
private let activeValueLabel = ComponentView<Empty>()
|
||||
|
||||
private let badgeView: UIView
|
||||
private let badgeMaskView: UIView
|
||||
private let badgeShapeLayer = CAShapeLayer()
|
||||
|
||||
private let badgeForeground: SimpleLayer
|
||||
private let badgeLabel: BadgeLabelView
|
||||
private let badgeLabelMaskView = UIImageView()
|
||||
|
||||
private var badgeTailPosition: CGFloat = 0.0
|
||||
private var badgeShapeArguments: (Double, Double, CGSize, CGFloat, CGFloat)?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.container = UIView()
|
||||
self.container.clipsToBounds = true
|
||||
self.container.layer.cornerRadius = 9.0
|
||||
|
||||
self.inactiveBackground = SimpleLayer()
|
||||
|
||||
self.activeContainer = UIView()
|
||||
self.activeContainer.clipsToBounds = true
|
||||
|
||||
self.activeBackground = SimpleLayer()
|
||||
self.activeBackground.anchorPoint = CGPoint()
|
||||
|
||||
self.badgeView = UIView()
|
||||
self.badgeView.alpha = 0.0
|
||||
|
||||
self.badgeShapeLayer.fillColor = UIColor.white.cgColor
|
||||
self.badgeShapeLayer.transform = CATransform3DMakeScale(1.0, -1.0, 1.0)
|
||||
|
||||
self.badgeMaskView = UIView()
|
||||
self.badgeMaskView.layer.addSublayer(self.badgeShapeLayer)
|
||||
self.badgeView.mask = self.badgeMaskView
|
||||
|
||||
self.badgeForeground = SimpleLayer()
|
||||
|
||||
self.badgeLabel = BadgeLabelView()
|
||||
let _ = self.badgeLabel.update(value: "0", transition: .immediate)
|
||||
self.badgeLabel.mask = self.badgeLabelMaskView
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.addSubview(self.container)
|
||||
self.container.layer.addSublayer(self.inactiveBackground)
|
||||
self.container.addSubview(self.activeContainer)
|
||||
self.activeContainer.layer.addSublayer(self.activeBackground)
|
||||
|
||||
self.addSubview(self.badgeView)
|
||||
self.badgeView.layer.addSublayer(self.badgeForeground)
|
||||
self.badgeView.addSubview(self.badgeLabel)
|
||||
|
||||
self.badgeLabelMaskView.contentMode = .scaleToFill
|
||||
self.badgeLabelMaskView.image = generateImage(CGSize(width: 2.0, height: 30.0), rotatedContext: { size, context in
|
||||
let bounds = CGRect(origin: .zero, size: size)
|
||||
context.clear(bounds)
|
||||
|
||||
let colorsArray: [CGColor] = [
|
||||
UIColor(rgb: 0xffffff, alpha: 0.0).cgColor,
|
||||
UIColor(rgb: 0xffffff).cgColor,
|
||||
UIColor(rgb: 0xffffff).cgColor,
|
||||
UIColor(rgb: 0xffffff, alpha: 0.0).cgColor,
|
||||
]
|
||||
var locations: [CGFloat] = [0.0, 0.24, 0.76, 1.0]
|
||||
let gradient = CGGradient(colorsSpace: deviceColorSpace, colors: colorsArray as CFArray, locations: &locations)!
|
||||
|
||||
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 0.0, y: size.height), options: CGGradientDrawingOptions())
|
||||
})
|
||||
|
||||
self.isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.badgeShapeAnimator?.invalidate()
|
||||
}
|
||||
|
||||
private var didPlayAppearanceAnimation = false
|
||||
func playAppearanceAnimation(component: RemainingCountComponent, badgeFullSize: CGSize, from: CGFloat? = nil) {
|
||||
if from == nil {
|
||||
self.badgeView.layer.animateScale(from: 0.1, to: 1.0, duration: 0.4, timingFunction: CAMediaTimingFunctionName.easeInEaseOut.rawValue)
|
||||
}
|
||||
|
||||
let rotationAngle: CGFloat
|
||||
if badgeFullSize.width > 100.0 {
|
||||
rotationAngle = 0.2
|
||||
} else {
|
||||
rotationAngle = 0.26
|
||||
}
|
||||
|
||||
let to: CGFloat = self.badgeView.center.x
|
||||
|
||||
let positionAnimation = CABasicAnimation(keyPath: "position.x")
|
||||
positionAnimation.fromValue = NSValue(cgPoint: CGPoint(x: from ?? self.container.frame.width, y: 0.0))
|
||||
positionAnimation.toValue = NSValue(cgPoint: CGPoint(x: to, y: 0.0))
|
||||
positionAnimation.duration = 0.5
|
||||
positionAnimation.fillMode = .forwards
|
||||
positionAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
||||
self.badgeView.layer.add(positionAnimation, forKey: "appearance1")
|
||||
|
||||
if from != to {
|
||||
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
|
||||
rotateAnimation.fromValue = 0.0 as NSNumber
|
||||
rotateAnimation.toValue = rotationAngle as NSNumber
|
||||
rotateAnimation.duration = 0.15
|
||||
rotateAnimation.fillMode = .forwards
|
||||
rotateAnimation.timingFunction = CAMediaTimingFunction(name: .easeOut)
|
||||
rotateAnimation.isRemovedOnCompletion = false
|
||||
self.badgeView.layer.add(rotateAnimation, forKey: "appearance2")
|
||||
|
||||
Queue.mainQueue().after(0.5, {
|
||||
let bounceAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
|
||||
bounceAnimation.fromValue = rotationAngle as NSNumber
|
||||
bounceAnimation.toValue = -0.04 as NSNumber
|
||||
bounceAnimation.duration = 0.2
|
||||
bounceAnimation.fillMode = .forwards
|
||||
bounceAnimation.timingFunction = CAMediaTimingFunction(name: .easeOut)
|
||||
bounceAnimation.isRemovedOnCompletion = false
|
||||
self.badgeView.layer.add(bounceAnimation, forKey: "appearance3")
|
||||
self.badgeView.layer.removeAnimation(forKey: "appearance2")
|
||||
|
||||
Queue.mainQueue().after(0.2) {
|
||||
let returnAnimation = CABasicAnimation(keyPath: "transform.rotation.z")
|
||||
returnAnimation.fromValue = -0.04 as NSNumber
|
||||
returnAnimation.toValue = 0.0 as NSNumber
|
||||
returnAnimation.duration = 0.15
|
||||
returnAnimation.fillMode = .forwards
|
||||
returnAnimation.timingFunction = CAMediaTimingFunction(name: .easeIn)
|
||||
self.badgeView.layer.add(returnAnimation, forKey: "appearance4")
|
||||
self.badgeView.layer.removeAnimation(forKey: "appearance3")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if from == nil {
|
||||
self.badgeView.alpha = 1.0
|
||||
self.badgeView.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.1)
|
||||
}
|
||||
|
||||
if let badgeText = component.badgeText {
|
||||
let transition: ComponentTransition = .easeInOut(duration: from != nil ? 0.3 : 0.5)
|
||||
var frameTransition = transition
|
||||
if from == nil {
|
||||
frameTransition = frameTransition.withAnimation(.none)
|
||||
}
|
||||
let badgeLabelSize = self.badgeLabel.update(value: badgeText, transition: transition)
|
||||
frameTransition.setFrame(view: self.badgeLabel, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((badgeFullSize.width - badgeLabelSize.width) / 2.0), y: -2.0), size: badgeLabelSize))
|
||||
}
|
||||
}
|
||||
|
||||
var previousAvailableSize: CGSize?
|
||||
func update(component: RemainingCountComponent, availableSize: CGSize, transition: ComponentTransition) -> CGSize {
|
||||
self.component = component
|
||||
self.inactiveBackground.backgroundColor = component.inactiveColor.cgColor
|
||||
self.activeBackground.backgroundColor = component.activeColors.last?.cgColor
|
||||
|
||||
let size = CGSize(width: availableSize.width, height: 90.0)
|
||||
|
||||
self.badgeLabel.color = component.activeTitleColor
|
||||
|
||||
let lineHeight: CGFloat = 30.0
|
||||
let containerFrame = CGRect(origin: CGPoint(x: 0.0, y: size.height - lineHeight), size: CGSize(width: size.width, height: lineHeight))
|
||||
self.container.frame = containerFrame
|
||||
|
||||
let activityPosition: CGFloat = floor(containerFrame.width * component.badgeGraphPosition)
|
||||
let activeWidth: CGFloat = containerFrame.width - activityPosition
|
||||
|
||||
let leftTextColor: UIColor
|
||||
let rightTextColor: UIColor
|
||||
if component.invertProgress {
|
||||
leftTextColor = component.inactiveTitleColor
|
||||
rightTextColor = component.inactiveTitleColor
|
||||
} else {
|
||||
leftTextColor = component.inactiveTitleColor
|
||||
rightTextColor = component.activeTitleColor
|
||||
}
|
||||
|
||||
if "".isEmpty {
|
||||
if component.invertProgress {
|
||||
let innerLeftTitleSize = self.innerLeftTitleLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(
|
||||
NSAttributedString(
|
||||
string: component.inactiveTitle,
|
||||
font: Font.semibold(15.0),
|
||||
textColor: component.activeTitleColor
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
if let view = self.innerLeftTitleLabel.view {
|
||||
if view.superview == nil {
|
||||
self.activeContainer.addSubview(view)
|
||||
}
|
||||
view.frame = CGRect(origin: CGPoint(x: 12.0, y: floorToScreenPixels((lineHeight - innerLeftTitleSize.height) / 2.0)), size: innerLeftTitleSize)
|
||||
}
|
||||
|
||||
let innerRightTitleSize = self.innerRightTitleLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(
|
||||
NSAttributedString(
|
||||
string: component.activeValue,
|
||||
font: Font.semibold(15.0),
|
||||
textColor: component.activeTitleColor
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
if let view = self.innerRightTitleLabel.view {
|
||||
if view.superview == nil {
|
||||
self.activeContainer.addSubview(view)
|
||||
}
|
||||
view.frame = CGRect(origin: CGPoint(x: containerFrame.width - 12.0 - innerRightTitleSize.width, y: floorToScreenPixels((lineHeight - innerRightTitleSize.height) / 2.0)), size: innerRightTitleSize)
|
||||
}
|
||||
}
|
||||
|
||||
let inactiveTitleSize = self.inactiveTitleLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(
|
||||
NSAttributedString(
|
||||
string: component.inactiveTitle,
|
||||
font: Font.semibold(15.0),
|
||||
textColor: leftTextColor
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
if let view = self.inactiveTitleLabel.view {
|
||||
if view.superview == nil {
|
||||
self.container.addSubview(view)
|
||||
}
|
||||
view.frame = CGRect(origin: CGPoint(x: 12.0, y: floorToScreenPixels((lineHeight - inactiveTitleSize.height) / 2.0)), size: inactiveTitleSize)
|
||||
}
|
||||
|
||||
let inactiveValueSize = self.inactiveValueLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(
|
||||
NSAttributedString(
|
||||
string: component.inactiveValue,
|
||||
font: Font.semibold(15.0),
|
||||
textColor: leftTextColor
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
if let view = self.inactiveValueLabel.view {
|
||||
if view.superview == nil {
|
||||
self.container.addSubview(view)
|
||||
}
|
||||
view.frame = CGRect(origin: CGPoint(x: activityPosition - 12.0 - inactiveValueSize.width, y: floorToScreenPixels((lineHeight - inactiveValueSize.height) / 2.0)), size: inactiveValueSize)
|
||||
}
|
||||
|
||||
let activeTitleSize = self.activeTitleLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(
|
||||
NSAttributedString(
|
||||
string: component.activeTitle,
|
||||
font: Font.semibold(15.0),
|
||||
textColor: rightTextColor
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
if let view = self.activeTitleLabel.view {
|
||||
if view.superview == nil {
|
||||
self.container.addSubview(view)
|
||||
}
|
||||
view.frame = CGRect(origin: CGPoint(x: activityPosition + 12.0, y: floorToScreenPixels((lineHeight - activeTitleSize.height) / 2.0)), size: activeTitleSize)
|
||||
}
|
||||
|
||||
let activeValueSize = self.activeValueLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
MultilineTextComponent(
|
||||
text: .plain(
|
||||
NSAttributedString(
|
||||
string: component.activeValue,
|
||||
font: Font.semibold(15.0),
|
||||
textColor: rightTextColor
|
||||
)
|
||||
)
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
if let view = self.activeValueLabel.view {
|
||||
if view.superview == nil {
|
||||
self.container.addSubview(view)
|
||||
|
||||
if component.invertProgress {
|
||||
self.container.bringSubviewToFront(self.activeContainer)
|
||||
}
|
||||
}
|
||||
view.frame = CGRect(origin: CGPoint(x: containerFrame.width - 12.0 - activeValueSize.width, y: floorToScreenPixels((lineHeight - activeValueSize.height) / 2.0)), size: activeValueSize)
|
||||
}
|
||||
}
|
||||
|
||||
var progressTransition: ComponentTransition = .immediate
|
||||
if !transition.animation.isImmediate {
|
||||
progressTransition = .easeInOut(duration: 0.5)
|
||||
}
|
||||
if "".isEmpty {
|
||||
if component.invertProgress {
|
||||
progressTransition.setFrame(layer: self.inactiveBackground, frame: CGRect(origin: CGPoint(x: activityPosition, y: 0.0), size: CGSize(width: size.width - activityPosition, height: lineHeight)))
|
||||
progressTransition.setFrame(view: self.activeContainer, frame: CGRect(origin: .zero, size: CGSize(width: activityPosition, height: lineHeight)))
|
||||
progressTransition.setBounds(layer: self.activeBackground, bounds: CGRect(origin: .zero, size: CGSize(width: containerFrame.width * 1.35, height: lineHeight)))
|
||||
} else {
|
||||
progressTransition.setFrame(layer: self.inactiveBackground, frame: CGRect(origin: .zero, size: CGSize(width: activityPosition, height: lineHeight)))
|
||||
progressTransition.setFrame(view: self.activeContainer, frame: CGRect(origin: CGPoint(x: activityPosition, y: 0.0), size: CGSize(width: activeWidth, height: lineHeight)))
|
||||
progressTransition.setFrame(layer: self.activeBackground, frame: CGRect(origin: CGPoint(x: -activityPosition, y: 0.0), size: CGSize(width: containerFrame.width * 1.35, height: lineHeight)))
|
||||
}
|
||||
if self.activeBackground.animation(forKey: "movement") == nil {
|
||||
self.activeBackground.position = CGPoint(x: -self.activeContainer.frame.width * 0.35, y: lineHeight / 2.0)
|
||||
}
|
||||
}
|
||||
|
||||
let countWidth: CGFloat
|
||||
if let badgeText = component.badgeText {
|
||||
countWidth = CGFloat(badgeText.count) * 10.0
|
||||
} else {
|
||||
countWidth = 51.0
|
||||
}
|
||||
let badgeWidth: CGFloat = countWidth + 20.0
|
||||
|
||||
let badgeSize = CGSize(width: badgeWidth, height: 30.0)
|
||||
let badgeFullSize = CGSize(width: badgeWidth, height: 30.0 + 8.0)
|
||||
let tailSize = CGSize(width: 15.0, height: 6.0)
|
||||
let tailRadius: CGFloat = 3.0
|
||||
self.badgeMaskView.frame = CGRect(origin: .zero, size: badgeFullSize)
|
||||
self.badgeShapeLayer.frame = CGRect(origin: CGPoint(x: 0.0, y: -4.0), size: badgeFullSize)
|
||||
|
||||
self.badgeView.bounds = CGRect(origin: .zero, size: badgeFullSize)
|
||||
|
||||
let currentBadgeX = self.badgeView.center.x
|
||||
|
||||
let badgePosition = component.badgePosition
|
||||
|
||||
if badgePosition > 1.0 - 0.15 {
|
||||
progressTransition.setAnchorPoint(layer: self.badgeView.layer, anchorPoint: CGPoint(x: 1.0, y: 1.0))
|
||||
|
||||
if progressTransition.animation.isImmediate {
|
||||
self.badgeShapeLayer.path = generateRoundedRectWithTailPath(rectSize: badgeSize, tailSize: tailSize, tailRadius: tailRadius, tailPosition: 1.0).cgPath
|
||||
} else {
|
||||
self.badgeShapeArguments = (CACurrentMediaTime(), 0.5, badgeSize, self.badgeTailPosition, 1.0)
|
||||
self.animateBadgeTailPositionChange()
|
||||
}
|
||||
self.badgeTailPosition = 1.0
|
||||
|
||||
if let _ = self.badgeView.layer.animation(forKey: "appearance1") {
|
||||
} else {
|
||||
self.badgeView.center = CGPoint(x: 3.0 + (size.width - 6.0) * badgePosition + 3.0, y: 56.0)
|
||||
}
|
||||
} else if badgePosition < 0.15 {
|
||||
progressTransition.setAnchorPoint(layer: self.badgeView.layer, anchorPoint: CGPoint(x: 0.0, y: 1.0))
|
||||
|
||||
if progressTransition.animation.isImmediate {
|
||||
self.badgeShapeLayer.path = generateRoundedRectWithTailPath(rectSize: badgeSize, tailSize: tailSize, tailRadius: tailRadius, tailPosition: 0.0).cgPath
|
||||
} else {
|
||||
self.badgeShapeArguments = (CACurrentMediaTime(), 0.5, badgeSize, self.badgeTailPosition, 0.0)
|
||||
self.animateBadgeTailPositionChange()
|
||||
}
|
||||
self.badgeTailPosition = 0.0
|
||||
|
||||
if let _ = self.badgeView.layer.animation(forKey: "appearance1") {
|
||||
|
||||
} else {
|
||||
self.badgeView.center = CGPoint(x: (size.width - 6.0) * badgePosition, y: 56.0)
|
||||
}
|
||||
} else {
|
||||
progressTransition.setAnchorPoint(layer: self.badgeView.layer, anchorPoint: CGPoint(x: 0.5, y: 1.0))
|
||||
|
||||
if progressTransition.animation.isImmediate {
|
||||
self.badgeShapeLayer.path = generateRoundedRectWithTailPath(rectSize: badgeSize, tailSize: tailSize, tailRadius: tailRadius, tailPosition: 0.5).cgPath
|
||||
} else {
|
||||
self.badgeShapeArguments = (CACurrentMediaTime(), 0.5, badgeSize, self.badgeTailPosition, 0.5)
|
||||
self.animateBadgeTailPositionChange()
|
||||
}
|
||||
self.badgeTailPosition = 0.5
|
||||
|
||||
if let _ = self.badgeView.layer.animation(forKey: "appearance1") {
|
||||
|
||||
} else {
|
||||
self.badgeView.center = CGPoint(x: size.width * badgePosition, y: 56.0)
|
||||
}
|
||||
}
|
||||
self.badgeForeground.bounds = CGRect(origin: CGPoint(), size: CGSize(width: badgeFullSize.width * 3.0, height: badgeFullSize.height))
|
||||
if self.badgeForeground.animation(forKey: "movement") == nil {
|
||||
self.badgeForeground.position = CGPoint(x: badgeSize.width * 3.0 / 2.0 - self.badgeForeground.frame.width * 0.35, y: badgeFullSize.height / 2.0)
|
||||
}
|
||||
|
||||
self.badgeLabelMaskView.frame = CGRect(x: 0.0, y: 0.0, width: 100.0, height: 36.0)
|
||||
|
||||
if !self.didPlayAppearanceAnimation || !transition.animation.isImmediate {
|
||||
self.didPlayAppearanceAnimation = true
|
||||
if transition.animation.isImmediate {
|
||||
if component.badgePosition < 0.1 {
|
||||
self.badgeView.alpha = 1.0
|
||||
if let badgeText = component.badgeText {
|
||||
let badgeLabelSize = self.badgeLabel.update(value: badgeText, transition: .immediate)
|
||||
transition.setFrame(view: self.badgeLabel, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((badgeFullSize.width - badgeLabelSize.width) / 2.0), y: -2.0), size: badgeLabelSize))
|
||||
}
|
||||
} else {
|
||||
self.playAppearanceAnimation(component: component, badgeFullSize: badgeFullSize)
|
||||
}
|
||||
} else {
|
||||
self.playAppearanceAnimation(component: component, badgeFullSize: badgeFullSize, from: currentBadgeX)
|
||||
}
|
||||
}
|
||||
|
||||
if self.previousAvailableSize != availableSize {
|
||||
self.previousAvailableSize = availableSize
|
||||
|
||||
var locations: [CGFloat] = []
|
||||
let delta = 1.0 / CGFloat(component.activeColors.count - 1)
|
||||
for i in 0 ..< component.activeColors.count {
|
||||
locations.append(delta * CGFloat(i))
|
||||
}
|
||||
|
||||
let gradient = generateGradientImage(size: CGSize(width: 200.0, height: 60.0), colors: component.activeColors, locations: locations, direction: .horizontal)
|
||||
self.badgeForeground.contentsGravity = .resizeAspectFill
|
||||
self.badgeForeground.contents = gradient?.cgImage
|
||||
|
||||
self.activeBackground.contentsGravity = .resizeAspectFill
|
||||
self.activeBackground.contents = gradient?.cgImage
|
||||
|
||||
self.setupGradientAnimations()
|
||||
}
|
||||
|
||||
return size
|
||||
}
|
||||
|
||||
private var badgeShapeAnimator: ConstantDisplayLinkAnimator?
|
||||
private func animateBadgeTailPositionChange() {
|
||||
if self.badgeShapeAnimator == nil {
|
||||
self.badgeShapeAnimator = ConstantDisplayLinkAnimator(update: { [weak self] in
|
||||
self?.animateBadgeTailPositionChange()
|
||||
})
|
||||
self.badgeShapeAnimator?.isPaused = true
|
||||
}
|
||||
|
||||
if let (startTime, duration, badgeSize, initial, target) = self.badgeShapeArguments {
|
||||
self.badgeShapeAnimator?.isPaused = false
|
||||
|
||||
let t = CGFloat(max(0.0, min(1.0, (CACurrentMediaTime() - startTime) / duration)))
|
||||
let value = initial + (target - initial) * t
|
||||
|
||||
let tailSize = CGSize(width: 15.0, height: 6.0)
|
||||
let tailRadius: CGFloat = 3.0
|
||||
self.badgeShapeLayer.path = generateRoundedRectWithTailPath(rectSize: badgeSize, tailSize: tailSize, tailRadius: tailRadius, tailPosition: value).cgPath
|
||||
|
||||
if t >= 1.0 {
|
||||
self.badgeShapeArguments = nil
|
||||
self.badgeShapeAnimator?.isPaused = true
|
||||
self.badgeShapeAnimator?.invalidate()
|
||||
self.badgeShapeAnimator = nil
|
||||
}
|
||||
} else {
|
||||
self.badgeShapeAnimator?.isPaused = true
|
||||
self.badgeShapeAnimator?.invalidate()
|
||||
self.badgeShapeAnimator = nil
|
||||
}
|
||||
}
|
||||
|
||||
private func setupGradientAnimations() {
|
||||
guard let _ = self.component else {
|
||||
return
|
||||
}
|
||||
if let _ = self.badgeForeground.animation(forKey: "movement") {
|
||||
} else {
|
||||
CATransaction.begin()
|
||||
|
||||
let badgeOffset = (self.badgeForeground.frame.width - self.badgeView.bounds.width) / 2.0
|
||||
let badgePreviousValue = self.badgeForeground.position.x
|
||||
var badgeNewValue: CGFloat = badgeOffset
|
||||
if badgeOffset - badgePreviousValue < self.badgeForeground.frame.width * 0.25 {
|
||||
badgeNewValue -= self.badgeForeground.frame.width * 0.35
|
||||
}
|
||||
self.badgeForeground.position = CGPoint(x: badgeNewValue, y: self.badgeForeground.bounds.size.height / 2.0)
|
||||
|
||||
let lineOffset = 0.0
|
||||
let linePreviousValue = self.activeBackground.position.x
|
||||
var lineNewValue: CGFloat = lineOffset
|
||||
if linePreviousValue < 0.0 {
|
||||
lineNewValue = 0.0
|
||||
} else {
|
||||
lineNewValue = -self.activeContainer.bounds.width * 0.35
|
||||
}
|
||||
lineNewValue -= self.activeContainer.frame.minX
|
||||
self.activeBackground.position = CGPoint(x: lineNewValue, y: 0.0)
|
||||
|
||||
let badgeAnimation = CABasicAnimation(keyPath: "position.x")
|
||||
badgeAnimation.duration = 4.5
|
||||
badgeAnimation.fromValue = badgePreviousValue
|
||||
badgeAnimation.toValue = badgeNewValue
|
||||
badgeAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
||||
|
||||
CATransaction.setCompletionBlock { [weak self] in
|
||||
self?.setupGradientAnimations()
|
||||
}
|
||||
self.badgeForeground.add(badgeAnimation, forKey: "movement")
|
||||
|
||||
let lineAnimation = CABasicAnimation(keyPath: "position.x")
|
||||
lineAnimation.duration = 4.5
|
||||
lineAnimation.fromValue = linePreviousValue
|
||||
lineAnimation.toValue = lineNewValue
|
||||
lineAnimation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
|
||||
self.activeBackground.add(lineAnimation, forKey: "movement")
|
||||
|
||||
CATransaction.commit()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<Empty>, transition: ComponentTransition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private let labelWidth: CGFloat = 10.0
|
||||
private let labelHeight: CGFloat = 30.0
|
||||
private let labelSize = CGSize(width: labelWidth, height: labelHeight)
|
||||
private let font = Font.with(size: 15.0, design: .regular, weight: .semibold, traits: [])
|
||||
|
||||
final class BadgeLabelView: UIView {
|
||||
private class StackView: UIView {
|
||||
var labels: [UILabel] = []
|
||||
|
||||
var currentValue: Int32 = 0
|
||||
|
||||
var color: UIColor = .white {
|
||||
didSet {
|
||||
for view in self.labels {
|
||||
view.textColor = self.color
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
super.init(frame: CGRect(origin: .zero, size: labelSize))
|
||||
|
||||
var height: CGFloat = -labelHeight
|
||||
for i in -1 ..< 10 {
|
||||
let label = UILabel()
|
||||
if i == -1 {
|
||||
label.text = "9"
|
||||
} else {
|
||||
label.text = "\(i)"
|
||||
}
|
||||
label.textColor = self.color
|
||||
label.font = font
|
||||
label.textAlignment = .center
|
||||
label.frame = CGRect(x: 0, y: height, width: labelWidth, height: labelHeight)
|
||||
self.addSubview(label)
|
||||
self.labels.append(label)
|
||||
|
||||
height += labelHeight
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
func update(value: Int32, isFirst: Bool, isLast: Bool, transition: ComponentTransition) {
|
||||
let previousValue = self.currentValue
|
||||
self.currentValue = value
|
||||
|
||||
self.labels[1].alpha = isFirst && !isLast ? 0.0 : 1.0
|
||||
|
||||
if previousValue == 9 && value < 9 {
|
||||
self.bounds = CGRect(
|
||||
origin: CGPoint(
|
||||
x: 0.0,
|
||||
y: -1.0 * labelSize.height
|
||||
),
|
||||
size: labelSize
|
||||
)
|
||||
}
|
||||
|
||||
let bounds = CGRect(
|
||||
origin: CGPoint(
|
||||
x: 0.0,
|
||||
y: CGFloat(value) * labelSize.height
|
||||
),
|
||||
size: labelSize
|
||||
)
|
||||
transition.setBounds(view: self, bounds: bounds)
|
||||
}
|
||||
}
|
||||
|
||||
private var itemViews: [Int: StackView] = [:]
|
||||
private var staticLabel = UILabel()
|
||||
|
||||
init() {
|
||||
super.init(frame: .zero)
|
||||
|
||||
self.clipsToBounds = true
|
||||
self.isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
var color: UIColor = .white {
|
||||
didSet {
|
||||
self.staticLabel.textColor = self.color
|
||||
for (_, view) in self.itemViews {
|
||||
view.color = self.color
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func update(value: String, transition: ComponentTransition) -> CGSize {
|
||||
if value.contains(" ") {
|
||||
for (_, view) in self.itemViews {
|
||||
view.isHidden = true
|
||||
}
|
||||
|
||||
if self.staticLabel.superview == nil {
|
||||
self.staticLabel.textColor = self.color
|
||||
self.staticLabel.font = font
|
||||
|
||||
self.addSubview(self.staticLabel)
|
||||
}
|
||||
|
||||
self.staticLabel.text = value
|
||||
let size = self.staticLabel.sizeThatFits(CGSize(width: 100.0, height: 100.0))
|
||||
self.staticLabel.frame = CGRect(origin: .zero, size: CGSize(width: size.width, height: labelHeight))
|
||||
|
||||
return CGSize(width: ceil(self.staticLabel.bounds.width), height: ceil(self.staticLabel.bounds.height))
|
||||
}
|
||||
|
||||
let string = value
|
||||
let stringArray = Array(string.map { String($0) }.reversed())
|
||||
|
||||
let totalWidth = CGFloat(stringArray.count) * labelWidth
|
||||
|
||||
var validIds: [Int] = []
|
||||
for i in 0 ..< stringArray.count {
|
||||
validIds.append(i)
|
||||
|
||||
let itemView: StackView
|
||||
var itemTransition = transition
|
||||
if let current = self.itemViews[i] {
|
||||
itemView = current
|
||||
} else {
|
||||
itemTransition = transition.withAnimation(.none)
|
||||
itemView = StackView()
|
||||
itemView.color = self.color
|
||||
self.itemViews[i] = itemView
|
||||
self.addSubview(itemView)
|
||||
}
|
||||
|
||||
let digit = Int32(stringArray[i]) ?? 0
|
||||
itemView.update(value: digit, isFirst: i == stringArray.count - 1, isLast: i == 0, transition: transition)
|
||||
|
||||
itemTransition.setFrame(
|
||||
view: itemView,
|
||||
frame: CGRect(x: totalWidth - labelWidth * CGFloat(i + 1), y: 0.0, width: labelWidth, height: labelHeight)
|
||||
)
|
||||
}
|
||||
|
||||
var removeIds: [Int] = []
|
||||
for (id, itemView) in self.itemViews {
|
||||
if !validIds.contains(id) {
|
||||
removeIds.append(id)
|
||||
|
||||
transition.setAlpha(view: itemView, alpha: 0.0, completion: { _ in
|
||||
itemView.removeFromSuperview()
|
||||
})
|
||||
}
|
||||
}
|
||||
for id in removeIds {
|
||||
self.itemViews.removeValue(forKey: id)
|
||||
}
|
||||
return CGSize(width: totalWidth, height: labelHeight)
|
||||
}
|
||||
}
|
@ -1382,7 +1382,8 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
url: "",
|
||||
simple: true,
|
||||
source: .generic,
|
||||
skipTermsOfService: true
|
||||
skipTermsOfService: true,
|
||||
payload: nil
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -945,8 +945,8 @@ final class AuthorizedApplicationContext {
|
||||
chatLocation = .peer(peer)
|
||||
}
|
||||
|
||||
if openAppIfAny, let parentController = self.rootController.viewControllers.last as? ViewController {
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: parentController, updatedPresentationData: nil, peer: peer, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: true)
|
||||
if openAppIfAny, case let .user(user) = peer, let botInfo = user.botInfo, botInfo.flags.contains(.hasWebApp), let parentController = self.rootController.viewControllers.last as? ViewController {
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: parentController, updatedPresentationData: nil, peer: peer, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: true, payload: nil)
|
||||
} else {
|
||||
self.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: self.rootController, context: self.context, chatLocation: chatLocation, subject: isOutgoingMessage ? messageId.flatMap { .message(id: .id($0), highlight: ChatControllerSubject.MessageHighlight(quote: nil), timecode: nil, setupReply: false) } : nil, activateInput: activateInput ? .text : nil))
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ import UndoUI
|
||||
import UrlHandling
|
||||
import TelegramPresentationData
|
||||
|
||||
func openWebAppImpl(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: EnginePeer, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool) {
|
||||
func openWebAppImpl(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: EnginePeer, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?) {
|
||||
let presentationData: PresentationData
|
||||
if let parentController = parentController as? ChatControllerImpl {
|
||||
presentationData = parentController.presentationData
|
||||
@ -195,7 +195,7 @@ func openWebAppImpl(context: AccountContext, parentController: ViewController, u
|
||||
} else {
|
||||
source = url.isEmpty ? .generic : .simple
|
||||
}
|
||||
let params = WebAppParameters(source: source, peerId: peer.id, botId: botId, botName: botName, botVerified: botVerified, url: result.url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, forceHasSettings: false, fullSize: result.flags.contains(.fullSize))
|
||||
let params = WebAppParameters(source: source, peerId: peer.id, botId: botId, botName: botName, botVerified: botVerified, url: result.url, queryId: nil, payload: payload, buttonText: buttonText, keepAliveSignal: nil, forceHasSettings: false, fullSize: result.flags.contains(.fullSize))
|
||||
let controller = standaloneWebAppController(context: context, updatedPresentationData: updatedPresentationData, params: params, threadId: threadId, openUrl: { [weak parentController] url, concealed, commit in
|
||||
ChatControllerImpl.botOpenUrl(context: context, peerId: peer.id, controller: parentController as? ChatControllerImpl, url: url, concealed: concealed, present: { c, a in
|
||||
presentImpl?(c, a)
|
||||
@ -310,7 +310,7 @@ public extension ChatControllerImpl {
|
||||
}
|
||||
self.chatDisplayNode.dismissInput()
|
||||
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, peer: EnginePeer(peer), threadId: self.chatLocation.threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: false)
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, peer: EnginePeer(peer), threadId: self.chatLocation.threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: false, payload: nil)
|
||||
}
|
||||
|
||||
static func botRequestSwitchInline(context: AccountContext, controller: ChatControllerImpl?, peerId: EnginePeer.Id, botAddress: String, query: String, chatTypes: [ReplyMarkupButtonRequestPeerType]?, completion: @escaping () -> Void) -> Void {
|
||||
@ -561,7 +561,7 @@ public extension ChatControllerImpl {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, peer: botPeer, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false)
|
||||
self.context.sharedContext.openWebApp(context: self.context, parentController: self, updatedPresentationData: self.updatedPresentationData, peer: botPeer, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false, payload: payload)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9721,7 +9721,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
commit()
|
||||
})
|
||||
} else {
|
||||
strongSelf.context.sharedContext.openWebApp(context: strongSelf.context, parentController: strongSelf, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false)
|
||||
strongSelf.context.sharedContext.openWebApp(context: strongSelf.context, parentController: strongSelf, updatedPresentationData: strongSelf.updatedPresentationData, peer: peer, threadId: nil, buttonText: "", url: "", simple: true, source: .generic, skipTermsOfService: false, payload: botAppStart.payload)
|
||||
commit()
|
||||
}
|
||||
}
|
||||
|
@ -2827,8 +2827,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
return MiniAppListScreen(context: context, initialData: initialData as! MiniAppListScreen.InitialData)
|
||||
}
|
||||
|
||||
public func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: EnginePeer, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool) {
|
||||
openWebAppImpl(context: context, parentController: parentController, updatedPresentationData: updatedPresentationData, peer: peer, threadId: threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: skipTermsOfService)
|
||||
public func openWebApp(context: AccountContext, parentController: ViewController, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?, peer: EnginePeer, threadId: Int64?, buttonText: String, url: String, simple: Bool, source: ChatOpenWebViewSource, skipTermsOfService: Bool, payload: String?) {
|
||||
openWebAppImpl(context: context, parentController: parentController, updatedPresentationData: updatedPresentationData, peer: peer, threadId: threadId, buttonText: buttonText, url: url, simple: simple, source: source, skipTermsOfService: skipTermsOfService, payload: payload)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user