mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 13:33:42 +00:00
Animations improvements
This commit is contained in:
parent
5f50797b54
commit
08ed810b9e
@ -116,7 +116,7 @@ final class NavigationModel: ObservableObject {
|
|||||||
if presentingPlayer { delay = 1.0 }
|
if presentingPlayer { delay = 1.0 }
|
||||||
#endif
|
#endif
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
|
||||||
withAnimation(.linear(duration: 0.3)) {
|
withAnimation(Constants.overlayAnimation) {
|
||||||
navigation.presentingChannel = true
|
navigation.presentingChannel = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,7 +156,7 @@ final class NavigationModel: ObservableObject {
|
|||||||
if presentingPlayer { delay = 1.0 }
|
if presentingPlayer { delay = 1.0 }
|
||||||
#endif
|
#endif
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
|
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
|
||||||
withAnimation(.linear(duration: 0.3)) {
|
withAnimation(Constants.overlayAnimation) {
|
||||||
navigation.presentingPlaylist = true
|
navigation.presentingPlaylist = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import SwiftUI
|
|||||||
|
|
||||||
final class MPVBackend: PlayerBackend {
|
final class MPVBackend: PlayerBackend {
|
||||||
static var controlsUpdateInterval = 0.5
|
static var controlsUpdateInterval = 0.5
|
||||||
static var networkStateUpdateInterval = 0.3
|
static var networkStateUpdateInterval = 1.0
|
||||||
|
|
||||||
private var logger = Logger(label: "mpv-backend")
|
private var logger = Logger(label: "mpv-backend")
|
||||||
|
|
||||||
|
@ -225,15 +225,13 @@ final class PlayerModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
navigation.hideKeyboard()
|
#if os(iOS)
|
||||||
|
Delay.by(0.5) {
|
||||||
if !presentingPlayer {
|
self.navigation.hideKeyboard()
|
||||||
DispatchQueue.main.async { [weak self] in
|
|
||||||
withAnimation(.linear(duration: 0.25)) {
|
|
||||||
self?.presentingPlayer = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
#endif
|
||||||
|
|
||||||
|
if !presentingPlayer { presentingPlayer = true }
|
||||||
|
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
Windows.player.open()
|
Windows.player.open()
|
||||||
@ -241,13 +239,17 @@ final class PlayerModel: ObservableObject {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
func hide() {
|
func hide(animate: Bool = true) {
|
||||||
withAnimation(.linear(duration: 0.25)) {
|
if animate {
|
||||||
|
withAnimation(.easeOut(duration: 0.2)) {
|
||||||
|
presentingPlayer = false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
presentingPlayer = false
|
presentingPlayer = false
|
||||||
}
|
}
|
||||||
|
|
||||||
DispatchQueue.main.async { [weak self] in
|
DispatchQueue.main.async { [weak self] in
|
||||||
self?.playingFullScreen = false
|
self?.exitFullScreen(showControls: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@ -591,9 +593,7 @@ final class PlayerModel: ObservableObject {
|
|||||||
exitFullScreen()
|
exitFullScreen()
|
||||||
|
|
||||||
#if !os(macOS)
|
#if !os(macOS)
|
||||||
if closePlayerOnItemClose {
|
if closePlayerOnItemClose { Delay.by(0.2) { self.hide() } }
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in self?.hide() }
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
6
Shared/Constants.swift
Normal file
6
Shared/Constants.swift
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct Constants {
|
||||||
|
static let overlayAnimation = Animation.linear(duration: 0.2)
|
||||||
|
}
|
7
Shared/Delay.swift
Normal file
7
Shared/Delay.swift
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct Delay {
|
||||||
|
@discardableResult static func by(_ interval: TimeInterval, block: @escaping () -> Void) -> Timer {
|
||||||
|
Timer.scheduledTimer(withTimeInterval: interval, repeats: false) { _ in block() }
|
||||||
|
}
|
||||||
|
}
|
51
Shared/Modifiers/AnimationCompletionObserverModifier.swift
Normal file
51
Shared/Modifiers/AnimationCompletionObserverModifier.swift
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import Foundation
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
/// An animatable modifier that is used for observing animations for a given animatable value.
|
||||||
|
struct AnimationCompletionObserverModifier<Value>: AnimatableModifier where Value: VectorArithmetic {
|
||||||
|
/// While animating, SwiftUI changes the old input value to the new target value using this property. This value is set to the old value until the animation completes.
|
||||||
|
var animatableData: Value {
|
||||||
|
didSet {
|
||||||
|
notifyCompletionIfFinished()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The target value for which we're observing. This value is directly set once the animation starts. During animation, `animatableData` will hold the oldValue and is only updated to the target value once the animation completes.
|
||||||
|
private var targetValue: Value
|
||||||
|
|
||||||
|
/// The completion callback which is called once the animation completes.
|
||||||
|
private var completion: () -> Void
|
||||||
|
|
||||||
|
init(observedValue: Value, completion: @escaping () -> Void) {
|
||||||
|
self.completion = completion
|
||||||
|
animatableData = observedValue
|
||||||
|
targetValue = observedValue
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Verifies whether the current animation is finished and calls the completion callback if true.
|
||||||
|
private func notifyCompletionIfFinished() {
|
||||||
|
guard animatableData == targetValue else { return }
|
||||||
|
|
||||||
|
/// Dispatching is needed to take the next runloop for the completion callback.
|
||||||
|
/// This prevents errors like "Modifying state during view update, this will cause undefined behavior."
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.completion()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
/// We're not really modifying the view so we can directly return the original input value.
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension View {
|
||||||
|
/// Calls the completion handler whenever an animation on the given value completes.
|
||||||
|
/// - Parameters:
|
||||||
|
/// - value: The value to observe for animations.
|
||||||
|
/// - completion: The completion callback to call once the animation completes.
|
||||||
|
/// - Returns: A modified `View` instance with the observer attached.
|
||||||
|
func onAnimationCompleted<Value: VectorArithmetic>(for value: Value, completion: @escaping () -> Void) -> ModifiedContent<Self, AnimationCompletionObserverModifier<Value>> {
|
||||||
|
modifier(AnimationCompletionObserverModifier(observedValue: value, completion: completion))
|
||||||
|
}
|
||||||
|
}
|
@ -157,6 +157,7 @@ struct AppTabNavigation: View {
|
|||||||
.environmentObject(subscriptions)
|
.environmentObject(subscriptions)
|
||||||
.environmentObject(thumbnailsModel)
|
.environmentObject(thumbnailsModel)
|
||||||
.id("channelVideos")
|
.id("channelVideos")
|
||||||
|
.zIndex(player.presentingPlayer ? -1 : 2)
|
||||||
.transition(.move(edge: .bottom))
|
.transition(.move(edge: .bottom))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,6 +172,7 @@ struct AppTabNavigation: View {
|
|||||||
.environmentObject(subscriptions)
|
.environmentObject(subscriptions)
|
||||||
.environmentObject(thumbnailsModel)
|
.environmentObject(thumbnailsModel)
|
||||||
.id("channelPlaylist")
|
.id("channelPlaylist")
|
||||||
|
.zIndex(player.presentingPlayer ? -1 : 1)
|
||||||
.transition(.move(edge: .bottom))
|
.transition(.move(edge: .bottom))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,8 @@ struct ContentView: View {
|
|||||||
@ViewBuilder var videoPlayer: some View {
|
@ViewBuilder var videoPlayer: some View {
|
||||||
if player.presentingPlayer {
|
if player.presentingPlayer {
|
||||||
playerView
|
playerView
|
||||||
.transition(.move(edge: .bottom))
|
.transition(.asymmetric(insertion: .identity, removal: .move(edge: .bottom)))
|
||||||
|
.zIndex(3)
|
||||||
} else if player.activeBackend == .appleAVPlayer {
|
} else if player.activeBackend == .appleAVPlayer {
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
playerView.offset(y: UIScreen.main.bounds.height)
|
playerView.offset(y: UIScreen.main.bounds.height)
|
||||||
|
@ -12,7 +12,7 @@ import Foundation
|
|||||||
wantsLayer = true
|
wantsLayer = true
|
||||||
}}
|
}}
|
||||||
|
|
||||||
override init(frame frameRect: NSRect) {
|
override init(frame frameRect: CGRect) {
|
||||||
super.init(frame: frameRect)
|
super.init(frame: frameRect)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import SwiftUI
|
|||||||
struct PlayerQueueView: View {
|
struct PlayerQueueView: View {
|
||||||
var sidebarQueue: Bool
|
var sidebarQueue: Bool
|
||||||
@Binding var fullScreen: Bool
|
@Binding var fullScreen: Bool
|
||||||
|
@State private var relatedVisible = false
|
||||||
|
|
||||||
@FetchRequest(sortDescriptors: [.init(key: "watchedAt", ascending: false)])
|
@FetchRequest(sortDescriptors: [.init(key: "watchedAt", ascending: false)])
|
||||||
var watches: FetchedResults<Watch>
|
var watches: FetchedResults<Watch>
|
||||||
@ -24,7 +25,7 @@ struct PlayerQueueView: View {
|
|||||||
autoplaying
|
autoplaying
|
||||||
}
|
}
|
||||||
playingNext
|
playingNext
|
||||||
if sidebarQueue {
|
if sidebarQueue, relatedVisible {
|
||||||
related
|
related
|
||||||
}
|
}
|
||||||
if saveHistory, showHistoryInPlayer {
|
if saveHistory, showHistoryInPlayer {
|
||||||
@ -37,7 +38,15 @@ struct PlayerQueueView: View {
|
|||||||
.listRowInsets(EdgeInsets())
|
.listRowInsets(EdgeInsets())
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
.onChange(of: player.currentItem) { _ in
|
||||||
|
relatedVisible = false
|
||||||
|
|
||||||
|
Delay.by(2) {
|
||||||
|
withAnimation(.easeIn(duration: 0.25)) {
|
||||||
|
self.relatedVisible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#if os(macOS)
|
#if os(macOS)
|
||||||
.listStyle(.inset)
|
.listStyle(.inset)
|
||||||
#elseif os(iOS)
|
#elseif os(iOS)
|
||||||
@ -131,18 +140,18 @@ struct PlayerQueueView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private var related: some View {
|
@ViewBuilder private var related: some View {
|
||||||
Group {
|
if let related = player.currentVideo?.related, !related.isEmpty {
|
||||||
if !player.currentVideo.isNil, !player.currentVideo!.related.isEmpty {
|
Section(header: Text("Related")) {
|
||||||
Section(header: Text("Related")) {
|
ForEach(related) { video in
|
||||||
ForEach(player.currentVideo!.related) { video in
|
PlayerQueueRow(item: PlayerQueueItem(video), fullScreen: $fullScreen)
|
||||||
PlayerQueueRow(item: PlayerQueueItem(video), fullScreen: $fullScreen)
|
.contextMenu {
|
||||||
.contextMenu {
|
VideoContextMenuView(video: video)
|
||||||
VideoContextMenuView(video: video)
|
}
|
||||||
}
|
.id(video.videoID)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.transaction { t in t.disablesAnimations = true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,13 +124,14 @@ struct VideoDescription: View {
|
|||||||
components.scheme = "yattee"
|
components.scheme = "yattee"
|
||||||
if let yatteeURL = components.url {
|
if let yatteeURL = components.url {
|
||||||
let parser = URLParser(url: urlToOpen)
|
let parser = URLParser(url: urlToOpen)
|
||||||
if parser.destination == .video,
|
let destination = parser.destination
|
||||||
|
if destination == .video,
|
||||||
parser.videoID == player.currentVideo?.videoID,
|
parser.videoID == player.currentVideo?.videoID,
|
||||||
let time = parser.time
|
let time = parser.time
|
||||||
{
|
{
|
||||||
player.backend.seek(to: Double(time))
|
player.backend.seek(to: Double(time))
|
||||||
return
|
return
|
||||||
} else {
|
} else if destination != nil {
|
||||||
urlToOpen = yatteeURL
|
urlToOpen = yatteeURL
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,11 +89,13 @@ struct VideoDetails: View {
|
|||||||
VStack {}
|
VStack {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.onPageWillChange { pageIndex in
|
.onPageWillChange { pageIndex in
|
||||||
if pageIndex == DetailsPage.comments.index {
|
if pageIndex == DetailsPage.comments.index {
|
||||||
comments.load()
|
comments.load()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.frame(maxWidth: detailsSize.width)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
page.update(.moveToFirst)
|
page.update(.moveToFirst)
|
||||||
@ -209,38 +211,36 @@ struct VideoDetails: View {
|
|||||||
@State private var detailsSize = CGSize.zero
|
@State private var detailsSize = CGSize.zero
|
||||||
|
|
||||||
var detailsPage: some View {
|
var detailsPage: some View {
|
||||||
Group {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
if let video = video {
|
||||||
if let video = video {
|
VStack(spacing: 6) {
|
||||||
VStack(spacing: 6) {
|
videoProperties
|
||||||
videoProperties
|
|
||||||
|
|
||||||
Divider()
|
Divider()
|
||||||
}
|
}
|
||||||
.padding(.bottom, 6)
|
.padding(.bottom, 6)
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 10) {
|
VStack(alignment: .leading, spacing: 10) {
|
||||||
if !player.videoBeingOpened.isNil && (video.description.isNil || video.description!.isEmpty) {
|
if !player.videoBeingOpened.isNil && (video.description.isNil || video.description!.isEmpty) {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
ForEach(1 ... Int.random(in: 2 ... 5), id: \.self) { _ in
|
ForEach(1 ... Int.random(in: 2 ... 5), id: \.self) { _ in
|
||||||
Text(String(repeating: Video.fixture.description ?? "", count: Int.random(in: 1 ... 4)))
|
Text(String(repeating: Video.fixture.description ?? "", count: Int.random(in: 1 ... 4)))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.redacted(reason: .placeholder)
|
|
||||||
} else if video.description != nil, !video.description!.isEmpty {
|
|
||||||
VideoDescription(video: video, detailsSize: detailsSize)
|
|
||||||
#if os(iOS)
|
|
||||||
.padding(.bottom, fullScreenLayout ? 10 : SafeArea.insets.bottom)
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
Text("No description")
|
|
||||||
.foregroundColor(.secondary)
|
|
||||||
}
|
}
|
||||||
|
.redacted(reason: .placeholder)
|
||||||
|
} else if video.description != nil, !video.description!.isEmpty {
|
||||||
|
VideoDescription(video: video, detailsSize: detailsSize)
|
||||||
|
#if os(iOS)
|
||||||
|
.padding(.bottom, fullScreenLayout ? 10 : SafeArea.insets.bottom)
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
Text("No description")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.horizontal)
|
|
||||||
}
|
}
|
||||||
|
.padding(.horizontal)
|
||||||
}
|
}
|
||||||
|
|
||||||
var fullScreenLayout: Bool {
|
var fullScreenLayout: Bool {
|
||||||
|
@ -8,7 +8,7 @@ import SwiftUI
|
|||||||
|
|
||||||
struct VideoPlayerView: View {
|
struct VideoPlayerView: View {
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
static let hiddenOffset = YatteeApp.isForPreviews ? 0 : max(UIScreen.main.bounds.height, UIScreen.main.bounds.width) + 100
|
static let hiddenOffset = UIScreen.main.bounds.height
|
||||||
static let defaultSidebarQueueValue = UIScreen.main.bounds.width > 900 && Defaults[.playerSidebar] == .whenFits
|
static let defaultSidebarQueueValue = UIScreen.main.bounds.width > 900 && Defaults[.playerSidebar] == .whenFits
|
||||||
#else
|
#else
|
||||||
static let defaultSidebarQueueValue = Defaults[.playerSidebar] != .never
|
static let defaultSidebarQueueValue = Defaults[.playerSidebar] != .never
|
||||||
@ -45,7 +45,7 @@ struct VideoPlayerView: View {
|
|||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@GestureState private var dragGestureState = false
|
@GestureState private var dragGestureState = false
|
||||||
@GestureState private var dragGestureOffset = CGSize.zero
|
@GestureState private var dragGestureOffset = CGSize.zero
|
||||||
@State private var viewDragOffset = 0.0
|
@State private var viewDragOffset = Self.hiddenOffset
|
||||||
@State private var orientationObserver: Any?
|
@State private var orientationObserver: Any?
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -102,6 +102,7 @@ struct VideoPlayerView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.animation(nil, value: player.playerSize)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
if player.musicMode {
|
if player.musicMode {
|
||||||
player.backend.startControlsUpdates()
|
player.backend.startControlsUpdates()
|
||||||
@ -145,25 +146,20 @@ struct VideoPlayerView: View {
|
|||||||
playerSize = geometry.size
|
playerSize = geometry.size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if os(iOS)
|
|
||||||
.frame(width: playerWidth.isNil ? nil : Double(playerWidth!), height: playerHeight.isNil ? nil : Double(playerHeight!))
|
|
||||||
.ignoresSafeArea(.all, edges: playerEdgesIgnoringSafeArea)
|
|
||||||
#endif
|
|
||||||
.onChange(of: geometry.size) { size in
|
.onChange(of: geometry.size) { size in
|
||||||
self.playerSize = size
|
self.playerSize = size
|
||||||
}
|
}
|
||||||
.onChange(of: fullScreenDetails) { value in
|
.onChange(of: fullScreenDetails) { value in
|
||||||
player.backend.setNeedsDrawing(!value)
|
player.backend.setNeedsDrawing(!value)
|
||||||
}
|
}
|
||||||
|
#if os(iOS)
|
||||||
|
.frame(width: playerWidth.isNil ? nil : Double(playerWidth!), height: playerHeight.isNil ? nil : Double(playerHeight!))
|
||||||
|
.ignoresSafeArea(.all, edges: playerEdgesIgnoringSafeArea)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
#if os(iOS)
|
viewDragOffset = 0
|
||||||
viewDragOffset = 0.0
|
|
||||||
configureOrientationUpdatesBasedOnAccelerometer()
|
|
||||||
|
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak player] in
|
Delay.by(0.2) {
|
||||||
player?.onPresentPlayer?()
|
configureOrientationUpdatesBasedOnAccelerometer()
|
||||||
player?.onPresentPlayer = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if let orientationMask = player.lockedOrientation {
|
if let orientationMask = player.lockedOrientation {
|
||||||
Orientation.lockOrientation(
|
Orientation.lockOrientation(
|
||||||
@ -171,27 +167,37 @@ struct VideoPlayerView: View {
|
|||||||
andRotateTo: orientationMask == .landscapeLeft ? .landscapeLeft : orientationMask == .landscapeRight ? .landscapeRight : .portrait
|
andRotateTo: orientationMask == .landscapeLeft ? .landscapeLeft : orientationMask == .landscapeRight ? .landscapeRight : .portrait
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
.onDisappear {
|
.onDisappear {
|
||||||
#if os(iOS)
|
if Defaults[.lockPortraitWhenBrowsing] {
|
||||||
if Defaults[.lockPortraitWhenBrowsing] {
|
Orientation.lockOrientation(.portrait, andRotateTo: .portrait)
|
||||||
Orientation.lockOrientation(.portrait, andRotateTo: .portrait)
|
} else {
|
||||||
} else {
|
Orientation.lockOrientation(.allButUpsideDown)
|
||||||
Orientation.lockOrientation(.allButUpsideDown)
|
}
|
||||||
}
|
stopOrientationUpdates()
|
||||||
stopOrientationUpdates()
|
playerControls.hideOverlays()
|
||||||
playerControls.hideOverlays()
|
|
||||||
|
|
||||||
player.lockedOrientation = nil
|
player.lockedOrientation = nil
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
.onAnimationCompleted(for: viewDragOffset) {
|
||||||
|
guard !dragGestureState else { return }
|
||||||
|
if viewDragOffset == 0 {
|
||||||
|
player.onPresentPlayer?()
|
||||||
|
player.onPresentPlayer = nil
|
||||||
|
} else if viewDragOffset == Self.hiddenOffset {
|
||||||
|
player.hide(animate: false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
.compositingGroup()
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
.offset(y: playerOffset)
|
.offset(y: playerOffset)
|
||||||
.animation(.linear(duration: 0.2), value: playerOffset)
|
.animation(dragGestureState ? .interactiveSpring(response: 0.05) : .easeOut(duration: 0.2), value: playerOffset)
|
||||||
.backport
|
.backport
|
||||||
.persistentSystemOverlays(!fullScreenLayout)
|
.persistentSystemOverlays(!fullScreenLayout)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -276,11 +282,6 @@ struct VideoPlayerView: View {
|
|||||||
}
|
}
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
.gesture(playerControls.presentingOverlays ? nil : playerDragGesture)
|
.gesture(playerControls.presentingOverlays ? nil : playerDragGesture)
|
||||||
.onChange(of: dragGestureState) { _ in
|
|
||||||
if !dragGestureState {
|
|
||||||
onPlayerDragGestureEnded()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#elseif os(macOS)
|
#elseif os(macOS)
|
||||||
.onAppear(perform: {
|
.onAppear(perform: {
|
||||||
NSEvent.addLocalMonitorForEvents(matching: [.mouseMoved]) {
|
NSEvent.addLocalMonitorForEvents(matching: [.mouseMoved]) {
|
||||||
@ -302,7 +303,6 @@ struct VideoPlayerView: View {
|
|||||||
VideoDetails(sidebarQueue: sidebarQueue, fullScreen: $fullScreenDetails)
|
VideoDetails(sidebarQueue: sidebarQueue, fullScreen: $fullScreenDetails)
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
.ignoresSafeArea(.all, edges: .bottom)
|
.ignoresSafeArea(.all, edges: .bottom)
|
||||||
.transition(.move(edge: .bottom))
|
|
||||||
#endif
|
#endif
|
||||||
.background(colorScheme == .dark ? Color.black : Color.white)
|
.background(colorScheme == .dark ? Color.black : Color.white)
|
||||||
.modifier(VideoDetailsPaddingModifier(
|
.modifier(VideoDetailsPaddingModifier(
|
||||||
@ -412,7 +412,9 @@ struct VideoPlayerView: View {
|
|||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
Button {
|
Button {
|
||||||
player.hide()
|
withAnimation(.spring(response: 0.3, dampingFraction: 0, blendDuration: 0)) {
|
||||||
|
viewDragOffset = Self.hiddenOffset
|
||||||
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Image(systemName: "xmark")
|
Image(systemName: "xmark")
|
||||||
.font(.system(size: 40))
|
.font(.system(size: 40))
|
||||||
@ -474,16 +476,11 @@ struct VideoPlayerView: View {
|
|||||||
!playerControls.presentingControlsOverlay else { return }
|
!playerControls.presentingControlsOverlay else { return }
|
||||||
|
|
||||||
if viewDragOffset > 100 {
|
if viewDragOffset > 100 {
|
||||||
player.hide()
|
withAnimation(Constants.overlayAnimation) {
|
||||||
|
viewDragOffset = Self.hiddenOffset
|
||||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) {
|
|
||||||
player.backend.setNeedsDrawing(false)
|
|
||||||
player.exitFullScreen()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
viewDragOffset = Self.hiddenOffset
|
|
||||||
} else {
|
} else {
|
||||||
withAnimation(.linear(duration: 0.2)) {
|
withAnimation(Constants.overlayAnimation) {
|
||||||
viewDragOffset = 0
|
viewDragOffset = 0
|
||||||
}
|
}
|
||||||
player.backend.setNeedsDrawing(true)
|
player.backend.setNeedsDrawing(true)
|
||||||
@ -502,6 +499,8 @@ struct VideoPlayerView: View {
|
|||||||
!player.playingFullScreen,
|
!player.playingFullScreen,
|
||||||
!player.playingInPictureInPicture
|
!player.playingInPictureInPicture
|
||||||
{
|
{
|
||||||
|
guard player.presentingPlayer else { return }
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
playerControls.presentingControls = false
|
playerControls.presentingControls = false
|
||||||
player.enterFullScreen(showControls: false)
|
player.enterFullScreen(showControls: false)
|
||||||
@ -532,7 +531,9 @@ struct VideoPlayerView: View {
|
|||||||
lastOrientation = orientation
|
lastOrientation = orientation
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
guard Defaults[.enterFullscreenInLandscape] else {
|
guard Defaults[.enterFullscreenInLandscape],
|
||||||
|
player.presentingPlayer
|
||||||
|
else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -45,6 +45,6 @@ struct MultiselectRow: View {
|
|||||||
|
|
||||||
struct MultiselectRow_Previews: PreviewProvider {
|
struct MultiselectRow_Previews: PreviewProvider {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
MultiselectRow(title: "Title", selected: false, action: { _ in })
|
MultiselectRow(title: "Title", selected: false) { _ in }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ struct ChannelPlaylistView: View {
|
|||||||
ToolbarItem(placement: .navigation) {
|
ToolbarItem(placement: .navigation) {
|
||||||
if navigationStyle == .tab {
|
if navigationStyle == .tab {
|
||||||
Button("Done") {
|
Button("Done") {
|
||||||
withAnimation {
|
withAnimation(Constants.overlayAnimation) {
|
||||||
navigation.presentingPlaylist = false
|
navigation.presentingPlaylist = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ struct ChannelVideosView: View {
|
|||||||
ToolbarItem(placement: .navigation) {
|
ToolbarItem(placement: .navigation) {
|
||||||
if navigationStyle == .tab {
|
if navigationStyle == .tab {
|
||||||
Button("Done") {
|
Button("Done") {
|
||||||
withAnimation {
|
withAnimation(Constants.overlayAnimation) {
|
||||||
navigation.presentingChannel = false
|
navigation.presentingChannel = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,6 +318,9 @@
|
|||||||
3752069D285E910600CA655F /* ChapterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3752069C285E910600CA655F /* ChapterView.swift */; };
|
3752069D285E910600CA655F /* ChapterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3752069C285E910600CA655F /* ChapterView.swift */; };
|
||||||
3752069E285E910600CA655F /* ChapterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3752069C285E910600CA655F /* ChapterView.swift */; };
|
3752069E285E910600CA655F /* ChapterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3752069C285E910600CA655F /* ChapterView.swift */; };
|
||||||
3752069F285E910600CA655F /* ChapterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3752069C285E910600CA655F /* ChapterView.swift */; };
|
3752069F285E910600CA655F /* ChapterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3752069C285E910600CA655F /* ChapterView.swift */; };
|
||||||
|
3754B01528B7F84D009717C8 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3754B01428B7F84D009717C8 /* Constants.swift */; };
|
||||||
|
3754B01628B7F84D009717C8 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3754B01428B7F84D009717C8 /* Constants.swift */; };
|
||||||
|
3754B01728B7F84D009717C8 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3754B01428B7F84D009717C8 /* Constants.swift */; };
|
||||||
3756C2A62861131100E4B059 /* NetworkState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3756C2A52861131100E4B059 /* NetworkState.swift */; };
|
3756C2A62861131100E4B059 /* NetworkState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3756C2A52861131100E4B059 /* NetworkState.swift */; };
|
||||||
3756C2A72861131100E4B059 /* NetworkState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3756C2A52861131100E4B059 /* NetworkState.swift */; };
|
3756C2A72861131100E4B059 /* NetworkState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3756C2A52861131100E4B059 /* NetworkState.swift */; };
|
||||||
3756C2A82861131100E4B059 /* NetworkState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3756C2A52861131100E4B059 /* NetworkState.swift */; };
|
3756C2A82861131100E4B059 /* NetworkState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3756C2A52861131100E4B059 /* NetworkState.swift */; };
|
||||||
@ -691,6 +694,12 @@
|
|||||||
37CFB48528AFE2510070024C /* VideoDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CFB48428AFE2510070024C /* VideoDescription.swift */; };
|
37CFB48528AFE2510070024C /* VideoDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CFB48428AFE2510070024C /* VideoDescription.swift */; };
|
||||||
37CFB48628AFE2510070024C /* VideoDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CFB48428AFE2510070024C /* VideoDescription.swift */; };
|
37CFB48628AFE2510070024C /* VideoDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CFB48428AFE2510070024C /* VideoDescription.swift */; };
|
||||||
37CFB48728AFE2510070024C /* VideoDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CFB48428AFE2510070024C /* VideoDescription.swift */; };
|
37CFB48728AFE2510070024C /* VideoDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37CFB48428AFE2510070024C /* VideoDescription.swift */; };
|
||||||
|
37D2E0D028B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2E0CF28B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift */; };
|
||||||
|
37D2E0D128B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2E0CF28B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift */; };
|
||||||
|
37D2E0D228B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2E0CF28B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift */; };
|
||||||
|
37D2E0D428B67EFC00F64D52 /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2E0D328B67EFC00F64D52 /* Delay.swift */; };
|
||||||
|
37D2E0D528B67EFC00F64D52 /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2E0D328B67EFC00F64D52 /* Delay.swift */; };
|
||||||
|
37D2E0D628B67EFC00F64D52 /* Delay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D2E0D328B67EFC00F64D52 /* Delay.swift */; };
|
||||||
37D4B0D92671614900C925CA /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B0D82671614900C925CA /* Tests_iOS.swift */; };
|
37D4B0D92671614900C925CA /* Tests_iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B0D82671614900C925CA /* Tests_iOS.swift */; };
|
||||||
37D4B0E32671614900C925CA /* Tests_macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B0E22671614900C925CA /* Tests_macOS.swift */; };
|
37D4B0E32671614900C925CA /* Tests_macOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B0E22671614900C925CA /* Tests_macOS.swift */; };
|
||||||
37D4B0E42671614900C925CA /* YatteeApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B0C22671614700C925CA /* YatteeApp.swift */; };
|
37D4B0E42671614900C925CA /* YatteeApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D4B0C22671614700C925CA /* YatteeApp.swift */; };
|
||||||
@ -1057,6 +1066,7 @@
|
|||||||
3751BA8227E6914F007B1A60 /* ReturnYouTubeDislikeAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReturnYouTubeDislikeAPI.swift; sourceTree = "<group>"; };
|
3751BA8227E6914F007B1A60 /* ReturnYouTubeDislikeAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReturnYouTubeDislikeAPI.swift; sourceTree = "<group>"; };
|
||||||
37520698285E8DD300CA655F /* Chapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Chapter.swift; sourceTree = "<group>"; };
|
37520698285E8DD300CA655F /* Chapter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Chapter.swift; sourceTree = "<group>"; };
|
||||||
3752069C285E910600CA655F /* ChapterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChapterView.swift; sourceTree = "<group>"; };
|
3752069C285E910600CA655F /* ChapterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChapterView.swift; sourceTree = "<group>"; };
|
||||||
|
3754B01428B7F84D009717C8 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
||||||
3756C2A52861131100E4B059 /* NetworkState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkState.swift; sourceTree = "<group>"; };
|
3756C2A52861131100E4B059 /* NetworkState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkState.swift; sourceTree = "<group>"; };
|
||||||
3756C2A92861151C00E4B059 /* NetworkStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkStateModel.swift; sourceTree = "<group>"; };
|
3756C2A92861151C00E4B059 /* NetworkStateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkStateModel.swift; sourceTree = "<group>"; };
|
||||||
37579D5C27864F5F00FD0B98 /* Help.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Help.swift; sourceTree = "<group>"; };
|
37579D5C27864F5F00FD0B98 /* Help.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Help.swift; sourceTree = "<group>"; };
|
||||||
@ -1194,6 +1204,8 @@
|
|||||||
37CEE4BC2677B670005A1EFE /* SingleAssetStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleAssetStream.swift; sourceTree = "<group>"; };
|
37CEE4BC2677B670005A1EFE /* SingleAssetStream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SingleAssetStream.swift; sourceTree = "<group>"; };
|
||||||
37CEE4C02677B697005A1EFE /* Stream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stream.swift; sourceTree = "<group>"; };
|
37CEE4C02677B697005A1EFE /* Stream.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Stream.swift; sourceTree = "<group>"; };
|
||||||
37CFB48428AFE2510070024C /* VideoDescription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoDescription.swift; sourceTree = "<group>"; };
|
37CFB48428AFE2510070024C /* VideoDescription.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoDescription.swift; sourceTree = "<group>"; };
|
||||||
|
37D2E0CF28B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AnimationCompletionObserverModifier.swift; sourceTree = "<group>"; };
|
||||||
|
37D2E0D328B67EFC00F64D52 /* Delay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Delay.swift; sourceTree = "<group>"; };
|
||||||
37D4B0C22671614700C925CA /* YatteeApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YatteeApp.swift; sourceTree = "<group>"; };
|
37D4B0C22671614700C925CA /* YatteeApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YatteeApp.swift; sourceTree = "<group>"; };
|
||||||
37D4B0C32671614700C925CA /* AppTabNavigation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTabNavigation.swift; sourceTree = "<group>"; };
|
37D4B0C32671614700C925CA /* AppTabNavigation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppTabNavigation.swift; sourceTree = "<group>"; };
|
||||||
37D4B0C42671614800C925CA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
37D4B0C42671614800C925CA /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
@ -1796,6 +1808,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
37F64FE326FE70A60081B69E /* RedrawOnModifier.swift */,
|
37F64FE326FE70A60081B69E /* RedrawOnModifier.swift */,
|
||||||
|
37D2E0CF28B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift */,
|
||||||
);
|
);
|
||||||
path = Modifiers;
|
path = Modifiers;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1965,8 +1978,10 @@
|
|||||||
371AAE2526CEBF0B00901972 /* Trending */,
|
371AAE2526CEBF0B00901972 /* Trending */,
|
||||||
371AAE2726CEBF4700901972 /* Videos */,
|
371AAE2726CEBF4700901972 /* Videos */,
|
||||||
371AAE2826CEC7D900901972 /* Views */,
|
371AAE2826CEC7D900901972 /* Views */,
|
||||||
|
3754B01428B7F84D009717C8 /* Constants.swift */,
|
||||||
375168D52700FAFF008F96A6 /* Debounce.swift */,
|
375168D52700FAFF008F96A6 /* Debounce.swift */,
|
||||||
372915E52687E3B900F5A35B /* Defaults.swift */,
|
372915E52687E3B900F5A35B /* Defaults.swift */,
|
||||||
|
37D2E0D328B67EFC00F64D52 /* Delay.swift */,
|
||||||
3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */,
|
3761ABFC26F0F8DE00AA496F /* EnvironmentValues.swift */,
|
||||||
3729037D2739E47400EA99F6 /* MenuCommands.swift */,
|
3729037D2739E47400EA99F6 /* MenuCommands.swift */,
|
||||||
37B7958F2771DAE0001CF27B /* OpenURLHandler.swift */,
|
37B7958F2771DAE0001CF27B /* OpenURLHandler.swift */,
|
||||||
@ -2740,6 +2755,7 @@
|
|||||||
372CFD15285F2E2A00B0B54B /* ControlsBar.swift in Sources */,
|
372CFD15285F2E2A00B0B54B /* ControlsBar.swift in Sources */,
|
||||||
37BD07C82698B71C003EBB87 /* AppTabNavigation.swift in Sources */,
|
37BD07C82698B71C003EBB87 /* AppTabNavigation.swift in Sources */,
|
||||||
37599F38272B4D740087F250 /* FavoriteButton.swift in Sources */,
|
37599F38272B4D740087F250 /* FavoriteButton.swift in Sources */,
|
||||||
|
3754B01528B7F84D009717C8 /* Constants.swift in Sources */,
|
||||||
378FFBC428660172009E3FBE /* URLParser.swift in Sources */,
|
378FFBC428660172009E3FBE /* URLParser.swift in Sources */,
|
||||||
3784B23D2728B85300B09468 /* ShareButton.swift in Sources */,
|
3784B23D2728B85300B09468 /* ShareButton.swift in Sources */,
|
||||||
37EAD86B267B9C5600D9E01B /* SponsorBlockAPI.swift in Sources */,
|
37EAD86B267B9C5600D9E01B /* SponsorBlockAPI.swift in Sources */,
|
||||||
@ -2750,6 +2766,7 @@
|
|||||||
37A5DBC8285E371400CA4DD1 /* ControlBackgroundModifier.swift in Sources */,
|
37A5DBC8285E371400CA4DD1 /* ControlBackgroundModifier.swift in Sources */,
|
||||||
377ABC40286E4AD5009C986F /* InstancesManifest.swift in Sources */,
|
377ABC40286E4AD5009C986F /* InstancesManifest.swift in Sources */,
|
||||||
37BD07B52698AA4D003EBB87 /* ContentView.swift in Sources */,
|
37BD07B52698AA4D003EBB87 /* ContentView.swift in Sources */,
|
||||||
|
37D2E0D428B67EFC00F64D52 /* Delay.swift in Sources */,
|
||||||
37130A5B277657090033018A /* Yattee.xcdatamodeld in Sources */,
|
37130A5B277657090033018A /* Yattee.xcdatamodeld in Sources */,
|
||||||
37152EEA26EFEB95004FB96D /* LazyView.swift in Sources */,
|
37152EEA26EFEB95004FB96D /* LazyView.swift in Sources */,
|
||||||
3761ABFD26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */,
|
3761ABFD26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */,
|
||||||
@ -2760,6 +2777,7 @@
|
|||||||
37C7A1DA267CACF50010EAD6 /* TrendingCountry.swift in Sources */,
|
37C7A1DA267CACF50010EAD6 /* TrendingCountry.swift in Sources */,
|
||||||
37E80F40287B472300561799 /* ScrollContentBackground+Backport.swift in Sources */,
|
37E80F40287B472300561799 /* ScrollContentBackground+Backport.swift in Sources */,
|
||||||
375EC959289EEB8200751258 /* QualityProfileForm.swift in Sources */,
|
375EC959289EEB8200751258 /* QualityProfileForm.swift in Sources */,
|
||||||
|
37D2E0D028B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */,
|
||||||
3727B74A27872A920021C15E /* VisualEffectBlur-iOS.swift in Sources */,
|
3727B74A27872A920021C15E /* VisualEffectBlur-iOS.swift in Sources */,
|
||||||
37977583268922F600DD52A8 /* InvidiousAPI.swift in Sources */,
|
37977583268922F600DD52A8 /* InvidiousAPI.swift in Sources */,
|
||||||
37130A5F277657300033018A /* PersistenceController.swift in Sources */,
|
37130A5F277657300033018A /* PersistenceController.swift in Sources */,
|
||||||
@ -2991,6 +3009,7 @@
|
|||||||
37DD9DBB2785D60300539416 /* FramePreferenceKey.swift in Sources */,
|
37DD9DBB2785D60300539416 /* FramePreferenceKey.swift in Sources */,
|
||||||
375DFB5926F9DA010013F468 /* InstancesModel.swift in Sources */,
|
375DFB5926F9DA010013F468 /* InstancesModel.swift in Sources */,
|
||||||
3705B183267B4E4900704544 /* TrendingCategory.swift in Sources */,
|
3705B183267B4E4900704544 /* TrendingCategory.swift in Sources */,
|
||||||
|
37D2E0D128B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */,
|
||||||
37FB285F272225E800A57617 /* ContentItemView.swift in Sources */,
|
37FB285F272225E800A57617 /* ContentItemView.swift in Sources */,
|
||||||
37FD43DC270470B70073EE42 /* InstancesSettings.swift in Sources */,
|
37FD43DC270470B70073EE42 /* InstancesSettings.swift in Sources */,
|
||||||
3756C2A72861131100E4B059 /* NetworkState.swift in Sources */,
|
3756C2A72861131100E4B059 /* NetworkState.swift in Sources */,
|
||||||
@ -3125,6 +3144,7 @@
|
|||||||
37484C2A26FC83FF00287258 /* AccountForm.swift in Sources */,
|
37484C2A26FC83FF00287258 /* AccountForm.swift in Sources */,
|
||||||
37BE0BD026A0E2D50092E2DB /* VideoPlayerView.swift in Sources */,
|
37BE0BD026A0E2D50092E2DB /* VideoPlayerView.swift in Sources */,
|
||||||
373CFAEC26975CBF003CB2C6 /* PlaylistFormView.swift in Sources */,
|
373CFAEC26975CBF003CB2C6 /* PlaylistFormView.swift in Sources */,
|
||||||
|
37D2E0D528B67EFC00F64D52 /* Delay.swift in Sources */,
|
||||||
37977584268922F600DD52A8 /* InvidiousAPI.swift in Sources */,
|
37977584268922F600DD52A8 /* InvidiousAPI.swift in Sources */,
|
||||||
370F4FAB27CC164D001B35DC /* PlayerControlsModel.swift in Sources */,
|
370F4FAB27CC164D001B35DC /* PlayerControlsModel.swift in Sources */,
|
||||||
37E8B0ED27B326C00024006F /* TimelineView.swift in Sources */,
|
37E8B0ED27B326C00024006F /* TimelineView.swift in Sources */,
|
||||||
@ -3135,6 +3155,7 @@
|
|||||||
3748186B26A764FB0084E870 /* Thumbnail+Fixtures.swift in Sources */,
|
3748186B26A764FB0084E870 /* Thumbnail+Fixtures.swift in Sources */,
|
||||||
3782B95E2755858100990149 /* NSTextField+FocusRingType.swift in Sources */,
|
3782B95E2755858100990149 /* NSTextField+FocusRingType.swift in Sources */,
|
||||||
37C3A252272366440087A57A /* ChannelPlaylistView.swift in Sources */,
|
37C3A252272366440087A57A /* ChannelPlaylistView.swift in Sources */,
|
||||||
|
3754B01628B7F84D009717C8 /* Constants.swift in Sources */,
|
||||||
373CFADC269663F1003CB2C6 /* Thumbnail.swift in Sources */,
|
373CFADC269663F1003CB2C6 /* Thumbnail.swift in Sources */,
|
||||||
37C0697B2725C09E00F7F6CB /* PlayerQueueItemBridge.swift in Sources */,
|
37C0697B2725C09E00F7F6CB /* PlayerQueueItemBridge.swift in Sources */,
|
||||||
37CFB48628AFE2510070024C /* VideoDescription.swift in Sources */,
|
37CFB48628AFE2510070024C /* VideoDescription.swift in Sources */,
|
||||||
@ -3234,6 +3255,7 @@
|
|||||||
3748187026A769D60084E870 /* DetailBadge.swift in Sources */,
|
3748187026A769D60084E870 /* DetailBadge.swift in Sources */,
|
||||||
3741A32C27E7EFFD00D266D1 /* PlayerControls.swift in Sources */,
|
3741A32C27E7EFFD00D266D1 /* PlayerControls.swift in Sources */,
|
||||||
371B7E632759706A00D21217 /* CommentsView.swift in Sources */,
|
371B7E632759706A00D21217 /* CommentsView.swift in Sources */,
|
||||||
|
37D2E0D628B67EFC00F64D52 /* Delay.swift in Sources */,
|
||||||
379F1421289ECE7F00DE48B5 /* QualitySettings.swift in Sources */,
|
379F1421289ECE7F00DE48B5 /* QualitySettings.swift in Sources */,
|
||||||
37A9965C26D6F8CA006E3224 /* HorizontalCells.swift in Sources */,
|
37A9965C26D6F8CA006E3224 /* HorizontalCells.swift in Sources */,
|
||||||
3782B95727557E6E00990149 /* SearchSuggestions.swift in Sources */,
|
3782B95727557E6E00990149 /* SearchSuggestions.swift in Sources */,
|
||||||
@ -3372,6 +3394,7 @@
|
|||||||
37D4B19926717E1500C925CA /* Video.swift in Sources */,
|
37D4B19926717E1500C925CA /* Video.swift in Sources */,
|
||||||
378E50FD26FE8B9F00F49626 /* Instance.swift in Sources */,
|
378E50FD26FE8B9F00F49626 /* Instance.swift in Sources */,
|
||||||
37169AA82729E2CC0011DE61 /* AccountsBridge.swift in Sources */,
|
37169AA82729E2CC0011DE61 /* AccountsBridge.swift in Sources */,
|
||||||
|
3754B01728B7F84D009717C8 /* Constants.swift in Sources */,
|
||||||
37BC50AE2778BCBA00510953 /* HistoryModel.swift in Sources */,
|
37BC50AE2778BCBA00510953 /* HistoryModel.swift in Sources */,
|
||||||
37D526E02720AC4400ED2F5E /* VideosAPI.swift in Sources */,
|
37D526E02720AC4400ED2F5E /* VideosAPI.swift in Sources */,
|
||||||
37599F36272B44000087F250 /* FavoritesModel.swift in Sources */,
|
37599F36272B44000087F250 /* FavoritesModel.swift in Sources */,
|
||||||
@ -3383,6 +3406,7 @@
|
|||||||
3761ABFF26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */,
|
3761ABFF26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */,
|
||||||
37C3A24F272360470087A57A /* ChannelPlaylist+Fixtures.swift in Sources */,
|
37C3A24F272360470087A57A /* ChannelPlaylist+Fixtures.swift in Sources */,
|
||||||
37FB28432721B22200A57617 /* ContentItem.swift in Sources */,
|
37FB28432721B22200A57617 /* ContentItem.swift in Sources */,
|
||||||
|
37D2E0D228B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */,
|
||||||
37AAF2A226741C97007FC770 /* SubscriptionsView.swift in Sources */,
|
37AAF2A226741C97007FC770 /* SubscriptionsView.swift in Sources */,
|
||||||
37484C1B26FC837400287258 /* PlayerSettings.swift in Sources */,
|
37484C1B26FC837400287258 /* PlayerSettings.swift in Sources */,
|
||||||
372915E82687E3B900F5A35B /* Defaults.swift in Sources */,
|
372915E82687E3B900F5A35B /* Defaults.swift in Sources */,
|
||||||
|
Loading…
Reference in New Issue
Block a user