mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various improvements
This commit is contained in:
parent
a5bd955643
commit
78b02192cf
@ -8891,3 +8891,5 @@ Sorry for the inconvenience.";
|
||||
"Settings.RaiseToListenInfo" = "Raise to Listen allows you to quickly listen and reply to incoming audio messages by raising the phone to your ear.";
|
||||
|
||||
"Login.CodeSentCallText" = "Calling **%@** to dictate the code.";
|
||||
|
||||
"Premium.Purchase.OnlyOneSubscriptionAllowed" = "You have already purchased Telegram Premium for another account. You can only have one Telegram Premium subscription on one Apple ID.";
|
||||
|
@ -308,11 +308,17 @@ public final class InAppPurchaseManager: NSObject {
|
||||
return signal
|
||||
}
|
||||
|
||||
public func getValidTransactionIds() -> [String] {
|
||||
public struct ReceiptPurchase: Equatable {
|
||||
public let productId: String
|
||||
public let transactionId: String
|
||||
public let expirationDate: Date
|
||||
}
|
||||
|
||||
public func getReceiptPurchases() -> [ReceiptPurchase] {
|
||||
guard let data = getReceiptData(), let receipt = parseReceipt(data) else {
|
||||
return []
|
||||
}
|
||||
return receipt.purchases.map { $0.transactionId }
|
||||
return receipt.purchases.map { ReceiptPurchase(productId: $0.productId, transactionId: $0.transactionId, expirationDate: $0.expirationDate) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -359,7 +365,6 @@ extension InAppPurchaseManager: SKPaymentTransactionObserver {
|
||||
switch transaction.transactionState {
|
||||
case .purchased:
|
||||
Logger.shared.log("InAppPurchaseManager", "Account \(accountPeerId), transaction \(transaction.transactionIdentifier ?? ""), original transaction \(transaction.original?.transactionIdentifier ?? "none") purchased")
|
||||
|
||||
transactionState = .purchased(transactionId: transaction.transactionIdentifier)
|
||||
transactionsToAssign.append(transaction)
|
||||
case .restored:
|
||||
|
@ -7,6 +7,7 @@ private struct Asn1Tag {
|
||||
static let sequence: Int32 = 0x10
|
||||
static let set: Int32 = 0x11
|
||||
static let utf8String: Int32 = 0x0c
|
||||
static let date: Int32 = 0x16
|
||||
}
|
||||
|
||||
private struct Asn1Entry {
|
||||
@ -124,10 +125,12 @@ struct Receipt {
|
||||
fileprivate struct Tag {
|
||||
static let productIdentifier: Int32 = 1702
|
||||
static let transactionIdentifier: Int32 = 1703
|
||||
static let expirationDate: Int32 = 1708
|
||||
}
|
||||
|
||||
let productId: String
|
||||
let transactionId: String
|
||||
let expirationDate: Date
|
||||
}
|
||||
|
||||
let purchases: [Purchase]
|
||||
@ -192,6 +195,27 @@ func parseReceipt(_ data: Data) -> Receipt? {
|
||||
return Receipt(purchases: purchases)
|
||||
}
|
||||
|
||||
private func parseRfc3339Date(_ str: String) -> Date? {
|
||||
let posixLocale = Locale(identifier: "en_US_POSIX")
|
||||
|
||||
let formatter1 = DateFormatter()
|
||||
formatter1.locale = posixLocale
|
||||
formatter1.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssX5"
|
||||
formatter1.timeZone = TimeZone(secondsFromGMT: 0)
|
||||
|
||||
let result = formatter1.date(from: str)
|
||||
if result != nil {
|
||||
return result
|
||||
}
|
||||
|
||||
let formatter2 = DateFormatter()
|
||||
formatter2.locale = posixLocale
|
||||
formatter2.dateFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.SSSSSSX5"
|
||||
formatter2.timeZone = TimeZone(secondsFromGMT: 0)
|
||||
|
||||
return formatter2.date(from: str)
|
||||
}
|
||||
|
||||
private func parsePurchaseAttributes(_ data: Data) -> Receipt.Purchase? {
|
||||
let root = parse(data)
|
||||
guard root.tag == Asn1Tag.set else {
|
||||
@ -200,6 +224,7 @@ private func parsePurchaseAttributes(_ data: Data) -> Receipt.Purchase? {
|
||||
|
||||
var productId: String?
|
||||
var transactionId: String?
|
||||
var expirationDate: Date?
|
||||
|
||||
let receiptAttributes = parseSequence(root.data)
|
||||
for attribute in receiptAttributes {
|
||||
@ -219,12 +244,16 @@ private func parsePurchaseAttributes(_ data: Data) -> Receipt.Purchase? {
|
||||
let valEntry = parse(value)
|
||||
guard valEntry.tag == Asn1Tag.utf8String else { return nil }
|
||||
transactionId = String(bytes: valEntry.data, encoding: .utf8)
|
||||
case Receipt.Purchase.Tag.expirationDate:
|
||||
let valEntry = parse(value)
|
||||
guard valEntry.tag == Asn1Tag.date else { return nil }
|
||||
expirationDate = parseRfc3339Date(String(bytes: valEntry.data, encoding: .utf8) ?? "")
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
guard let productId, let transactionId else {
|
||||
guard let productId, let transactionId, let expirationDate else {
|
||||
return nil
|
||||
}
|
||||
return Receipt.Purchase(productId: productId, transactionId: transactionId)
|
||||
return Receipt.Purchase(productId: productId, transactionId: transactionId, expirationDate: expirationDate)
|
||||
}
|
||||
|
@ -1196,14 +1196,28 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
||||
let otherPeerName: String?
|
||||
let products: [PremiumProduct]?
|
||||
let selectedProductId: String?
|
||||
let validTransactionIds: [String]
|
||||
let validPurchases: [InAppPurchaseManager.ReceiptPurchase]
|
||||
let promoConfiguration: PremiumPromoConfiguration?
|
||||
let present: (ViewController) -> Void
|
||||
let selectProduct: (String) -> Void
|
||||
let buy: () -> Void
|
||||
let updateIsFocused: (Bool) -> Void
|
||||
|
||||
init(context: AccountContext, source: PremiumSource, isPremium: Bool?, justBought: Bool, otherPeerName: String?, products: [PremiumProduct]?, selectedProductId: String?, validTransactionIds: [String], promoConfiguration: PremiumPromoConfiguration?, present: @escaping (ViewController) -> Void, selectProduct: @escaping (String) -> Void, buy: @escaping () -> Void, updateIsFocused: @escaping (Bool) -> Void) {
|
||||
init(
|
||||
context: AccountContext,
|
||||
source: PremiumSource,
|
||||
isPremium: Bool?,
|
||||
justBought: Bool,
|
||||
otherPeerName: String?,
|
||||
products: [PremiumProduct]?,
|
||||
selectedProductId: String?,
|
||||
validPurchases: [InAppPurchaseManager.ReceiptPurchase],
|
||||
promoConfiguration: PremiumPromoConfiguration?,
|
||||
present: @escaping (ViewController) -> Void,
|
||||
selectProduct: @escaping (String) -> Void,
|
||||
buy: @escaping () -> Void,
|
||||
updateIsFocused: @escaping (Bool) -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.source = source
|
||||
self.isPremium = isPremium
|
||||
@ -1211,7 +1225,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
||||
self.otherPeerName = otherPeerName
|
||||
self.products = products
|
||||
self.selectedProductId = selectedProductId
|
||||
self.validTransactionIds = validTransactionIds
|
||||
self.validPurchases = validPurchases
|
||||
self.promoConfiguration = promoConfiguration
|
||||
self.present = present
|
||||
self.selectProduct = selectProduct
|
||||
@ -1241,7 +1255,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
||||
if lhs.selectedProductId != rhs.selectedProductId {
|
||||
return false
|
||||
}
|
||||
if lhs.validTransactionIds != rhs.validTransactionIds {
|
||||
if lhs.validPurchases != rhs.validPurchases {
|
||||
return false
|
||||
}
|
||||
if lhs.promoConfiguration != rhs.promoConfiguration {
|
||||
@ -1256,7 +1270,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
||||
|
||||
var products: [PremiumProduct]?
|
||||
var selectedProductId: String?
|
||||
var validTransactionIds: [String] = []
|
||||
var validPurchases: [InAppPurchaseManager.ReceiptPurchase] = []
|
||||
|
||||
var isPremium: Bool?
|
||||
|
||||
@ -1276,7 +1290,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
||||
|
||||
var canUpgrade: Bool {
|
||||
if let products = self.products, let current = products.first(where: { $0.isCurrent }), let transactionId = current.transactionId {
|
||||
if self.validTransactionIds.contains(transactionId) {
|
||||
if self.validPurchases.contains(where: { $0.transactionId == transactionId }) {
|
||||
return products.first(where: { $0.months > current.months }) != nil
|
||||
} else {
|
||||
return false
|
||||
@ -1373,7 +1387,7 @@ private final class PremiumIntroScreenContentComponent: CombinedComponent {
|
||||
let state = context.state
|
||||
state.products = context.component.products
|
||||
state.selectedProductId = context.component.selectedProductId
|
||||
state.validTransactionIds = context.component.validTransactionIds
|
||||
state.validPurchases = context.component.validPurchases
|
||||
state.isPremium = context.component.isPremium
|
||||
|
||||
let theme = environment.theme
|
||||
@ -1986,7 +2000,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
|
||||
private(set) var products: [PremiumProduct]?
|
||||
private(set) var selectedProductId: String?
|
||||
fileprivate var validTransactionIds: [String] = []
|
||||
fileprivate var validPurchases: [InAppPurchaseManager.ReceiptPurchase] = []
|
||||
|
||||
var isPremium: Bool?
|
||||
var otherPeerName: String?
|
||||
@ -2015,7 +2029,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
|
||||
var canUpgrade: Bool {
|
||||
if let products = self.products, let current = products.first(where: { $0.isCurrent }), let transactionId = current.transactionId {
|
||||
if self.validTransactionIds.contains(transactionId) {
|
||||
if self.validPurchases.contains(where: { $0.transactionId == transactionId }) {
|
||||
return products.first(where: { $0.months > current.months }) != nil
|
||||
} else {
|
||||
return false
|
||||
@ -2036,7 +2050,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
|
||||
super.init()
|
||||
|
||||
self.validTransactionIds = context.inAppPurchaseManager?.getValidTransactionIds() ?? []
|
||||
self.validPurchases = context.inAppPurchaseManager?.getReceiptPurchases() ?? []
|
||||
|
||||
let availableProducts: Signal<[InAppPurchaseManager.Product], NoError>
|
||||
if let inAppPurchaseManager = context.inAppPurchaseManager {
|
||||
@ -2136,8 +2150,29 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
let premiumProduct = self.products?.first(where: { $0.id == self.selectedProductId }), !self.inProgress else {
|
||||
return
|
||||
}
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
let isUpgrade = self.products?.first(where: { $0.isCurrent }) != nil
|
||||
|
||||
var hasActiveSubsciption = false
|
||||
if let data = self.context.currentAppConfiguration.with({ $0 }).data, let _ = data["ios_killswitch_disable_receipt_check"] {
|
||||
|
||||
} else if !self.validPurchases.isEmpty && !isUpgrade {
|
||||
let now = Date()
|
||||
for purchase in self.validPurchases.reversed() {
|
||||
if (purchase.productId.hasSuffix(".monthly") || purchase.productId.hasSuffix(".annual")) && purchase.expirationDate > now {
|
||||
hasActiveSubsciption = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if hasActiveSubsciption {
|
||||
let errorText = presentationData.strings.Premium_Purchase_OnlyOneSubscriptionAllowed
|
||||
let alertController = textAlertController(context: self.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
|
||||
self.present(alertController)
|
||||
return
|
||||
}
|
||||
|
||||
addAppLogEvent(postbox: self.context.account.postbox, type: "premium.promo_screen_accept")
|
||||
|
||||
self.inProgress = true
|
||||
@ -2173,7 +2208,6 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
|
||||
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
|
||||
let alertController = textAlertController(context: strongSelf.context, title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})])
|
||||
strongSelf.present(alertController)
|
||||
@ -2198,7 +2232,6 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
strongSelf.updateInProgress(false)
|
||||
strongSelf.updated(transition: .immediate)
|
||||
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
var errorText: String?
|
||||
switch error {
|
||||
case .generic:
|
||||
@ -2475,7 +2508,7 @@ private final class PremiumIntroScreenComponent: CombinedComponent {
|
||||
otherPeerName: state.otherPeerName,
|
||||
products: state.products,
|
||||
selectedProductId: state.selectedProductId,
|
||||
validTransactionIds: state.validTransactionIds,
|
||||
validPurchases: state.validPurchases,
|
||||
promoConfiguration: state.promoConfiguration,
|
||||
present: context.component.present,
|
||||
selectProduct: { [weak state] productId in
|
||||
|
@ -188,7 +188,7 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
|
||||
case .x0_5:
|
||||
self.rateButton.setContent(.image(optionsRateImage(rate: "0.5X", color: self.theme.rootController.navigationBar.accentTextColor)))
|
||||
case .x1:
|
||||
self.rateButton.setContent(.image(optionsRateImage(rate: "2X", color: self.theme.rootController.navigationBar.controlColor)))
|
||||
self.rateButton.setContent(.image(optionsRateImage(rate: "1X", color: self.theme.rootController.navigationBar.controlColor)))
|
||||
self.rateButton.accessibilityLabel = self.strings.VoiceOver_Media_PlaybackRate
|
||||
self.rateButton.accessibilityValue = self.strings.VoiceOver_Media_PlaybackRateNormal
|
||||
self.rateButton.accessibilityHint = self.strings.VoiceOver_Media_PlaybackRateChange
|
||||
@ -378,7 +378,7 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
|
||||
case .x0_5:
|
||||
self.rateButton.setContent(.image(optionsRateImage(rate: "0.5X", color: self.theme.rootController.navigationBar.accentTextColor)))
|
||||
case .x1:
|
||||
self.rateButton.setContent(.image(optionsRateImage(rate: "2X", color: self.theme.rootController.navigationBar.controlColor)))
|
||||
self.rateButton.setContent(.image(optionsRateImage(rate: "1X", color: self.theme.rootController.navigationBar.controlColor)))
|
||||
case .x1_5:
|
||||
self.rateButton.setContent(.image(optionsRateImage(rate: "1.5X", color: self.theme.rootController.navigationBar.accentTextColor)))
|
||||
case .x2:
|
||||
@ -511,6 +511,8 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
|
||||
if let rate = self.playbackBaseRate {
|
||||
switch rate {
|
||||
case .x1:
|
||||
nextRate = .x1_5
|
||||
case .x1_5:
|
||||
nextRate = .x2
|
||||
default:
|
||||
nextRate = .x1
|
||||
|
@ -687,41 +687,41 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
}
|
||||
strongSelf.context.sharedContext.mediaManager.playlistControl(.setBaseRate(baseRate), type: type)
|
||||
|
||||
var hasTooltip = false
|
||||
strongSelf.forEachController({ controller in
|
||||
if let controller = controller as? UndoOverlayController {
|
||||
hasTooltip = true
|
||||
controller.dismissWithCommitAction()
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let slowdown: Bool?
|
||||
if baseRate == .x1 {
|
||||
slowdown = true
|
||||
} else if baseRate == .x2 {
|
||||
slowdown = false
|
||||
} else {
|
||||
slowdown = nil
|
||||
}
|
||||
if let slowdown = slowdown {
|
||||
strongSelf.present(
|
||||
UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .audioRate(
|
||||
slowdown: slowdown,
|
||||
text: slowdown ? presentationData.strings.Conversation_AudioRateTooltipNormal : presentationData.strings.Conversation_AudioRateTooltipSpeedUp
|
||||
),
|
||||
elevatedLayout: false,
|
||||
animateInAsReplacement: hasTooltip,
|
||||
action: { action in
|
||||
return true
|
||||
}
|
||||
),
|
||||
in: .current
|
||||
)
|
||||
}
|
||||
// var hasTooltip = false
|
||||
// strongSelf.forEachController({ controller in
|
||||
// if let controller = controller as? UndoOverlayController {
|
||||
// hasTooltip = true
|
||||
// controller.dismissWithCommitAction()
|
||||
// }
|
||||
// return true
|
||||
// })
|
||||
//
|
||||
// let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
// let slowdown: Bool?
|
||||
// if baseRate == .x1 {
|
||||
// slowdown = true
|
||||
// } else if baseRate == .x2 {
|
||||
// slowdown = false
|
||||
// } else {
|
||||
// slowdown = nil
|
||||
// }
|
||||
// if let slowdown = slowdown {
|
||||
// strongSelf.present(
|
||||
// UndoOverlayController(
|
||||
// presentationData: presentationData,
|
||||
// content: .audioRate(
|
||||
// slowdown: slowdown,
|
||||
// text: slowdown ? presentationData.strings.Conversation_AudioRateTooltipNormal : presentationData.strings.Conversation_AudioRateTooltipSpeedUp
|
||||
// ),
|
||||
// elevatedLayout: false,
|
||||
// animateInAsReplacement: hasTooltip,
|
||||
// action: { action in
|
||||
// return true
|
||||
// }
|
||||
// ),
|
||||
// in: .current
|
||||
// )
|
||||
// }
|
||||
})
|
||||
}
|
||||
mediaAccessoryPanel.togglePlayPause = { [weak self] in
|
||||
|
@ -35,6 +35,47 @@ private func generateCollapseIcon(theme: PresentationTheme) -> UIImage? {
|
||||
})
|
||||
}
|
||||
|
||||
private func optionsRateImage(rate: String, color: UIColor = .white) -> UIImage? {
|
||||
return generateImage(CGSize(width: 30.0, height: 16.0), rotatedContext: { size, context in
|
||||
UIGraphicsPushContext(context)
|
||||
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let lineWidth = 1.0 + UIScreenPixel
|
||||
context.setLineWidth(lineWidth)
|
||||
context.setStrokeColor(color.cgColor)
|
||||
|
||||
|
||||
let string = NSMutableAttributedString(string: rate, font: Font.with(size: 11.0, design: .round, weight: .bold), textColor: color)
|
||||
|
||||
var offset = CGPoint(x: 1.0, y: 0.0)
|
||||
var width: CGFloat
|
||||
if rate.count >= 3 {
|
||||
if rate == "0.5X" {
|
||||
string.addAttribute(.kern, value: -0.8 as NSNumber, range: NSRange(string.string.startIndex ..< string.string.endIndex, in: string.string))
|
||||
offset.x += -0.5
|
||||
} else {
|
||||
string.addAttribute(.kern, value: -0.5 as NSNumber, range: NSRange(string.string.startIndex ..< string.string.endIndex, in: string.string))
|
||||
offset.x += -0.3
|
||||
}
|
||||
width = 29.0
|
||||
} else {
|
||||
string.addAttribute(.kern, value: -0.5 as NSNumber, range: NSRange(string.string.startIndex ..< string.string.endIndex, in: string.string))
|
||||
width = 19.0
|
||||
offset.x += -0.3
|
||||
}
|
||||
|
||||
let path = UIBezierPath(roundedRect: CGRect(x: floorToScreenPixels((size.width - width) / 2.0), y: 0.0, width: width, height: 16.0).insetBy(dx: lineWidth / 2.0, dy: lineWidth / 2.0), byRoundingCorners: .allCorners, cornerRadii: CGSize(width: 2.0, height: 2.0))
|
||||
context.addPath(path.cgPath)
|
||||
context.strokePath()
|
||||
|
||||
let boundingRect = string.boundingRect(with: size, options: [], context: nil)
|
||||
string.draw(at: CGPoint(x: offset.x + floor((size.width - boundingRect.width) / 2.0), y: offset.y + UIScreenPixel + floor((size.height - boundingRect.height) / 2.0)))
|
||||
|
||||
UIGraphicsPopContext()
|
||||
})
|
||||
}
|
||||
|
||||
private let digitsSet = CharacterSet(charactersIn: "0123456789")
|
||||
private func timestampLabelWidthForDuration(_ timestamp: Double) -> CGFloat {
|
||||
let text: String
|
||||
@ -375,8 +416,10 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
let baseRate: AudioPlaybackRate
|
||||
if !value.status.baseRate.isEqual(to: 1.0) {
|
||||
if value.status.baseRate.isEqual(to: 2.0) {
|
||||
baseRate = .x2
|
||||
} else if value.status.baseRate.isEqual(to: 1.5) {
|
||||
baseRate = .x1_5
|
||||
} else {
|
||||
baseRate = .x1
|
||||
}
|
||||
@ -715,10 +758,9 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
private func updateOrderButton(_ order: MusicPlaybackSettingsOrder) {
|
||||
let baseColor = self.presentationData.theme.list.itemSecondaryTextColor
|
||||
switch order {
|
||||
case .regular:
|
||||
self.orderButton.icon = generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/OrderReverse"), color: baseColor)
|
||||
self.orderButton.icon = generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/OrderReverse"), color: self.presentationData.theme.list.itemSecondaryTextColor)
|
||||
case .reversed:
|
||||
self.orderButton.icon = generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/OrderReverse"), color: self.presentationData.theme.list.itemAccentColor)
|
||||
case .random:
|
||||
@ -741,9 +783,11 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
|
||||
private func updateRateButton(_ baseRate: AudioPlaybackRate) {
|
||||
switch baseRate {
|
||||
case .x2:
|
||||
self.rateButton.setImage(PresentationResourcesRootController.navigationPlayerMaximizedRateActiveIcon(self.presentationData.theme), for: [])
|
||||
self.rateButton.setImage(optionsRateImage(rate: "2X", color: self.presentationData.theme.list.itemAccentColor), for: [])
|
||||
case .x1_5:
|
||||
self.rateButton.setImage(optionsRateImage(rate: "1.5X", color: self.presentationData.theme.list.itemAccentColor), for: [])
|
||||
default:
|
||||
self.rateButton.setImage(PresentationResourcesRootController.navigationPlayerMaximizedRateInactiveIcon(self.presentationData.theme), for: [])
|
||||
self.rateButton.setImage(optionsRateImage(rate: "1X", color: self.presentationData.theme.list.itemSecondaryTextColor), for: [])
|
||||
}
|
||||
}
|
||||
|
||||
@ -959,12 +1003,14 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
|
||||
if let currentRate = self.currentRate {
|
||||
switch currentRate {
|
||||
case .x1:
|
||||
nextRate = .x1_5
|
||||
case .x1_5:
|
||||
nextRate = .x2
|
||||
default:
|
||||
nextRate = .x1
|
||||
}
|
||||
} else {
|
||||
nextRate = .x2
|
||||
nextRate = .x1_5
|
||||
}
|
||||
self.control?(.setBaseRate(nextRate))
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user