Various fixes

This commit is contained in:
Ilya Laktyushin 2022-07-25 04:09:33 +03:00
parent 5986a4d3b1
commit 73a8431095
9 changed files with 120 additions and 89 deletions

Binary file not shown.

Binary file not shown.

View File

@ -2476,16 +2476,16 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
c.setItems(strongSelf.contextMenuSpeedItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil) c.setItems(strongSelf.contextMenuSpeedItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil)
}))) })))
if #available(iOS 11.0, *) { // if #available(iOS 11.0, *) {
items.append(.action(ContextMenuActionItem(text: "AirPlay", textColor: .primary, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/AirPlay"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in // items.append(.action(ContextMenuActionItem(text: "AirPlay", textColor: .primary, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Media Gallery/AirPlay"), color: theme.contextMenu.primaryColor) }, action: { [weak self] _, f in
f(.default) // f(.default)
guard let strongSelf = self else { // guard let strongSelf = self else {
return // return
} // }
strongSelf.beginAirPlaySetup() // strongSelf.beginAirPlaySetup()
}))) // })))
} // }
if let (message, _, _) = strongSelf.contentInfo() { if let (message, _, _) = strongSelf.contentInfo() {
for media in message.media { for media in message.media {

View File

@ -145,7 +145,7 @@ private final class ProductGroupComponent: Component {
buttonView?.backgroundColor = component.selectionColor buttonView?.backgroundColor = component.selectionColor
} else { } else {
UIView.animate(withDuration: 0.3, animations: { UIView.animate(withDuration: 0.3, animations: {
buttonView?.backgroundColor = nil buttonView?.backgroundColor = component.backgroundColor
}) })
} }
} }
@ -299,31 +299,44 @@ private final class GiftComponent: CombinedComponent {
transition: context.transition transition: context.transition
) )
let discount = discount.update( let discountSize: CGSize
component: MultilineTextComponent( if !component.discount.isEmpty {
text: .plain( let discount = discount.update(
NSAttributedString( component: MultilineTextComponent(
string: component.discount, text: .plain(
font: Font.with(size: 14.0, design: .round, weight: .semibold, traits: []), NSAttributedString(
textColor: .white string: component.discount,
) font: Font.with(size: 14.0, design: .round, weight: .semibold, traits: []),
textColor: .white
)
),
maximumNumberOfLines: 1
), ),
maximumNumberOfLines: 1 availableSize: context.availableSize,
), transition: context.transition
availableSize: context.availableSize, )
transition: context.transition
) discountSize = CGSize(width: discount.size.width + 6.0, height: 18.0)
let discountSize = CGSize(width: discount.size.width + 6.0, height: 18.0) let discountBackground = discountBackground.update(
component: RoundedRectangle(
let discountBackground = discountBackground.update( color: component.accentColor,
component: RoundedRectangle( cornerRadius: 5.0
color: component.accentColor, ),
cornerRadius: 5.0 availableSize: discountSize,
), transition: context.transition
availableSize: discountSize, )
transition: context.transition
) context.add(discountBackground
.position(CGPoint(x: insets.left + discountSize.width / 2.0, y: insets.top + title.size.height + spacing + discountSize.height / 2.0))
)
context.add(discount
.position(CGPoint(x: insets.left + discountSize.width / 2.0, y: insets.top + title.size.height + spacing + discountSize.height / 2.0))
)
} else {
discountSize = CGSize(width: 0.0, height: 18.0)
}
let subtitle = subtitle.update( let subtitle = subtitle.update(
component: MultilineTextComponent( component: MultilineTextComponent(
@ -359,17 +372,9 @@ private final class GiftComponent: CombinedComponent {
context.add(title context.add(title
.position(CGPoint(x: insets.left + title.size.width / 2.0, y: insets.top + title.size.height / 2.0)) .position(CGPoint(x: insets.left + title.size.width / 2.0, y: insets.top + title.size.height / 2.0))
) )
context.add(discountBackground
.position(CGPoint(x: insets.left + discountSize.width / 2.0, y: insets.top + title.size.height + spacing + discountSize.height / 2.0))
)
context.add(discount
.position(CGPoint(x: insets.left + discountSize.width / 2.0, y: insets.top + title.size.height + spacing + discountSize.height / 2.0))
)
context.add(subtitle context.add(subtitle
.position(CGPoint(x: insets.left + discountSize.width + 7.0 + subtitle.size.width / 2.0, y: insets.top + title.size.height + spacing + discountSize.height / 2.0)) .position(CGPoint(x: insets.left + (discountSize.width.isZero ? 0.0 : discountSize.width + 7.0) + subtitle.size.width / 2.0, y: insets.top + title.size.height + spacing + discountSize.height / 2.0))
) )
let size = CGSize(width: context.availableSize.width, height: insets.top + title.size.height + spacing + subtitle.size.height + insets.bottom) let size = CGSize(width: context.availableSize.width, height: insets.top + title.size.height + spacing + subtitle.size.height + insets.bottom)
@ -510,13 +515,13 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
let context: AccountContext let context: AccountContext
let peer: EnginePeer? let peer: EnginePeer?
let products: [InAppPurchaseManager.Product]? let products: [PremiumGiftProduct]?
let selectedProductId: String? let selectedProductId: String?
let present: (ViewController) -> Void let present: (ViewController) -> Void
let selectProduct: (String) -> Void let selectProduct: (String) -> Void
init(context: AccountContext, peer: EnginePeer?, products: [InAppPurchaseManager.Product]?, selectedProductId: String?, present: @escaping (ViewController) -> Void, selectProduct: @escaping (String) -> Void) { init(context: AccountContext, peer: EnginePeer?, products: [PremiumGiftProduct]?, selectedProductId: String?, present: @escaping (ViewController) -> Void, selectProduct: @escaping (String) -> Void) {
self.context = context self.context = context
self.peer = peer self.peer = peer
self.products = products self.products = products
@ -629,27 +634,27 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
var i = 0 var i = 0
if let products = component.products { if let products = component.products {
let shortestOptionPrice: Int64
if let product = products.last {
shortestOptionPrice = Int64(Float(product.storeProduct.priceCurrencyAndAmount.amount) / Float(product.months))
} else {
shortestOptionPrice = 1
}
for product in products { for product in products {
let monthsCount: Int
let giftTitle: String let giftTitle: String
if product.months == 12 {
giftTitle = strings.Premium_Gift_Years(1)
} else {
giftTitle = strings.Premium_Gift_Months(product.months)
}
let discountValue = Int((1.0 - Float(product.storeProduct.priceCurrencyAndAmount.amount) / Float(product.months) / Float(shortestOptionPrice)) * 100.0)
let discount: String let discount: String
switch product.id { if discountValue > 0 {
case "org.telegram.telegramPremium.twelveMonths": discount = "-\(discountValue)%"
giftTitle = strings.Premium_Gift_Years(1) } else {
monthsCount = 12 discount = ""
discount = "-15%"
case "org.telegram.telegramPremium.sixMonths":
giftTitle = strings.Premium_Gift_Months(6)
monthsCount = 6
discount = "-10%"
case "org.telegram.telegramPremium.threeMonths":
giftTitle = strings.Premium_Gift_Months(3)
monthsCount = 3
discount = "-7%"
default:
giftTitle = ""
monthsCount = 1
discount = ""
} }
items.append(ProductGroupComponent.Item( items.append(ProductGroupComponent.Item(
@ -659,7 +664,7 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
GiftComponent( GiftComponent(
title: giftTitle, title: giftTitle,
totalPrice: product.price, totalPrice: product.price,
perMonthPrice: strings.Premium_Gift_PricePerMonth(product.pricePerMonth(monthsCount)).string, perMonthPrice: strings.Premium_Gift_PricePerMonth(product.pricePerMonth).string,
discount: discount, discount: discount,
selected: product.id == component.selectedProductId, selected: product.id == component.selectedProductId,
primaryTextColor: textColor, primaryTextColor: textColor,
@ -705,19 +710,42 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
} }
} }
private struct PremiumGiftProduct: Equatable {
let giftOption: CachedPremiumGiftOption
let storeProduct: InAppPurchaseManager.Product
var id: String {
return self.storeProduct.id
}
var months: Int32 {
return self.giftOption.months
}
var price: String {
return self.storeProduct.price
}
var pricePerMonth: String {
return self.storeProduct.pricePerMonth(Int(self.months))
}
}
private final class PremiumGiftScreenComponent: CombinedComponent { private final class PremiumGiftScreenComponent: CombinedComponent {
typealias EnvironmentType = ViewControllerComponentContainer.Environment typealias EnvironmentType = ViewControllerComponentContainer.Environment
let context: AccountContext let context: AccountContext
let peerId: PeerId let peerId: PeerId
let options: [CachedPremiumGiftOption]
let updateInProgress: (Bool) -> Void let updateInProgress: (Bool) -> Void
let present: (ViewController) -> Void let present: (ViewController) -> Void
let push: (ViewController) -> Void let push: (ViewController) -> Void
let completion: (Int32) -> Void let completion: (Int32) -> Void
init(context: AccountContext, peerId: PeerId, updateInProgress: @escaping (Bool) -> Void, present: @escaping (ViewController) -> Void, push: @escaping (ViewController) -> Void, completion: @escaping (Int32) -> Void) { init(context: AccountContext, peerId: PeerId, options: [CachedPremiumGiftOption], updateInProgress: @escaping (Bool) -> Void, present: @escaping (ViewController) -> Void, push: @escaping (ViewController) -> Void, completion: @escaping (Int32) -> Void) {
self.context = context self.context = context
self.peerId = peerId self.peerId = peerId
self.options = options
self.updateInProgress = updateInProgress self.updateInProgress = updateInProgress
self.present = present self.present = present
self.push = push self.push = push
@ -731,12 +759,16 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
if lhs.peerId != rhs.peerId { if lhs.peerId != rhs.peerId {
return false return false
} }
if lhs.options != rhs.options {
return false
}
return true return true
} }
final class State: ComponentState { final class State: ComponentState {
private let context: AccountContext private let context: AccountContext
private let peerId: PeerId private let peerId: PeerId
private let options: [CachedPremiumGiftOption]
private let updateInProgress: (Bool) -> Void private let updateInProgress: (Bool) -> Void
private let present: (ViewController) -> Void private let present: (ViewController) -> Void
private let completion: (Int32) -> Void private let completion: (Int32) -> Void
@ -749,16 +781,17 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
var inProgress = false var inProgress = false
var peer: EnginePeer? var peer: EnginePeer?
var products: [InAppPurchaseManager.Product]? var products: [PremiumGiftProduct]?
var selectedProductId: String? var selectedProductId: String?
private var disposable: Disposable? private var disposable: Disposable?
private var paymentDisposable = MetaDisposable() private var paymentDisposable = MetaDisposable()
private var activationDisposable = MetaDisposable() private var activationDisposable = MetaDisposable()
init(context: AccountContext, peerId: PeerId, updateInProgress: @escaping (Bool) -> Void, present: @escaping (ViewController) -> Void, completion: @escaping (Int32) -> Void) { init(context: AccountContext, peerId: PeerId, options: [CachedPremiumGiftOption], updateInProgress: @escaping (Bool) -> Void, present: @escaping (ViewController) -> Void, completion: @escaping (Int32) -> Void) {
self.context = context self.context = context
self.peerId = peerId self.peerId = peerId
self.options = options
self.updateInProgress = updateInProgress self.updateInProgress = updateInProgress
self.present = present self.present = present
self.completion = completion self.completion = completion
@ -778,7 +811,15 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
).start(next: { [weak self] products, peer in ).start(next: { [weak self] products, peer in
if let strongSelf = self { if let strongSelf = self {
strongSelf.products = products.filter { !$0.isSubscription }.sorted(by: { $0.priceValue.compare($1.priceValue) == .orderedDescending })
var gifts: [PremiumGiftProduct] = []
for option in strongSelf.options {
if let product = products.first(where: { $0.id == option.storeProductId }), !product.isSubscription {
gifts.append(PremiumGiftProduct(giftOption: option, storeProduct: product))
}
}
strongSelf.products = gifts
strongSelf.selectedProductId = strongSelf.products?.first?.id strongSelf.selectedProductId = strongSelf.products?.first?.id
strongSelf.peer = peer strongSelf.peer = peer
strongSelf.updated(transition: .immediate) strongSelf.updated(transition: .immediate)
@ -805,19 +846,8 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
guard let product = self.products?.first(where: { $0.id == self.selectedProductId }) else { guard let product = self.products?.first(where: { $0.id == self.selectedProductId }) else {
return return
} }
let (currency, amount) = product.priceCurrencyAndAmount let (currency, amount) = product.storeProduct.priceCurrencyAndAmount
let duration = product.months
let duration: Int32
switch product.id {
case "org.telegram.telegramPremium.twelveMonths":
duration = 12
case "org.telegram.telegramPremium.sixMonths":
duration = 6
case "org.telegram.telegramPremium.threeMonths":
duration = 3
default:
duration = 0
}
// addAppLogEvent(postbox: self.context.account.postbox, type: "premium.promo_screen_accept") // addAppLogEvent(postbox: self.context.account.postbox, type: "premium.promo_screen_accept")
@ -829,7 +859,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
|> deliverOnMainQueue).start(next: { [weak self] available in |> deliverOnMainQueue).start(next: { [weak self] available in
if let strongSelf = self { if let strongSelf = self {
if available { if available {
strongSelf.paymentDisposable.set((inAppPurchaseManager.buyProduct(product, targetPeerId: strongSelf.peerId) strongSelf.paymentDisposable.set((inAppPurchaseManager.buyProduct(product.storeProduct, targetPeerId: strongSelf.peerId)
|> deliverOnMainQueue).start(next: { [weak self] status in |> deliverOnMainQueue).start(next: { [weak self] status in
if let strongSelf = self, case .purchased = status { if let strongSelf = self, case .purchased = status {
strongSelf.activationDisposable.set((strongSelf.context.account.postbox.peerView(id: strongSelf.context.account.peerId) strongSelf.activationDisposable.set((strongSelf.context.account.postbox.peerView(id: strongSelf.context.account.peerId)
@ -852,7 +882,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
strongSelf.updated(transition: .immediate) strongSelf.updated(transition: .immediate)
addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium.promo_screen_fail") // addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium.promo_screen_fail")
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
let errorText = presentationData.strings.Premium_Purchase_ErrorUnknown let errorText = presentationData.strings.Premium_Purchase_ErrorUnknown
@ -896,7 +926,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
} }
if let errorText = errorText { if let errorText = errorText {
addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium.promo_screen_fail") // addAppLogEvent(postbox: strongSelf.context.account.postbox, type: "premium.promo_screen_fail")
let alertController = textAlertController(context: strongSelf.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]) let alertController = textAlertController(context: strongSelf.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
strongSelf.present(alertController) strongSelf.present(alertController)
@ -919,7 +949,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent {
} }
func makeState() -> State { func makeState() -> State {
return State(context: self.context, peerId: self.peerId, updateInProgress: self.updateInProgress, present: self.present, completion: self.completion) return State(context: self.context, peerId: self.peerId, options: self.options, updateInProgress: self.updateInProgress, present: self.present, completion: self.completion)
} }
static var body: Body { static var body: Body {
@ -1242,6 +1272,7 @@ public final class PremiumGiftScreen: ViewControllerComponentContainer {
super.init(context: context, component: PremiumGiftScreenComponent( super.init(context: context, component: PremiumGiftScreenComponent(
context: context, context: context,
peerId: peerId, peerId: peerId,
options: options,
updateInProgress: { inProgress in updateInProgress: { inProgress in
updateInProgressImpl?(inProgress) updateInProgressImpl?(inProgress)
}, },

View File

@ -1220,7 +1220,7 @@ private final class StickerPackScreenNode: ViewControllerTracingNode {
super.didLoad() super.didLoad()
self.dimNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dimNodeTapGesture(_:)))) self.dimNode.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.dimNodeTapGesture(_:))))
self.containerContainingNode.view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.panGesture(_:)))) // self.containerContainingNode.view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.panGesture(_:))))
} }
func updatePresentationData(_ presentationData: PresentationData) { func updatePresentationData(_ presentationData: PresentationData) {

View File

@ -165,9 +165,9 @@ class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode {
duration = item.presentationData.strings.Notification_PremiumGift_Subtitle(item.presentationData.strings.Notification_PremiumGift_Months(months)).string duration = item.presentationData.strings.Notification_PremiumGift_Subtitle(item.presentationData.strings.Notification_PremiumGift_Months(months)).string
switch months { switch months {
case 12: case 12:
animationName = "Gift2" animationName = "Gift12"
case 6: case 6:
animationName = "Gift1" animationName = "Gift6"
case 3: case 3:
animationName = "Gift3" animationName = "Gift3"
default: default: