diff --git a/Telegram/Telegram-iOS/Resources/Gift1.tgs b/Telegram/Telegram-iOS/Resources/Gift1.tgs deleted file mode 100644 index f0b6f7a3cb..0000000000 Binary files a/Telegram/Telegram-iOS/Resources/Gift1.tgs and /dev/null differ diff --git a/Telegram/Telegram-iOS/Resources/Gift12.tgs b/Telegram/Telegram-iOS/Resources/Gift12.tgs new file mode 100644 index 0000000000..3fb5c07907 Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/Gift12.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/Gift2.tgs b/Telegram/Telegram-iOS/Resources/Gift2.tgs deleted file mode 100644 index 59d727cdf5..0000000000 Binary files a/Telegram/Telegram-iOS/Resources/Gift2.tgs and /dev/null differ diff --git a/Telegram/Telegram-iOS/Resources/Gift3.tgs b/Telegram/Telegram-iOS/Resources/Gift3.tgs index ba9a105858..42bfb3cbcd 100644 Binary files a/Telegram/Telegram-iOS/Resources/Gift3.tgs and b/Telegram/Telegram-iOS/Resources/Gift3.tgs differ diff --git a/Telegram/Telegram-iOS/Resources/Gift6.tgs b/Telegram/Telegram-iOS/Resources/Gift6.tgs new file mode 100644 index 0000000000..be7a587354 Binary files /dev/null and b/Telegram/Telegram-iOS/Resources/Gift6.tgs differ diff --git a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift index 8fa355bb15..d586315cdc 100644 --- a/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift +++ b/submodules/GalleryUI/Sources/Items/UniversalVideoGalleryItem.swift @@ -2476,16 +2476,16 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode { c.setItems(strongSelf.contextMenuSpeedItems() |> map { ContextController.Items(content: .list($0)) }, minHeight: nil) }))) - - 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 - f(.default) - guard let strongSelf = self else { - return - } - strongSelf.beginAirPlaySetup() - }))) - } + +// 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 +// f(.default) +// guard let strongSelf = self else { +// return +// } +// strongSelf.beginAirPlaySetup() +// }))) +// } if let (message, _, _) = strongSelf.contentInfo() { for media in message.media { diff --git a/submodules/PremiumUI/Sources/PremiumGiftScreen.swift b/submodules/PremiumUI/Sources/PremiumGiftScreen.swift index 1a8ebf6a09..c85674f73b 100644 --- a/submodules/PremiumUI/Sources/PremiumGiftScreen.swift +++ b/submodules/PremiumUI/Sources/PremiumGiftScreen.swift @@ -145,7 +145,7 @@ private final class ProductGroupComponent: Component { buttonView?.backgroundColor = component.selectionColor } else { 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 ) - let discount = discount.update( - component: MultilineTextComponent( - text: .plain( - NSAttributedString( - string: component.discount, - font: Font.with(size: 14.0, design: .round, weight: .semibold, traits: []), - textColor: .white - ) + let discountSize: CGSize + if !component.discount.isEmpty { + let discount = discount.update( + component: MultilineTextComponent( + text: .plain( + NSAttributedString( + 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( - color: component.accentColor, - cornerRadius: 5.0 - ), - availableSize: discountSize, - transition: context.transition - ) + let discountBackground = discountBackground.update( + component: RoundedRectangle( + color: component.accentColor, + cornerRadius: 5.0 + ), + 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( component: MultilineTextComponent( @@ -359,17 +372,9 @@ private final class GiftComponent: CombinedComponent { context.add(title .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 - .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) @@ -510,13 +515,13 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent { let context: AccountContext let peer: EnginePeer? - let products: [InAppPurchaseManager.Product]? + let products: [PremiumGiftProduct]? let selectedProductId: String? let present: (ViewController) -> 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.peer = peer self.products = products @@ -629,27 +634,27 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent { var i = 0 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 { - let monthsCount: Int 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 - switch product.id { - case "org.telegram.telegramPremium.twelveMonths": - giftTitle = strings.Premium_Gift_Years(1) - monthsCount = 12 - 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 = "" + if discountValue > 0 { + discount = "-\(discountValue)%" + } else { + discount = "" } items.append(ProductGroupComponent.Item( @@ -659,7 +664,7 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent { GiftComponent( title: giftTitle, totalPrice: product.price, - perMonthPrice: strings.Premium_Gift_PricePerMonth(product.pricePerMonth(monthsCount)).string, + perMonthPrice: strings.Premium_Gift_PricePerMonth(product.pricePerMonth).string, discount: discount, selected: product.id == component.selectedProductId, 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 { typealias EnvironmentType = ViewControllerComponentContainer.Environment let context: AccountContext let peerId: PeerId + let options: [CachedPremiumGiftOption] let updateInProgress: (Bool) -> Void let present: (ViewController) -> Void let push: (ViewController) -> 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.peerId = peerId + self.options = options self.updateInProgress = updateInProgress self.present = present self.push = push @@ -731,12 +759,16 @@ private final class PremiumGiftScreenComponent: CombinedComponent { if lhs.peerId != rhs.peerId { return false } + if lhs.options != rhs.options { + return false + } return true } final class State: ComponentState { private let context: AccountContext private let peerId: PeerId + private let options: [CachedPremiumGiftOption] private let updateInProgress: (Bool) -> Void private let present: (ViewController) -> Void private let completion: (Int32) -> Void @@ -749,16 +781,17 @@ private final class PremiumGiftScreenComponent: CombinedComponent { var inProgress = false var peer: EnginePeer? - var products: [InAppPurchaseManager.Product]? + var products: [PremiumGiftProduct]? var selectedProductId: String? private var disposable: Disposable? private var paymentDisposable = 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.peerId = peerId + self.options = options self.updateInProgress = updateInProgress self.present = present self.completion = completion @@ -778,7 +811,15 @@ private final class PremiumGiftScreenComponent: CombinedComponent { context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)) ).start(next: { [weak self] products, peer in 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.peer = peer 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 { return } - let (currency, amount) = product.priceCurrencyAndAmount - - 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 - } + let (currency, amount) = product.storeProduct.priceCurrencyAndAmount + let duration = product.months // 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 if let strongSelf = self { 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 if let strongSelf = self, case .purchased = status { 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) - 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 errorText = presentationData.strings.Premium_Purchase_ErrorUnknown @@ -896,7 +926,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent { } 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: {})]) strongSelf.present(alertController) @@ -919,7 +949,7 @@ private final class PremiumGiftScreenComponent: CombinedComponent { } 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 { @@ -1242,6 +1272,7 @@ public final class PremiumGiftScreen: ViewControllerComponentContainer { super.init(context: context, component: PremiumGiftScreenComponent( context: context, peerId: peerId, + options: options, updateInProgress: { inProgress in updateInProgressImpl?(inProgress) }, diff --git a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift index 0e266423e0..f3ebc8cbe4 100644 --- a/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift +++ b/submodules/StickerPackPreviewUI/Sources/StickerPackScreen.swift @@ -1220,7 +1220,7 @@ private final class StickerPackScreenNode: ViewControllerTracingNode { super.didLoad() 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) { diff --git a/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift index 937e1b1fdc..6340b68b50 100644 --- a/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageGiftItemNode.swift @@ -165,9 +165,9 @@ class ChatMessageGiftBubbleContentNode: ChatMessageBubbleContentNode { duration = item.presentationData.strings.Notification_PremiumGift_Subtitle(item.presentationData.strings.Notification_PremiumGift_Months(months)).string switch months { case 12: - animationName = "Gift2" + animationName = "Gift12" case 6: - animationName = "Gift1" + animationName = "Gift6" case 3: animationName = "Gift3" default: