mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
af3d440f5a
commit
28728b2ece
@ -305,6 +305,7 @@ public enum ResolvedUrl {
|
|||||||
case startAttach(peerId: PeerId, payload: String?, choose: ResolvedBotChoosePeerTypes?)
|
case startAttach(peerId: PeerId, payload: String?, choose: ResolvedBotChoosePeerTypes?)
|
||||||
case invoice(slug: String, invoice: TelegramMediaInvoice?)
|
case invoice(slug: String, invoice: TelegramMediaInvoice?)
|
||||||
case premiumOffer(reference: String?)
|
case premiumOffer(reference: String?)
|
||||||
|
case starsTopup(amount: Int64?)
|
||||||
case chatFolder(slug: String)
|
case chatFolder(slug: String)
|
||||||
case story(peerId: PeerId, id: Int32)
|
case story(peerId: PeerId, id: Int32)
|
||||||
case boost(peerId: PeerId?, status: ChannelBoostStatus?, myBoostStatus: MyBoostStatus?)
|
case boost(peerId: PeerId?, status: ChannelBoostStatus?, myBoostStatus: MyBoostStatus?)
|
||||||
|
@ -123,7 +123,7 @@ public enum BoostSubject: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum StarsPurchasePurpose: Equatable {
|
public enum StarsPurchasePurpose: Equatable {
|
||||||
case generic
|
case generic(requiredStars: Int64?)
|
||||||
case transfer(peerId: EnginePeer.Id, requiredStars: Int64)
|
case transfer(peerId: EnginePeer.Id, requiredStars: Int64)
|
||||||
case subscription(peerId: EnginePeer.Id, requiredStars: Int64, renew: Bool)
|
case subscription(peerId: EnginePeer.Id, requiredStars: Int64, renew: Bool)
|
||||||
case gift(peerId: EnginePeer.Id)
|
case gift(peerId: EnginePeer.Id)
|
||||||
|
@ -713,7 +713,7 @@ public class AttachmentController: ViewController, MinimizableController {
|
|||||||
}
|
}
|
||||||
if case .ended = recognizer.state {
|
if case .ended = recognizer.state {
|
||||||
if let lastController = self.currentControllers.last {
|
if let lastController = self.currentControllers.last {
|
||||||
if let controller = self.controller, controller.shouldMinimizeOnSwipe?(self.currentType) == true {
|
if let controller = self.controller, let layout = self.validLayout, !layout.metrics.isTablet, controller.shouldMinimizeOnSwipe?(self.currentType) == true {
|
||||||
self.minimize()
|
self.minimize()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -48,6 +48,7 @@ swift_library(
|
|||||||
"//submodules/SearchBarNode",
|
"//submodules/SearchBarNode",
|
||||||
"//submodules/TelegramUI/Components/SaveProgressScreen",
|
"//submodules/TelegramUI/Components/SaveProgressScreen",
|
||||||
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
"//submodules/TelegramUI/Components/ListActionItemComponent",
|
||||||
|
"//submodules/Utils/DeviceModel",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -20,6 +20,7 @@ import MultilineTextComponent
|
|||||||
import UrlEscaping
|
import UrlEscaping
|
||||||
import UrlHandling
|
import UrlHandling
|
||||||
import SaveProgressScreen
|
import SaveProgressScreen
|
||||||
|
import DeviceModel
|
||||||
|
|
||||||
private final class TonSchemeHandler: NSObject, WKURLSchemeHandler {
|
private final class TonSchemeHandler: NSObject, WKURLSchemeHandler {
|
||||||
private final class PendingTask {
|
private final class PendingTask {
|
||||||
@ -151,6 +152,22 @@ private class WeakScriptMessageHandler: NSObject, WKScriptMessageHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func computedUserAgent() -> String {
|
||||||
|
func getFirmwareVersion() -> String? {
|
||||||
|
var size = 0
|
||||||
|
sysctlbyname("kern.osversion", nil, &size, nil, 0)
|
||||||
|
|
||||||
|
var str = [CChar](repeating: 0, count: size)
|
||||||
|
sysctlbyname("kern.osversion", &str, &size, nil, 0)
|
||||||
|
|
||||||
|
return String(cString: str)
|
||||||
|
}
|
||||||
|
|
||||||
|
let osVersion = UIDevice.current.systemVersion
|
||||||
|
let firmwareVersion = getFirmwareVersion() ?? "15E148"
|
||||||
|
return DeviceModel.current.isIpad ? "Version/\(osVersion) Safari/605.1.15" : "Version/\(osVersion) Mobile/\(firmwareVersion) Safari/604.1"
|
||||||
|
}
|
||||||
|
|
||||||
final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKUIDelegate, UIScrollViewDelegate {
|
final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKUIDelegate, UIScrollViewDelegate {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private var presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
@ -211,6 +228,7 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||||||
let touchScript = WKUserScript(source: setupTouchObservers, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
let touchScript = WKUserScript(source: setupTouchObservers, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
contentController.addUserScript(touchScript)
|
contentController.addUserScript(touchScript)
|
||||||
configuration.userContentController = contentController
|
configuration.userContentController = contentController
|
||||||
|
configuration.applicationNameForUserAgent = computedUserAgent()
|
||||||
|
|
||||||
var handleScriptMessageImpl: ((WKScriptMessage) -> Void)?
|
var handleScriptMessageImpl: ((WKScriptMessage) -> Void)?
|
||||||
let eventProxyScript = WKUserScript(source: eventProxySource, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
let eventProxyScript = WKUserScript(source: eventProxySource, injectionTime: .atDocumentStart, forMainFrameOnly: false)
|
||||||
@ -221,7 +239,7 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||||||
|
|
||||||
self.webView = WebView(frame: CGRect(), configuration: configuration)
|
self.webView = WebView(frame: CGRect(), configuration: configuration)
|
||||||
self.webView.allowsLinkPreview = true
|
self.webView.allowsLinkPreview = true
|
||||||
|
|
||||||
if #available(iOS 11.0, *) {
|
if #available(iOS 11.0, *) {
|
||||||
self.webView.scrollView.contentInsetAdjustmentBehavior = .never
|
self.webView.scrollView.contentInsetAdjustmentBehavior = .never
|
||||||
}
|
}
|
||||||
@ -529,7 +547,14 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||||||
|
|
||||||
self.previousScrollingOffset = ScrollingOffsetState(value: self.webView.scrollView.contentOffset.y, isDraggingOrDecelerating: self.webView.scrollView.isDragging || self.webView.scrollView.isDecelerating)
|
self.previousScrollingOffset = ScrollingOffsetState(value: self.webView.scrollView.contentOffset.y, isDraggingOrDecelerating: self.webView.scrollView.isDragging || self.webView.scrollView.isDecelerating)
|
||||||
|
|
||||||
let webViewFrame = CGRect(origin: CGPoint(x: insets.left, y: insets.top), size: CGSize(width: size.width - insets.left - insets.right, height: size.height - insets.top))
|
let currentBounds = self.webView.scrollView.bounds
|
||||||
|
let offsetToBottomEdge = max(0.0, self.webView.scrollView.contentSize.height - currentBounds.maxY)
|
||||||
|
var bottomInset = insets.bottom
|
||||||
|
if offsetToBottomEdge < 128.0 {
|
||||||
|
bottomInset = fullInsets.bottom
|
||||||
|
}
|
||||||
|
|
||||||
|
let webViewFrame = CGRect(origin: CGPoint(x: insets.left, y: insets.top), size: CGSize(width: size.width - insets.left - insets.right, height: size.height - insets.top - bottomInset))
|
||||||
var refresh = false
|
var refresh = false
|
||||||
if self.webView.frame.width > 0 && webViewFrame.width != self.webView.frame.width {
|
if self.webView.frame.width > 0 && webViewFrame.width != self.webView.frame.width {
|
||||||
refresh = true
|
refresh = true
|
||||||
@ -540,11 +565,10 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||||||
self.webView.reloadInputViews()
|
self.webView.reloadInputViews()
|
||||||
}
|
}
|
||||||
|
|
||||||
self.webView.scrollView.contentInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: fullInsets.bottom, right: 0.0)
|
self.webView.customBottomInset = safeInsets.bottom * (1.0 - insets.bottom / fullInsets.bottom)
|
||||||
self.webView.customBottomInset = max(insets.bottom, safeInsets.bottom)
|
|
||||||
|
|
||||||
self.webView.scrollView.scrollIndicatorInsets = UIEdgeInsets(top: 0.0, left: -insets.left, bottom: 0.0, right: -insets.right)
|
// self.webView.scrollView.scrollIndicatorInsets = UIEdgeInsets(top: 0.0, left: -insets.left, bottom: 0.0, right: -insets.right)
|
||||||
self.webView.scrollView.horizontalScrollIndicatorInsets = UIEdgeInsets(top: 0.0, left: -insets.left, bottom: 0.0, right: -insets.right)
|
// self.webView.scrollView.horizontalScrollIndicatorInsets = UIEdgeInsets(top: 0.0, left: -insets.left, bottom: 0.0, right: -insets.right)
|
||||||
|
|
||||||
if let error = self.currentError {
|
if let error = self.currentError {
|
||||||
let errorSize = self.errorView.update(
|
let errorSize = self.errorView.update(
|
||||||
@ -682,7 +706,7 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||||||
// })
|
// })
|
||||||
// } else {
|
// } else {
|
||||||
if let url = navigationAction.request.url?.absoluteString {
|
if let url = navigationAction.request.url?.absoluteString {
|
||||||
if (navigationAction.targetFrame == nil || navigationAction.targetFrame?.isMainFrame == true) && (isTelegramMeLink(url) || isTelegraPhLink(url)) {
|
if (navigationAction.targetFrame == nil || navigationAction.targetFrame?.isMainFrame == true) && (isTelegramMeLink(url) || isTelegraPhLink(url)) && !url.contains("/auth/push?") && !self._state.url.contains("/auth/push?") {
|
||||||
decisionHandler(.cancel, preferences)
|
decisionHandler(.cancel, preferences)
|
||||||
self.minimize()
|
self.minimize()
|
||||||
self.openAppUrl(url)
|
self.openAppUrl(url)
|
||||||
@ -770,7 +794,9 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
|||||||
}
|
}
|
||||||
|
|
||||||
func webViewDidClose(_ webView: WKWebView) {
|
func webViewDidClose(_ webView: WKWebView) {
|
||||||
self.close()
|
Queue.mainQueue().after(0.5, {
|
||||||
|
self.close()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(iOS 15.0, *)
|
@available(iOS 15.0, *)
|
||||||
|
@ -58,6 +58,7 @@ swift_library(
|
|||||||
"//submodules/Display:Display",
|
"//submodules/Display:Display",
|
||||||
"//submodules/ImageBlur:ImageBlur",
|
"//submodules/ImageBlur:ImageBlur",
|
||||||
"//submodules/TelegramCore:TelegramCore",
|
"//submodules/TelegramCore:TelegramCore",
|
||||||
|
"//submodules/Utils/DeviceModel",
|
||||||
],
|
],
|
||||||
visibility = [
|
visibility = [
|
||||||
"//visibility:public",
|
"//visibility:public",
|
||||||
|
@ -4,6 +4,7 @@ import SwiftSignalKit
|
|||||||
import AVFoundation
|
import AVFoundation
|
||||||
import CoreImage
|
import CoreImage
|
||||||
import TelegramCore
|
import TelegramCore
|
||||||
|
import DeviceModel
|
||||||
|
|
||||||
final class CameraSession {
|
final class CameraSession {
|
||||||
private let singleSession: AVCaptureSession?
|
private let singleSession: AVCaptureSession?
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
import DeviceModel
|
||||||
|
|
||||||
public extension Camera {
|
public extension Camera {
|
||||||
enum Metrics {
|
enum Metrics {
|
||||||
@ -56,370 +57,3 @@ public extension Camera {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DeviceModel: CaseIterable, Equatable {
|
|
||||||
static var allCases: [DeviceModel] {
|
|
||||||
return [
|
|
||||||
.iPodTouch1,
|
|
||||||
.iPodTouch2,
|
|
||||||
.iPodTouch3,
|
|
||||||
.iPodTouch4,
|
|
||||||
.iPodTouch5,
|
|
||||||
.iPodTouch6,
|
|
||||||
.iPodTouch7,
|
|
||||||
.iPhone,
|
|
||||||
.iPhone3G,
|
|
||||||
.iPhone3GS,
|
|
||||||
.iPhone4,
|
|
||||||
.iPhone4S,
|
|
||||||
.iPhone5,
|
|
||||||
.iPhone5C,
|
|
||||||
.iPhone5S,
|
|
||||||
.iPhone6,
|
|
||||||
.iPhone6Plus,
|
|
||||||
.iPhone6S,
|
|
||||||
.iPhone6SPlus,
|
|
||||||
.iPhoneSE,
|
|
||||||
.iPhone7,
|
|
||||||
.iPhone7Plus,
|
|
||||||
.iPhone8,
|
|
||||||
.iPhone8Plus,
|
|
||||||
.iPhoneX,
|
|
||||||
.iPhoneXS,
|
|
||||||
.iPhoneXR,
|
|
||||||
.iPhone11,
|
|
||||||
.iPhone11Pro,
|
|
||||||
.iPhone11ProMax,
|
|
||||||
.iPhone12,
|
|
||||||
.iPhone12Mini,
|
|
||||||
.iPhone12Pro,
|
|
||||||
.iPhone12ProMax,
|
|
||||||
.iPhone13,
|
|
||||||
.iPhone13Mini,
|
|
||||||
.iPhone13Pro,
|
|
||||||
.iPhone13ProMax,
|
|
||||||
.iPhone14,
|
|
||||||
.iPhone14Plus,
|
|
||||||
.iPhone14Pro,
|
|
||||||
.iPhone14ProMax,
|
|
||||||
.iPhone15,
|
|
||||||
.iPhone15Plus,
|
|
||||||
.iPhone15Pro,
|
|
||||||
.iPhone15ProMax
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
case iPodTouch1
|
|
||||||
case iPodTouch2
|
|
||||||
case iPodTouch3
|
|
||||||
case iPodTouch4
|
|
||||||
case iPodTouch5
|
|
||||||
case iPodTouch6
|
|
||||||
case iPodTouch7
|
|
||||||
|
|
||||||
case iPhone
|
|
||||||
case iPhone3G
|
|
||||||
case iPhone3GS
|
|
||||||
|
|
||||||
case iPhone4
|
|
||||||
case iPhone4S
|
|
||||||
|
|
||||||
case iPhone5
|
|
||||||
case iPhone5C
|
|
||||||
case iPhone5S
|
|
||||||
|
|
||||||
case iPhone6
|
|
||||||
case iPhone6Plus
|
|
||||||
case iPhone6S
|
|
||||||
case iPhone6SPlus
|
|
||||||
|
|
||||||
case iPhoneSE
|
|
||||||
|
|
||||||
case iPhone7
|
|
||||||
case iPhone7Plus
|
|
||||||
case iPhone8
|
|
||||||
case iPhone8Plus
|
|
||||||
|
|
||||||
case iPhoneX
|
|
||||||
case iPhoneXS
|
|
||||||
case iPhoneXSMax
|
|
||||||
case iPhoneXR
|
|
||||||
|
|
||||||
case iPhone11
|
|
||||||
case iPhone11Pro
|
|
||||||
case iPhone11ProMax
|
|
||||||
|
|
||||||
case iPhoneSE2ndGen
|
|
||||||
|
|
||||||
case iPhone12
|
|
||||||
case iPhone12Mini
|
|
||||||
case iPhone12Pro
|
|
||||||
case iPhone12ProMax
|
|
||||||
|
|
||||||
case iPhone13
|
|
||||||
case iPhone13Mini
|
|
||||||
case iPhone13Pro
|
|
||||||
case iPhone13ProMax
|
|
||||||
|
|
||||||
case iPhoneSE3rdGen
|
|
||||||
|
|
||||||
case iPhone14
|
|
||||||
case iPhone14Plus
|
|
||||||
case iPhone14Pro
|
|
||||||
case iPhone14ProMax
|
|
||||||
|
|
||||||
case iPhone15
|
|
||||||
case iPhone15Plus
|
|
||||||
case iPhone15Pro
|
|
||||||
case iPhone15ProMax
|
|
||||||
|
|
||||||
case unknown(String)
|
|
||||||
|
|
||||||
var modelId: [String] {
|
|
||||||
switch self {
|
|
||||||
case .iPodTouch1:
|
|
||||||
return ["iPod1,1"]
|
|
||||||
case .iPodTouch2:
|
|
||||||
return ["iPod2,1"]
|
|
||||||
case .iPodTouch3:
|
|
||||||
return ["iPod3,1"]
|
|
||||||
case .iPodTouch4:
|
|
||||||
return ["iPod4,1"]
|
|
||||||
case .iPodTouch5:
|
|
||||||
return ["iPod5,1"]
|
|
||||||
case .iPodTouch6:
|
|
||||||
return ["iPod7,1"]
|
|
||||||
case .iPodTouch7:
|
|
||||||
return ["iPod9,1"]
|
|
||||||
case .iPhone:
|
|
||||||
return ["iPhone1,1"]
|
|
||||||
case .iPhone3G:
|
|
||||||
return ["iPhone1,2"]
|
|
||||||
case .iPhone3GS:
|
|
||||||
return ["iPhone2,1"]
|
|
||||||
case .iPhone4:
|
|
||||||
return ["iPhone3,1", "iPhone3,2", "iPhone3,3"]
|
|
||||||
case .iPhone4S:
|
|
||||||
return ["iPhone4,1", "iPhone4,2", "iPhone4,3"]
|
|
||||||
case .iPhone5:
|
|
||||||
return ["iPhone5,1", "iPhone5,2"]
|
|
||||||
case .iPhone5C:
|
|
||||||
return ["iPhone5,3", "iPhone5,4"]
|
|
||||||
case .iPhone5S:
|
|
||||||
return ["iPhone6,1", "iPhone6,2"]
|
|
||||||
case .iPhone6:
|
|
||||||
return ["iPhone7,2"]
|
|
||||||
case .iPhone6Plus:
|
|
||||||
return ["iPhone7,1"]
|
|
||||||
case .iPhone6S:
|
|
||||||
return ["iPhone8,1"]
|
|
||||||
case .iPhone6SPlus:
|
|
||||||
return ["iPhone8,2"]
|
|
||||||
case .iPhoneSE:
|
|
||||||
return ["iPhone8,4"]
|
|
||||||
case .iPhone7:
|
|
||||||
return ["iPhone9,1", "iPhone9,3"]
|
|
||||||
case .iPhone7Plus:
|
|
||||||
return ["iPhone9,2", "iPhone9,4"]
|
|
||||||
case .iPhone8:
|
|
||||||
return ["iPhone10,1", "iPhone10,4"]
|
|
||||||
case .iPhone8Plus:
|
|
||||||
return ["iPhone10,2", "iPhone10,5"]
|
|
||||||
case .iPhoneX:
|
|
||||||
return ["iPhone10,3", "iPhone10,6"]
|
|
||||||
case .iPhoneXS:
|
|
||||||
return ["iPhone11,2"]
|
|
||||||
case .iPhoneXSMax:
|
|
||||||
return ["iPhone11,4", "iPhone11,6"]
|
|
||||||
case .iPhoneXR:
|
|
||||||
return ["iPhone11,8"]
|
|
||||||
case .iPhone11:
|
|
||||||
return ["iPhone12,1"]
|
|
||||||
case .iPhone11Pro:
|
|
||||||
return ["iPhone12,3"]
|
|
||||||
case .iPhone11ProMax:
|
|
||||||
return ["iPhone12,5"]
|
|
||||||
case .iPhoneSE2ndGen:
|
|
||||||
return ["iPhone12,8"]
|
|
||||||
case .iPhone12:
|
|
||||||
return ["iPhone13,2"]
|
|
||||||
case .iPhone12Mini:
|
|
||||||
return ["iPhone13,1"]
|
|
||||||
case .iPhone12Pro:
|
|
||||||
return ["iPhone13,3"]
|
|
||||||
case .iPhone12ProMax:
|
|
||||||
return ["iPhone13,4"]
|
|
||||||
case .iPhone13:
|
|
||||||
return ["iPhone14,5"]
|
|
||||||
case .iPhone13Mini:
|
|
||||||
return ["iPhone14,4"]
|
|
||||||
case .iPhone13Pro:
|
|
||||||
return ["iPhone14,2"]
|
|
||||||
case .iPhone13ProMax:
|
|
||||||
return ["iPhone14,3"]
|
|
||||||
case .iPhoneSE3rdGen:
|
|
||||||
return ["iPhone14,6"]
|
|
||||||
case .iPhone14:
|
|
||||||
return ["iPhone14,7"]
|
|
||||||
case .iPhone14Plus:
|
|
||||||
return ["iPhone14,8"]
|
|
||||||
case .iPhone14Pro:
|
|
||||||
return ["iPhone15,2"]
|
|
||||||
case .iPhone14ProMax:
|
|
||||||
return ["iPhone15,3"]
|
|
||||||
case .iPhone15:
|
|
||||||
return ["iPhone15,4"]
|
|
||||||
case .iPhone15Plus:
|
|
||||||
return ["iPhone15,5"]
|
|
||||||
case .iPhone15Pro:
|
|
||||||
return ["iPhone16,1"]
|
|
||||||
case .iPhone15ProMax:
|
|
||||||
return ["iPhone16,2"]
|
|
||||||
case let .unknown(modelId):
|
|
||||||
return [modelId]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var modelName: String {
|
|
||||||
switch self {
|
|
||||||
case .iPodTouch1:
|
|
||||||
return "iPod touch 1G"
|
|
||||||
case .iPodTouch2:
|
|
||||||
return "iPod touch 2G"
|
|
||||||
case .iPodTouch3:
|
|
||||||
return "iPod touch 3G"
|
|
||||||
case .iPodTouch4:
|
|
||||||
return "iPod touch 4G"
|
|
||||||
case .iPodTouch5:
|
|
||||||
return "iPod touch 5G"
|
|
||||||
case .iPodTouch6:
|
|
||||||
return "iPod touch 6G"
|
|
||||||
case .iPodTouch7:
|
|
||||||
return "iPod touch 7G"
|
|
||||||
case .iPhone:
|
|
||||||
return "iPhone"
|
|
||||||
case .iPhone3G:
|
|
||||||
return "iPhone 3G"
|
|
||||||
case .iPhone3GS:
|
|
||||||
return "iPhone 3GS"
|
|
||||||
case .iPhone4:
|
|
||||||
return "iPhone 4"
|
|
||||||
case .iPhone4S:
|
|
||||||
return "iPhone 4S"
|
|
||||||
case .iPhone5:
|
|
||||||
return "iPhone 5"
|
|
||||||
case .iPhone5C:
|
|
||||||
return "iPhone 5C"
|
|
||||||
case .iPhone5S:
|
|
||||||
return "iPhone 5S"
|
|
||||||
case .iPhone6:
|
|
||||||
return "iPhone 6"
|
|
||||||
case .iPhone6Plus:
|
|
||||||
return "iPhone 6 Plus"
|
|
||||||
case .iPhone6S:
|
|
||||||
return "iPhone 6S"
|
|
||||||
case .iPhone6SPlus:
|
|
||||||
return "iPhone 6S Plus"
|
|
||||||
case .iPhoneSE:
|
|
||||||
return "iPhone SE"
|
|
||||||
case .iPhone7:
|
|
||||||
return "iPhone 7"
|
|
||||||
case .iPhone7Plus:
|
|
||||||
return "iPhone 7 Plus"
|
|
||||||
case .iPhone8:
|
|
||||||
return "iPhone 8"
|
|
||||||
case .iPhone8Plus:
|
|
||||||
return "iPhone 8 Plus"
|
|
||||||
case .iPhoneX:
|
|
||||||
return "iPhone X"
|
|
||||||
case .iPhoneXS:
|
|
||||||
return "iPhone XS"
|
|
||||||
case .iPhoneXSMax:
|
|
||||||
return "iPhone XS Max"
|
|
||||||
case .iPhoneXR:
|
|
||||||
return "iPhone XR"
|
|
||||||
case .iPhone11:
|
|
||||||
return "iPhone 11"
|
|
||||||
case .iPhone11Pro:
|
|
||||||
return "iPhone 11 Pro"
|
|
||||||
case .iPhone11ProMax:
|
|
||||||
return "iPhone 11 Pro Max"
|
|
||||||
case .iPhoneSE2ndGen:
|
|
||||||
return "iPhone SE (2nd gen)"
|
|
||||||
case .iPhone12:
|
|
||||||
return "iPhone 12"
|
|
||||||
case .iPhone12Mini:
|
|
||||||
return "iPhone 12 mini"
|
|
||||||
case .iPhone12Pro:
|
|
||||||
return "iPhone 12 Pro"
|
|
||||||
case .iPhone12ProMax:
|
|
||||||
return "iPhone 12 Pro Max"
|
|
||||||
case .iPhone13:
|
|
||||||
return "iPhone 13"
|
|
||||||
case .iPhone13Mini:
|
|
||||||
return "iPhone 13 mini"
|
|
||||||
case .iPhone13Pro:
|
|
||||||
return "iPhone 13 Pro"
|
|
||||||
case .iPhone13ProMax:
|
|
||||||
return "iPhone 13 Pro Max"
|
|
||||||
case .iPhoneSE3rdGen:
|
|
||||||
return "iPhone SE (3rd gen)"
|
|
||||||
case .iPhone14:
|
|
||||||
return "iPhone 14"
|
|
||||||
case .iPhone14Plus:
|
|
||||||
return "iPhone 14 Plus"
|
|
||||||
case .iPhone14Pro:
|
|
||||||
return "iPhone 14 Pro"
|
|
||||||
case .iPhone14ProMax:
|
|
||||||
return "iPhone 14 Pro Max"
|
|
||||||
case .iPhone15:
|
|
||||||
return "iPhone 15"
|
|
||||||
case .iPhone15Plus:
|
|
||||||
return "iPhone 15 Plus"
|
|
||||||
case .iPhone15Pro:
|
|
||||||
return "iPhone 15 Pro"
|
|
||||||
case .iPhone15ProMax:
|
|
||||||
return "iPhone 15 Pro Max"
|
|
||||||
case let .unknown(modelId):
|
|
||||||
if modelId.hasPrefix("iPhone") {
|
|
||||||
return "Unknown iPhone"
|
|
||||||
} else if modelId.hasPrefix("iPod") {
|
|
||||||
return "Unknown iPod"
|
|
||||||
} else if modelId.hasPrefix("iPad") {
|
|
||||||
return "Unknown iPad"
|
|
||||||
} else {
|
|
||||||
return "Unknown Device"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var isIpad: Bool {
|
|
||||||
return self.modelId.first?.hasPrefix("iPad") ?? false
|
|
||||||
}
|
|
||||||
|
|
||||||
static let current = DeviceModel()
|
|
||||||
|
|
||||||
private init() {
|
|
||||||
var systemInfo = utsname()
|
|
||||||
uname(&systemInfo)
|
|
||||||
let modelCode = withUnsafePointer(to: &systemInfo.machine) {
|
|
||||||
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
|
|
||||||
ptr in String.init(validatingUTF8: ptr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var result: DeviceModel?
|
|
||||||
if let modelCode {
|
|
||||||
for model in DeviceModel.allCases {
|
|
||||||
if model.modelId.contains(modelCode) {
|
|
||||||
result = model
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if let result {
|
|
||||||
self = result
|
|
||||||
} else {
|
|
||||||
self = .unknown(modelCode ?? "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1260,6 +1260,8 @@ final class ChatRecentActionsControllerNode: ViewControllerTracingNode {
|
|||||||
break
|
break
|
||||||
case .premiumOffer:
|
case .premiumOffer:
|
||||||
break
|
break
|
||||||
|
case .starsTopup:
|
||||||
|
break
|
||||||
case let .joinVoiceChat(peerId, invite):
|
case let .joinVoiceChat(peerId, invite):
|
||||||
strongSelf.presentController(VoiceChatJoinScreen(context: strongSelf.context, peerId: peerId, invite: invite, join: { call in
|
strongSelf.presentController(VoiceChatJoinScreen(context: strongSelf.context, peerId: peerId, invite: invite, join: { call in
|
||||||
}), .window(.root), nil)
|
}), .window(.root), nil)
|
||||||
|
@ -208,7 +208,8 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
|
|||||||
|
|
||||||
let textString: String
|
let textString: String
|
||||||
switch context.component.purpose {
|
switch context.component.purpose {
|
||||||
case .generic:
|
case let .generic(requiredStars):
|
||||||
|
let _ = requiredStars
|
||||||
textString = strings.Stars_Purchase_GetStarsInfo
|
textString = strings.Stars_Purchase_GetStarsInfo
|
||||||
case .gift:
|
case .gift:
|
||||||
textString = strings.Stars_Purchase_GiftInfo(component.peers.first?.value.compactDisplayTitle ?? "").string
|
textString = strings.Stars_Purchase_GiftInfo(component.peers.first?.value.compactDisplayTitle ?? "").string
|
||||||
@ -299,8 +300,13 @@ private final class StarsPurchaseScreenContentComponent: CombinedComponent {
|
|||||||
if let products = state.products, let balance = context.component.balance {
|
if let products = state.products, let balance = context.component.balance {
|
||||||
var minimumCount: Int64?
|
var minimumCount: Int64?
|
||||||
if let requiredStars = context.component.purpose.requiredStars {
|
if let requiredStars = context.component.purpose.requiredStars {
|
||||||
minimumCount = requiredStars - balance
|
if case .generic = context.component.purpose {
|
||||||
|
minimumCount = requiredStars
|
||||||
|
} else {
|
||||||
|
minimumCount = requiredStars - balance
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for product in products {
|
for product in products {
|
||||||
if let minimumCount, minimumCount > product.count && !(items.isEmpty && product.id == products.last?.id) {
|
if let minimumCount, minimumCount > product.count && !(items.isEmpty && product.id == products.last?.id) {
|
||||||
continue
|
continue
|
||||||
@ -810,8 +816,12 @@ private final class StarsPurchaseScreenComponent: CombinedComponent {
|
|||||||
|
|
||||||
let titleText: String
|
let titleText: String
|
||||||
switch context.component.purpose {
|
switch context.component.purpose {
|
||||||
case .generic:
|
case let .generic(requiredStars):
|
||||||
titleText = strings.Stars_Purchase_GetStars
|
if let requiredStars {
|
||||||
|
titleText = strings.Stars_Purchase_StarsNeeded(Int32(requiredStars))
|
||||||
|
} else {
|
||||||
|
titleText = strings.Stars_Purchase_GetStars
|
||||||
|
}
|
||||||
case .gift:
|
case .gift:
|
||||||
titleText = strings.Stars_Purchase_GiftStars
|
titleText = strings.Stars_Purchase_GiftStars
|
||||||
case let .transfer(_, requiredStars), let .subscription(_, requiredStars, _), let .unlockMedia(requiredStars):
|
case let .transfer(_, requiredStars), let .subscription(_, requiredStars, _), let .unlockMedia(requiredStars):
|
||||||
@ -1216,6 +1226,8 @@ private extension StarsPurchasePurpose {
|
|||||||
|
|
||||||
var requiredStars: Int64? {
|
var requiredStars: Int64? {
|
||||||
switch self {
|
switch self {
|
||||||
|
case let .generic(requiredStars):
|
||||||
|
return requiredStars
|
||||||
case let .transfer(_, requiredStars):
|
case let .transfer(_, requiredStars):
|
||||||
return requiredStars
|
return requiredStars
|
||||||
case let .subscription(_, requiredStars, _):
|
case let .subscription(_, requiredStars, _):
|
||||||
|
@ -806,7 +806,7 @@ public final class StarsTransactionsScreen: ViewControllerComponentContainer {
|
|||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let controller = context.sharedContext.makeStarsPurchaseScreen(context: context, starsContext: starsContext, options: options, purpose: .generic, completion: { [weak self] stars in
|
let controller = context.sharedContext.makeStarsPurchaseScreen(context: context, starsContext: starsContext, options: options, purpose: .generic(requiredStars: nil), completion: { [weak self] stars in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -484,7 +484,7 @@ private final class SheetContent: CombinedComponent {
|
|||||||
} else if let peerId = state?.botPeer?.id {
|
} else if let peerId = state?.botPeer?.id {
|
||||||
purpose = .transfer(peerId: peerId, requiredStars: invoice.totalAmount)
|
purpose = .transfer(peerId: peerId, requiredStars: invoice.totalAmount)
|
||||||
} else {
|
} else {
|
||||||
purpose = .generic
|
purpose = .generic(requiredStars: nil)
|
||||||
}
|
}
|
||||||
let purchaseController = accountContext.sharedContext.makeStarsPurchaseScreen(
|
let purchaseController = accountContext.sharedContext.makeStarsPurchaseScreen(
|
||||||
context: accountContext,
|
context: accountContext,
|
||||||
|
@ -656,6 +656,14 @@ func openResolvedUrlImpl(
|
|||||||
if let navigationController = navigationController {
|
if let navigationController = navigationController {
|
||||||
navigationController.pushViewController(controller, animated: true)
|
navigationController.pushViewController(controller, animated: true)
|
||||||
}
|
}
|
||||||
|
case let .starsTopup(amount):
|
||||||
|
dismissInput()
|
||||||
|
if let starsContext = context.starsContext {
|
||||||
|
let controller = context.sharedContext.makeStarsPurchaseScreen(context: context, starsContext: starsContext, options: [], purpose: .generic(requiredStars: amount), completion: { _ in })
|
||||||
|
if let navigationController = navigationController {
|
||||||
|
navigationController.pushViewController(controller, animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
case let .joinVoiceChat(peerId, invite):
|
case let .joinVoiceChat(peerId, invite):
|
||||||
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
let _ = (context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|> deliverOnMainQueue).start(next: { peer in
|
|> deliverOnMainQueue).start(next: { peer in
|
||||||
|
@ -918,6 +918,20 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
handleResolvedUrl(.premiumMultiGift(reference: reference))
|
handleResolvedUrl(.premiumMultiGift(reference: reference))
|
||||||
|
} else if parsedUrl.host == "stars_topup" {
|
||||||
|
var amount: Int64?
|
||||||
|
if let components = URLComponents(string: "/?" + query) {
|
||||||
|
if let queryItems = components.queryItems {
|
||||||
|
for queryItem in queryItems {
|
||||||
|
if let value = queryItem.value {
|
||||||
|
if queryItem.name == "amount" {
|
||||||
|
amount = Int64(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
handleResolvedUrl(.starsTopup(amount: amount))
|
||||||
} else if parsedUrl.host == "addlist" {
|
} else if parsedUrl.host == "addlist" {
|
||||||
if let components = URLComponents(string: "/?" + query) {
|
if let components = URLComponents(string: "/?" + query) {
|
||||||
var slug: String?
|
var slug: String?
|
||||||
|
20
submodules/Utils/DeviceModel/BUILD
Normal file
20
submodules/Utils/DeviceModel/BUILD
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
load("@build_bazel_rules_swift//swift:swift.bzl", "swift_library")
|
||||||
|
|
||||||
|
swift_library(
|
||||||
|
name = "DeviceModel",
|
||||||
|
module_name = "DeviceModel",
|
||||||
|
srcs = glob([
|
||||||
|
"Sources/**/*.swift",
|
||||||
|
]),
|
||||||
|
copts = [
|
||||||
|
"-warnings-as-errors",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"//submodules/SSignalKit/SwiftSignalKit",
|
||||||
|
"//submodules/LegacyComponents",
|
||||||
|
"//submodules/AccountContext",
|
||||||
|
],
|
||||||
|
visibility = [
|
||||||
|
"//visibility:public",
|
||||||
|
],
|
||||||
|
)
|
368
submodules/Utils/DeviceModel/Sources/DeviceModel.swift
Normal file
368
submodules/Utils/DeviceModel/Sources/DeviceModel.swift
Normal file
@ -0,0 +1,368 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
public enum DeviceModel: CaseIterable, Equatable {
|
||||||
|
public static var allCases: [DeviceModel] {
|
||||||
|
return [
|
||||||
|
.iPodTouch1,
|
||||||
|
.iPodTouch2,
|
||||||
|
.iPodTouch3,
|
||||||
|
.iPodTouch4,
|
||||||
|
.iPodTouch5,
|
||||||
|
.iPodTouch6,
|
||||||
|
.iPodTouch7,
|
||||||
|
.iPhone,
|
||||||
|
.iPhone3G,
|
||||||
|
.iPhone3GS,
|
||||||
|
.iPhone4,
|
||||||
|
.iPhone4S,
|
||||||
|
.iPhone5,
|
||||||
|
.iPhone5C,
|
||||||
|
.iPhone5S,
|
||||||
|
.iPhone6,
|
||||||
|
.iPhone6Plus,
|
||||||
|
.iPhone6S,
|
||||||
|
.iPhone6SPlus,
|
||||||
|
.iPhoneSE,
|
||||||
|
.iPhone7,
|
||||||
|
.iPhone7Plus,
|
||||||
|
.iPhone8,
|
||||||
|
.iPhone8Plus,
|
||||||
|
.iPhoneX,
|
||||||
|
.iPhoneXS,
|
||||||
|
.iPhoneXR,
|
||||||
|
.iPhone11,
|
||||||
|
.iPhone11Pro,
|
||||||
|
.iPhone11ProMax,
|
||||||
|
.iPhone12,
|
||||||
|
.iPhone12Mini,
|
||||||
|
.iPhone12Pro,
|
||||||
|
.iPhone12ProMax,
|
||||||
|
.iPhone13,
|
||||||
|
.iPhone13Mini,
|
||||||
|
.iPhone13Pro,
|
||||||
|
.iPhone13ProMax,
|
||||||
|
.iPhone14,
|
||||||
|
.iPhone14Plus,
|
||||||
|
.iPhone14Pro,
|
||||||
|
.iPhone14ProMax,
|
||||||
|
.iPhone15,
|
||||||
|
.iPhone15Plus,
|
||||||
|
.iPhone15Pro,
|
||||||
|
.iPhone15ProMax
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
case iPodTouch1
|
||||||
|
case iPodTouch2
|
||||||
|
case iPodTouch3
|
||||||
|
case iPodTouch4
|
||||||
|
case iPodTouch5
|
||||||
|
case iPodTouch6
|
||||||
|
case iPodTouch7
|
||||||
|
|
||||||
|
case iPhone
|
||||||
|
case iPhone3G
|
||||||
|
case iPhone3GS
|
||||||
|
|
||||||
|
case iPhone4
|
||||||
|
case iPhone4S
|
||||||
|
|
||||||
|
case iPhone5
|
||||||
|
case iPhone5C
|
||||||
|
case iPhone5S
|
||||||
|
|
||||||
|
case iPhone6
|
||||||
|
case iPhone6Plus
|
||||||
|
case iPhone6S
|
||||||
|
case iPhone6SPlus
|
||||||
|
|
||||||
|
case iPhoneSE
|
||||||
|
|
||||||
|
case iPhone7
|
||||||
|
case iPhone7Plus
|
||||||
|
case iPhone8
|
||||||
|
case iPhone8Plus
|
||||||
|
|
||||||
|
case iPhoneX
|
||||||
|
case iPhoneXS
|
||||||
|
case iPhoneXSMax
|
||||||
|
case iPhoneXR
|
||||||
|
|
||||||
|
case iPhone11
|
||||||
|
case iPhone11Pro
|
||||||
|
case iPhone11ProMax
|
||||||
|
|
||||||
|
case iPhoneSE2ndGen
|
||||||
|
|
||||||
|
case iPhone12
|
||||||
|
case iPhone12Mini
|
||||||
|
case iPhone12Pro
|
||||||
|
case iPhone12ProMax
|
||||||
|
|
||||||
|
case iPhone13
|
||||||
|
case iPhone13Mini
|
||||||
|
case iPhone13Pro
|
||||||
|
case iPhone13ProMax
|
||||||
|
|
||||||
|
case iPhoneSE3rdGen
|
||||||
|
|
||||||
|
case iPhone14
|
||||||
|
case iPhone14Plus
|
||||||
|
case iPhone14Pro
|
||||||
|
case iPhone14ProMax
|
||||||
|
|
||||||
|
case iPhone15
|
||||||
|
case iPhone15Plus
|
||||||
|
case iPhone15Pro
|
||||||
|
case iPhone15ProMax
|
||||||
|
|
||||||
|
case unknown(String)
|
||||||
|
|
||||||
|
public var modelId: [String] {
|
||||||
|
switch self {
|
||||||
|
case .iPodTouch1:
|
||||||
|
return ["iPod1,1"]
|
||||||
|
case .iPodTouch2:
|
||||||
|
return ["iPod2,1"]
|
||||||
|
case .iPodTouch3:
|
||||||
|
return ["iPod3,1"]
|
||||||
|
case .iPodTouch4:
|
||||||
|
return ["iPod4,1"]
|
||||||
|
case .iPodTouch5:
|
||||||
|
return ["iPod5,1"]
|
||||||
|
case .iPodTouch6:
|
||||||
|
return ["iPod7,1"]
|
||||||
|
case .iPodTouch7:
|
||||||
|
return ["iPod9,1"]
|
||||||
|
case .iPhone:
|
||||||
|
return ["iPhone1,1"]
|
||||||
|
case .iPhone3G:
|
||||||
|
return ["iPhone1,2"]
|
||||||
|
case .iPhone3GS:
|
||||||
|
return ["iPhone2,1"]
|
||||||
|
case .iPhone4:
|
||||||
|
return ["iPhone3,1", "iPhone3,2", "iPhone3,3"]
|
||||||
|
case .iPhone4S:
|
||||||
|
return ["iPhone4,1", "iPhone4,2", "iPhone4,3"]
|
||||||
|
case .iPhone5:
|
||||||
|
return ["iPhone5,1", "iPhone5,2"]
|
||||||
|
case .iPhone5C:
|
||||||
|
return ["iPhone5,3", "iPhone5,4"]
|
||||||
|
case .iPhone5S:
|
||||||
|
return ["iPhone6,1", "iPhone6,2"]
|
||||||
|
case .iPhone6:
|
||||||
|
return ["iPhone7,2"]
|
||||||
|
case .iPhone6Plus:
|
||||||
|
return ["iPhone7,1"]
|
||||||
|
case .iPhone6S:
|
||||||
|
return ["iPhone8,1"]
|
||||||
|
case .iPhone6SPlus:
|
||||||
|
return ["iPhone8,2"]
|
||||||
|
case .iPhoneSE:
|
||||||
|
return ["iPhone8,4"]
|
||||||
|
case .iPhone7:
|
||||||
|
return ["iPhone9,1", "iPhone9,3"]
|
||||||
|
case .iPhone7Plus:
|
||||||
|
return ["iPhone9,2", "iPhone9,4"]
|
||||||
|
case .iPhone8:
|
||||||
|
return ["iPhone10,1", "iPhone10,4"]
|
||||||
|
case .iPhone8Plus:
|
||||||
|
return ["iPhone10,2", "iPhone10,5"]
|
||||||
|
case .iPhoneX:
|
||||||
|
return ["iPhone10,3", "iPhone10,6"]
|
||||||
|
case .iPhoneXS:
|
||||||
|
return ["iPhone11,2"]
|
||||||
|
case .iPhoneXSMax:
|
||||||
|
return ["iPhone11,4", "iPhone11,6"]
|
||||||
|
case .iPhoneXR:
|
||||||
|
return ["iPhone11,8"]
|
||||||
|
case .iPhone11:
|
||||||
|
return ["iPhone12,1"]
|
||||||
|
case .iPhone11Pro:
|
||||||
|
return ["iPhone12,3"]
|
||||||
|
case .iPhone11ProMax:
|
||||||
|
return ["iPhone12,5"]
|
||||||
|
case .iPhoneSE2ndGen:
|
||||||
|
return ["iPhone12,8"]
|
||||||
|
case .iPhone12:
|
||||||
|
return ["iPhone13,2"]
|
||||||
|
case .iPhone12Mini:
|
||||||
|
return ["iPhone13,1"]
|
||||||
|
case .iPhone12Pro:
|
||||||
|
return ["iPhone13,3"]
|
||||||
|
case .iPhone12ProMax:
|
||||||
|
return ["iPhone13,4"]
|
||||||
|
case .iPhone13:
|
||||||
|
return ["iPhone14,5"]
|
||||||
|
case .iPhone13Mini:
|
||||||
|
return ["iPhone14,4"]
|
||||||
|
case .iPhone13Pro:
|
||||||
|
return ["iPhone14,2"]
|
||||||
|
case .iPhone13ProMax:
|
||||||
|
return ["iPhone14,3"]
|
||||||
|
case .iPhoneSE3rdGen:
|
||||||
|
return ["iPhone14,6"]
|
||||||
|
case .iPhone14:
|
||||||
|
return ["iPhone14,7"]
|
||||||
|
case .iPhone14Plus:
|
||||||
|
return ["iPhone14,8"]
|
||||||
|
case .iPhone14Pro:
|
||||||
|
return ["iPhone15,2"]
|
||||||
|
case .iPhone14ProMax:
|
||||||
|
return ["iPhone15,3"]
|
||||||
|
case .iPhone15:
|
||||||
|
return ["iPhone15,4"]
|
||||||
|
case .iPhone15Plus:
|
||||||
|
return ["iPhone15,5"]
|
||||||
|
case .iPhone15Pro:
|
||||||
|
return ["iPhone16,1"]
|
||||||
|
case .iPhone15ProMax:
|
||||||
|
return ["iPhone16,2"]
|
||||||
|
case let .unknown(modelId):
|
||||||
|
return [modelId]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var modelName: String {
|
||||||
|
switch self {
|
||||||
|
case .iPodTouch1:
|
||||||
|
return "iPod touch 1G"
|
||||||
|
case .iPodTouch2:
|
||||||
|
return "iPod touch 2G"
|
||||||
|
case .iPodTouch3:
|
||||||
|
return "iPod touch 3G"
|
||||||
|
case .iPodTouch4:
|
||||||
|
return "iPod touch 4G"
|
||||||
|
case .iPodTouch5:
|
||||||
|
return "iPod touch 5G"
|
||||||
|
case .iPodTouch6:
|
||||||
|
return "iPod touch 6G"
|
||||||
|
case .iPodTouch7:
|
||||||
|
return "iPod touch 7G"
|
||||||
|
case .iPhone:
|
||||||
|
return "iPhone"
|
||||||
|
case .iPhone3G:
|
||||||
|
return "iPhone 3G"
|
||||||
|
case .iPhone3GS:
|
||||||
|
return "iPhone 3GS"
|
||||||
|
case .iPhone4:
|
||||||
|
return "iPhone 4"
|
||||||
|
case .iPhone4S:
|
||||||
|
return "iPhone 4S"
|
||||||
|
case .iPhone5:
|
||||||
|
return "iPhone 5"
|
||||||
|
case .iPhone5C:
|
||||||
|
return "iPhone 5C"
|
||||||
|
case .iPhone5S:
|
||||||
|
return "iPhone 5S"
|
||||||
|
case .iPhone6:
|
||||||
|
return "iPhone 6"
|
||||||
|
case .iPhone6Plus:
|
||||||
|
return "iPhone 6 Plus"
|
||||||
|
case .iPhone6S:
|
||||||
|
return "iPhone 6S"
|
||||||
|
case .iPhone6SPlus:
|
||||||
|
return "iPhone 6S Plus"
|
||||||
|
case .iPhoneSE:
|
||||||
|
return "iPhone SE"
|
||||||
|
case .iPhone7:
|
||||||
|
return "iPhone 7"
|
||||||
|
case .iPhone7Plus:
|
||||||
|
return "iPhone 7 Plus"
|
||||||
|
case .iPhone8:
|
||||||
|
return "iPhone 8"
|
||||||
|
case .iPhone8Plus:
|
||||||
|
return "iPhone 8 Plus"
|
||||||
|
case .iPhoneX:
|
||||||
|
return "iPhone X"
|
||||||
|
case .iPhoneXS:
|
||||||
|
return "iPhone XS"
|
||||||
|
case .iPhoneXSMax:
|
||||||
|
return "iPhone XS Max"
|
||||||
|
case .iPhoneXR:
|
||||||
|
return "iPhone XR"
|
||||||
|
case .iPhone11:
|
||||||
|
return "iPhone 11"
|
||||||
|
case .iPhone11Pro:
|
||||||
|
return "iPhone 11 Pro"
|
||||||
|
case .iPhone11ProMax:
|
||||||
|
return "iPhone 11 Pro Max"
|
||||||
|
case .iPhoneSE2ndGen:
|
||||||
|
return "iPhone SE (2nd gen)"
|
||||||
|
case .iPhone12:
|
||||||
|
return "iPhone 12"
|
||||||
|
case .iPhone12Mini:
|
||||||
|
return "iPhone 12 mini"
|
||||||
|
case .iPhone12Pro:
|
||||||
|
return "iPhone 12 Pro"
|
||||||
|
case .iPhone12ProMax:
|
||||||
|
return "iPhone 12 Pro Max"
|
||||||
|
case .iPhone13:
|
||||||
|
return "iPhone 13"
|
||||||
|
case .iPhone13Mini:
|
||||||
|
return "iPhone 13 mini"
|
||||||
|
case .iPhone13Pro:
|
||||||
|
return "iPhone 13 Pro"
|
||||||
|
case .iPhone13ProMax:
|
||||||
|
return "iPhone 13 Pro Max"
|
||||||
|
case .iPhoneSE3rdGen:
|
||||||
|
return "iPhone SE (3rd gen)"
|
||||||
|
case .iPhone14:
|
||||||
|
return "iPhone 14"
|
||||||
|
case .iPhone14Plus:
|
||||||
|
return "iPhone 14 Plus"
|
||||||
|
case .iPhone14Pro:
|
||||||
|
return "iPhone 14 Pro"
|
||||||
|
case .iPhone14ProMax:
|
||||||
|
return "iPhone 14 Pro Max"
|
||||||
|
case .iPhone15:
|
||||||
|
return "iPhone 15"
|
||||||
|
case .iPhone15Plus:
|
||||||
|
return "iPhone 15 Plus"
|
||||||
|
case .iPhone15Pro:
|
||||||
|
return "iPhone 15 Pro"
|
||||||
|
case .iPhone15ProMax:
|
||||||
|
return "iPhone 15 Pro Max"
|
||||||
|
case let .unknown(modelId):
|
||||||
|
if modelId.hasPrefix("iPhone") {
|
||||||
|
return "Unknown iPhone"
|
||||||
|
} else if modelId.hasPrefix("iPod") {
|
||||||
|
return "Unknown iPod"
|
||||||
|
} else if modelId.hasPrefix("iPad") {
|
||||||
|
return "Unknown iPad"
|
||||||
|
} else {
|
||||||
|
return "Unknown Device"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public var isIpad: Bool {
|
||||||
|
return self.modelId.first?.hasPrefix("iPad") ?? false
|
||||||
|
}
|
||||||
|
|
||||||
|
public static let current = DeviceModel()
|
||||||
|
|
||||||
|
private init() {
|
||||||
|
var systemInfo = utsname()
|
||||||
|
uname(&systemInfo)
|
||||||
|
let modelCode = withUnsafePointer(to: &systemInfo.machine) {
|
||||||
|
$0.withMemoryRebound(to: CChar.self, capacity: 1) {
|
||||||
|
ptr in String.init(validatingUTF8: ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var result: DeviceModel?
|
||||||
|
if let modelCode {
|
||||||
|
for model in DeviceModel.allCases {
|
||||||
|
if model.modelId.contains(modelCode) {
|
||||||
|
result = model
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if let result {
|
||||||
|
self = result
|
||||||
|
} else {
|
||||||
|
self = .unknown(modelCode ?? "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user