mirror of
https://github.com/yattee/yattee.git
synced 2025-11-24 10:18:16 +00:00
In fullscreen playback, swipe-down and timeline seek gestures now respect a 60pt safe zone at the top of the screen, allowing the system notification center gesture to work without triggering app gestures.
193 lines
4.0 KiB
Swift
193 lines
4.0 KiB
Swift
import Defaults
|
|
import Foundation
|
|
import SwiftUI
|
|
|
|
enum Constants {
|
|
static let overlayAnimation = Animation.linear(duration: 0.2)
|
|
static let aspectRatio16x9 = 16.0 / 9.0
|
|
static let aspectRatio4x3 = 4.0 / 3.0
|
|
static let notificationCenterZoneHeight: Double = 60
|
|
|
|
static var isAppleTV: Bool {
|
|
#if os(iOS)
|
|
UIDevice.current.userInterfaceIdiom == .tv
|
|
#else
|
|
false
|
|
#endif
|
|
}
|
|
|
|
static var isMac: Bool {
|
|
#if os(iOS)
|
|
UIDevice.current.userInterfaceIdiom == .mac
|
|
#else
|
|
false
|
|
#endif
|
|
}
|
|
|
|
static var isIPhone: Bool {
|
|
#if os(iOS)
|
|
UIDevice.current.userInterfaceIdiom == .phone
|
|
#else
|
|
false
|
|
#endif
|
|
}
|
|
|
|
static var isIPad: Bool {
|
|
#if os(iOS)
|
|
UIDevice.current.userInterfaceIdiom == .pad
|
|
#else
|
|
false
|
|
#endif
|
|
}
|
|
|
|
static var isWindowFullscreen: Bool {
|
|
#if os(iOS)
|
|
guard let windowScene = UIApplication.shared.connectedScenes
|
|
.filter({ $0.activationState == .foregroundActive })
|
|
.compactMap({ $0 as? UIWindowScene })
|
|
.first,
|
|
let window = windowScene.windows.first
|
|
else {
|
|
return false
|
|
}
|
|
|
|
let screenBounds = windowScene.screen.bounds
|
|
let windowBounds = window.frame
|
|
|
|
// Check if window size matches screen bounds (accounting for small differences)
|
|
return abs(windowBounds.width - screenBounds.width) < 1 &&
|
|
abs(windowBounds.height - screenBounds.height) < 1
|
|
#else
|
|
return false
|
|
#endif
|
|
}
|
|
|
|
static var iPadSystemControlsWidth: Double {
|
|
50
|
|
}
|
|
|
|
static var isTvOS: Bool {
|
|
#if os(tvOS)
|
|
true
|
|
#else
|
|
false
|
|
#endif
|
|
}
|
|
|
|
static var isMacOS: Bool {
|
|
#if os(macOS)
|
|
true
|
|
#else
|
|
false
|
|
#endif
|
|
}
|
|
|
|
static var isIOS: Bool {
|
|
#if os(iOS)
|
|
true
|
|
#else
|
|
false
|
|
#endif
|
|
}
|
|
|
|
static var detailsVisibility: Bool {
|
|
#if os(iOS)
|
|
false
|
|
#else
|
|
true
|
|
#endif
|
|
}
|
|
|
|
static var progressViewScale: Double {
|
|
#if os(macOS)
|
|
0.4
|
|
#else
|
|
0.6
|
|
#endif
|
|
}
|
|
|
|
static var channelThumbnailSize: Double {
|
|
#if os(tvOS)
|
|
50
|
|
#else
|
|
30
|
|
#endif
|
|
}
|
|
|
|
static var sidebarChannelThumbnailSize: Double {
|
|
#if os(macOS)
|
|
20
|
|
#else
|
|
30
|
|
#endif
|
|
}
|
|
|
|
static var channelDetailsStackSpacing: Double {
|
|
#if os(tvOS)
|
|
12
|
|
#else
|
|
6
|
|
#endif
|
|
}
|
|
|
|
static var contentViewMinWidth: Double {
|
|
#if os(macOS)
|
|
835
|
|
#else
|
|
0
|
|
#endif
|
|
}
|
|
|
|
static var deviceName: String {
|
|
#if os(macOS)
|
|
Host().localizedName ?? "Mac"
|
|
#else
|
|
UIDevice.current.name
|
|
#endif
|
|
}
|
|
|
|
static var platform: String {
|
|
#if os(macOS)
|
|
"macOS"
|
|
#elseif os(iOS)
|
|
"iOS"
|
|
#elseif os(tvOS)
|
|
"tvOS"
|
|
#else
|
|
"unknown"
|
|
#endif
|
|
}
|
|
|
|
static var defaultNavigationStyle: NavigationStyle {
|
|
#if os(macOS)
|
|
return .sidebar
|
|
#elseif os(iOS)
|
|
if isIPad {
|
|
return .sidebar
|
|
}
|
|
return .tab
|
|
#else
|
|
return .tab
|
|
#endif
|
|
}
|
|
|
|
static func seekIcon(_ type: String, _ interval: TimeInterval) -> String {
|
|
let interval = Int(interval)
|
|
let allVersions = [10, 15, 30, 45, 60, 75, 90]
|
|
let iOS15 = [5]
|
|
let iconName = "go\(type).\(interval)"
|
|
|
|
if iOS15.contains(interval) {
|
|
return iconName
|
|
}
|
|
|
|
if allVersions.contains(interval) {
|
|
return iconName
|
|
}
|
|
|
|
let sign = type == "forward" ? "plus" : "minus"
|
|
|
|
return "go\(type).\(sign)"
|
|
}
|
|
}
|