Drop iOS 14 and macOS 11 support

This commit is contained in:
Arkadiusz Fal 2023-07-01 18:38:11 +02:00
parent a1c9d3aaa9
commit dcef7f47ff
46 changed files with 90 additions and 688 deletions

View File

@ -1,15 +0,0 @@
import SwiftUI
extension Backport where Content: View {
@ViewBuilder func badge(_ count: Text?) -> some View {
#if os(tvOS)
content
#else
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
content.badge(count)
} else {
content
}
#endif
}
}

View File

@ -1,15 +0,0 @@
import Foundation
import SwiftUI
extension Backport where Content: View {
@ViewBuilder func listRowSeparator(_ visible: Bool) -> some View {
if #available(iOS 15, macOS 13, *) {
content
#if !os(tvOS)
.listRowSeparator(visible ? .visible : .hidden)
#endif
} else {
content
}
}
}

View File

@ -1,11 +0,0 @@
import SwiftUI
extension Backport where Content: View {
@ViewBuilder func refreshable(action: @Sendable @escaping () async -> Void) -> some View {
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
content.refreshable(action: action)
} else {
content
}
}
}

View File

@ -1,11 +0,0 @@
import SwiftUI
extension Backport where Content: View {
@ViewBuilder func tint(_ color: Color?) -> some View {
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
content.tint(color)
} else {
content.foregroundColor(color)
}
}
}

View File

@ -95,6 +95,7 @@ final class SubscribedChannelsModel: ObservableObject, CacheModel {
} }
} }
func loadCachedChannels(_ account: Account) { func loadCachedChannels(_ account: Account) {
let cache = getChannels(account: account) let cache = getChannels(account: account)
if !cache.isEmpty { if !cache.isEmpty {

View File

@ -40,7 +40,7 @@ struct ChannelVideosView: View {
} }
var body: some View { var body: some View {
let content = VStack { VStack {
#if os(tvOS) #if os(tvOS)
VStack { VStack {
HStack(spacing: 24) { HStack(spacing: 24) {
@ -181,19 +181,12 @@ struct ChannelVideosView: View {
.navigationTitle(navigationTitle) .navigationTitle(navigationTitle)
#endif #endif
return Group {
if #available(macOS 12.0, *) {
content
#if os(tvOS) #if os(tvOS)
.background(Color.background(scheme: colorScheme)) .background(Color.background(scheme: colorScheme))
#endif #endif
#if !os(iOS) #if !os(iOS)
.focusScope(focusNamespace) .focusScope(focusNamespace)
#endif #endif
} else {
content
}
}
} }
var verticalCellsEdgesIgnoringSafeArea: Edge.Set { var verticalCellsEdgesIgnoringSafeArea: Edge.Set {

View File

@ -63,16 +63,9 @@ struct Constants {
static func seekIcon(_ type: String, _ interval: TimeInterval) -> String { static func seekIcon(_ type: String, _ interval: TimeInterval) -> String {
let interval = Int(interval) let interval = Int(interval)
let allVersions = [10, 15, 30, 45, 60, 75, 90] let allVersions = [5, 10, 15, 30, 45, 60, 75, 90]
let iOS15 = [5]
let iconName = "go\(type).\(interval)" let iconName = "go\(type).\(interval)"
if #available(iOS 15, macOS 12, *) {
if iOS15.contains(interval) {
return iconName
}
}
if allVersions.contains(interval) { if allVersions.contains(interval) {
return iconName return iconName
} }

View File

@ -34,8 +34,7 @@ struct DocumentsView: View {
} }
.navigationTitle(directoryLabel) .navigationTitle(directoryLabel)
.padding(.horizontal) .padding(.horizontal)
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode) .navigationBarTitleDisplayMode(.inline)
.backport
.refreshable { .refreshable {
DispatchQueue.main.async { DispatchQueue.main.async {
self.refresh() self.refresh()

View File

@ -15,7 +15,6 @@ struct AccountViewButton: View {
} label: { } label: {
HStack(spacing: 6) { HStack(spacing: 6) {
if !accountPickerDisplaysUsername || !(model.current?.isPublic ?? true) { if !accountPickerDisplaysUsername || !(model.current?.isPublic ?? true) {
if #available(iOS 15, macOS 12, *) {
if let name = model.current?.app?.rawValue.capitalized { if let name = model.current?.app?.rawValue.capitalized {
Image(name) Image(name)
.resizable() .resizable()
@ -23,9 +22,6 @@ struct AccountViewButton: View {
} else { } else {
Image(systemName: "globe") Image(systemName: "globe")
} }
} else {
Image(systemName: "globe")
}
} }
if accountPickerDisplaysUsername { if accountPickerDisplaysUsername {

View File

@ -38,7 +38,6 @@ struct AppSidebarPlaylists: View {
if accounts.app.userPlaylistsEndpointIncludesVideos, !playlist.videos.isEmpty { if accounts.app.userPlaylistsEndpointIncludesVideos, !playlist.videos.isEmpty {
label label
.backport
.badge(Text("\(playlist.videos.count)")) .badge(Text("\(playlist.videos.count)"))
} else { } else {
label label

View File

@ -26,7 +26,6 @@ struct AppSidebarSubscriptions: View {
Spacer() Spacer()
} }
.backport
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedByChannelText(channel) : nil) .badge(showUnwatchedFeedBadges ? feedCount.unwatchedByChannelText(channel) : nil)
} }
.contextMenu { .contextMenu {

View File

@ -95,7 +95,6 @@ struct AppTabNavigation: View {
.accessibility(label: Text("Subscriptions")) .accessibility(label: Text("Subscriptions"))
} }
.tag(TabSelection.subscriptions) .tag(TabSelection.subscriptions)
.backport
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedText : nil) .badge(showUnwatchedFeedBadges ? feedCount.unwatchedText : nil)
} }

View File

@ -79,7 +79,6 @@ struct Sidebar: View {
Label("Subscriptions", systemImage: "star.circle") Label("Subscriptions", systemImage: "star.circle")
.accessibility(label: Text("Subscriptions")) .accessibility(label: Text("Subscriptions"))
} }
.backport
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedText : nil) .badge(showUnwatchedFeedBadges ? feedCount.unwatchedText : nil)
.contextMenu { .contextMenu {
playUnwatchedButton playUnwatchedButton

View File

@ -47,7 +47,7 @@ final class AppleAVPlayerViewController: UIViewController {
infoViewControllers.append(infoViewController([.chapters], title: "Chapters")) infoViewControllers.append(infoViewController([.chapters], title: "Chapters"))
infoViewControllers.append(infoViewController([.comments], title: "Comments")) infoViewControllers.append(infoViewController([.comments], title: "Comments"))
var queueSections = [NowPlayingView.ViewSection.playingNext] let queueSections = [NowPlayingView.ViewSection.playingNext]
infoViewControllers.append(contentsOf: [ infoViewControllers.append(contentsOf: [
infoViewController([.related], title: "Related"), infoViewController([.related], title: "Related"),

View File

@ -7,19 +7,8 @@ struct ControlBackgroundModifier: ViewModifier {
func body(content: Content) -> some View { func body(content: Content) -> some View {
if enabled { if enabled {
if #available(iOS 15, macOS 12, *) {
content content
.background(.thinMaterial) .background(.thinMaterial)
} else {
content
#if os(macOS)
.background(VisualEffectBlur(material: .hudWindow))
#elseif os(iOS)
.background(VisualEffectBlur(blurStyle: .systemThinMaterial).edgesIgnoringSafeArea(edgesIgnoringSafeArea))
#else
.background(.thinMaterial)
#endif
}
} else { } else {
content content
} }

View File

@ -255,8 +255,6 @@ struct PlayerControls: View {
{ {
ThumbnailView(url: url) ThumbnailView(url: url)
.frame(maxWidth: .infinity, maxHeight: .infinity) .frame(maxWidth: .infinity, maxHeight: .infinity)
.transition(.opacity)
.animation(.default)
} else if player.videoForDisplay == nil { } else if player.videoForDisplay == nil {
Color.black Color.black
} }

View File

@ -18,8 +18,9 @@ struct RelatedView: View {
Color.clear.padding(.bottom, 50) Color.clear.padding(.bottom, 50)
.listRowBackground(Color.clear) .listRowBackground(Color.clear)
.backport #if os(iOS)
.listRowSeparator(false) .listRowSeparator(.hidden)
#endif
} }
} }
} }

View File

@ -219,8 +219,10 @@ struct CommentView: View {
} }
private var commentText: some View { private var commentText: some View {
Group { Text(comment.text)
let text = Text(comment.text) #if !os(tvOS)
.textSelection(.enabled)
#endif
#if os(macOS) #if os(macOS)
.font(.system(size: 14)) .font(.system(size: 14))
#elseif os(iOS) #elseif os(iOS)
@ -228,16 +230,6 @@ struct CommentView: View {
#endif #endif
.lineSpacing(3) .lineSpacing(3)
.fixedSize(horizontal: false, vertical: true) .fixedSize(horizontal: false, vertical: true)
if #available(iOS 15.0, macOS 12.0, *) {
text
#if !os(tvOS)
.textSelection(.enabled)
#endif
} else {
text
}
}
} }
private func openChannelAction() { private func openChannelAction() {

View File

@ -32,13 +32,8 @@ struct CommentsView: View {
struct CommentsView_Previews: PreviewProvider { struct CommentsView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
CommentsView() CommentsView()
.previewInterfaceOrientation(.landscapeRight) .previewInterfaceOrientation(.landscapeRight)
.injectFixtureEnvironmentObjects() .injectFixtureEnvironmentObjects()
} }
CommentsView()
.injectFixtureEnvironmentObjects()
}
} }

View File

@ -79,15 +79,10 @@ struct InspectorView: View {
Text(detail.localized()) Text(detail.localized())
.foregroundColor(.secondary) .foregroundColor(.secondary)
Spacer() Spacer()
let value = Text(value).lineLimit(1) Text(value).lineLimit(1)
if #available(iOS 15.0, macOS 12.0, *) {
value
#if !os(tvOS) #if !os(tvOS)
.textSelection(.enabled) .textSelection(.enabled)
#endif #endif
} else {
value
}
} }
.font(.caption) .font(.caption)
} }

View File

@ -30,8 +30,9 @@ struct PlayerQueueView: View {
#endif #endif
Color.clear.padding(.bottom, 50) Color.clear.padding(.bottom, 50)
.listRowBackground(Color.clear) .listRowBackground(Color.clear)
.backport #if os(iOS)
.listRowSeparator(false) .listRowSeparator(.hidden)
#endif
} }
.environment(\.inNavigationView, false) .environment(\.inNavigationView, false)
} }

View File

@ -59,20 +59,12 @@ struct VideoDescription: View {
@ViewBuilder var textDescription: some View { @ViewBuilder var textDescription: some View {
#if !os(iOS) #if !os(iOS)
Group {
if #available(macOS 12, *) {
Text(description) Text(description)
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(shouldExpand ? 500 : Self.collapsedLines) .lineLimit(shouldExpand ? 500 : Self.collapsedLines)
#if !os(tvOS) #if !os(tvOS)
.textSelection(.enabled) .textSelection(.enabled)
#endif #endif
} else {
Text(description)
.frame(maxWidth: .infinity, alignment: .leading)
.lineLimit(shouldExpand ? 500 : Self.collapsedLines)
}
}
.multilineTextAlignment(.leading) .multilineTextAlignment(.leading)
.font(.system(size: 14)) .font(.system(size: 14))
.lineSpacing(3) .lineSpacing(3)

View File

@ -294,9 +294,6 @@ struct VideoPlayerView: View {
} }
}) })
#endif #endif
.background(Color.black)
if !detailsHiddenInFullScreen { if !detailsHiddenInFullScreen {
VideoDetails( VideoDetails(
video: player.videoForDisplay, video: player.videoForDisplay,

View File

@ -91,13 +91,6 @@ struct PlaylistsView: View {
loadResource() loadResource()
} }
#if os(iOS) #if os(iOS)
.refreshControl { refreshControl in
model.load(force: true) {
model.reloadPlaylists.toggle()
refreshControl.endRefreshing()
}
}
.backport
.refreshable { .refreshable {
DispatchQueue.main.async { DispatchQueue.main.async {
model.load(force: true) { model.reloadPlaylists.toggle() } model.load(force: true) { model.reloadPlaylists.toggle() }

View File

@ -2,7 +2,6 @@ import Introspect
import Repeat import Repeat
import SwiftUI import SwiftUI
@available(iOS 15.0, macOS 12, *)
struct FocusableSearchTextField: View { struct FocusableSearchTextField: View {
@ObservedObject private var state = SearchModel.shared @ObservedObject private var state = SearchModel.shared

View File

@ -95,11 +95,7 @@ struct SearchView: View {
filtersMenu filtersMenu
} }
if #available(macOS 12, *) {
FocusableSearchTextField() FocusableSearchTextField()
} else {
SearchTextField()
}
} }
#endif #endif
} }
@ -179,11 +175,7 @@ struct SearchView: View {
searchMenu searchMenu
} }
ToolbarItem(placement: .principal) { ToolbarItem(placement: .principal) {
if #available(iOS 15, *) {
FocusableSearchTextField() FocusableSearchTextField()
} else {
SearchTextField()
}
} }
} }
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)

View File

@ -200,7 +200,7 @@ struct QualityProfileForm: View {
@ViewBuilder var formatsPicker: some View { @ViewBuilder var formatsPicker: some View {
#if os(macOS) #if os(macOS)
let list = ForEach(QualityProfile.Format.allCases, id: \.self) { format in ForEach(QualityProfile.Format.allCases, id: \.self) { format in
MultiselectRow( MultiselectRow(
title: format.description, title: format.description,
selected: isFormatSelected(format), selected: isFormatSelected(format),
@ -209,16 +209,8 @@ struct QualityProfileForm: View {
toggleFormat(format, value: value) toggleFormat(format, value: value)
} }
} }
Group {
if #available(macOS 12.0, *) {
list
.listStyle(.inset(alternatesRowBackgrounds: true)) .listStyle(.inset(alternatesRowBackgrounds: true))
} else {
list
.listStyle(.inset)
}
}
Spacer() Spacer()
#else #else
ForEach(QualityProfile.Format.allCases, id: \.self) { format in ForEach(QualityProfile.Format.allCases, id: \.self) { format in

View File

@ -175,7 +175,6 @@ struct QualitySettings: View {
} }
} }
if #available(macOS 12.0, *) {
#if os(macOS) #if os(macOS)
List { List {
list list
@ -184,15 +183,6 @@ struct QualitySettings: View {
#else #else
list list
#endif #endif
} else {
#if os(macOS)
List {
list
}
#else
list
#endif
}
} }
} }

View File

@ -50,15 +50,8 @@ struct SponsorBlockSettings: View {
} }
} }
Group {
if #available(macOS 12.0, *) {
list list
.listStyle(.inset(alternatesRowBackgrounds: true)) .listStyle(.inset(alternatesRowBackgrounds: true))
} else {
list
.listStyle(.inset)
}
}
Spacer() Spacer()
#else #else
ForEach(SponsorBlockAPI.categories, id: \.self) { category in ForEach(SponsorBlockAPI.categories, id: \.self) { category in

View File

@ -34,8 +34,9 @@ struct ChannelsView: View {
Text(channel.name) Text(channel.name)
.lineLimit(1) .lineLimit(1)
} }
.backport #if !os(tvOS)
.badge(showUnwatchedFeedBadges ? feedCount.unwatchedByChannelText(channel) : nil) .badge(showUnwatchedFeedBadges ? feedCount.unwatchedByChannelText(channel) : nil)
#endif
Group { Group {
#if os(tvOS) #if os(tvOS)
@ -73,8 +74,9 @@ struct ChannelsView: View {
Color.clear.padding(.bottom, 50) Color.clear.padding(.bottom, 50)
.listRowBackground(Color.clear) .listRowBackground(Color.clear)
.backport #if os(iOS)
.listRowSeparator(false) .listRowSeparator(.hidden)
#endif
} }
} }
#if !os(tvOS) #if !os(tvOS)
@ -89,12 +91,6 @@ struct ChannelsView: View {
subscriptions.load(force: true) subscriptions.load(force: true)
} }
#if os(iOS) #if os(iOS)
.refreshControl { refreshControl in
subscriptions.load(force: true) {
refreshControl.endRefreshing()
}
}
.backport
.refreshable { .refreshable {
await subscriptions.load(force: true) await subscriptions.load(force: true)
} }

View File

@ -22,12 +22,6 @@ struct FeedView: View {
feed.loadResources() feed.loadResources()
} }
#if os(iOS) #if os(iOS)
.refreshControl { refreshControl in
feed.loadResources(force: true) {
refreshControl.endRefreshing()
}
}
.backport
.refreshable { .refreshable {
await feed.loadResources(force: true) await feed.loadResources(force: true)
} }

View File

@ -16,11 +16,7 @@ struct TrendingCountry: View {
VStack { VStack {
#if !os(tvOS) #if !os(tvOS)
HStack { HStack {
if #available(iOS 15.0, macOS 12.0, *) {
TextField("Country", text: $query, prompt: Text(Self.prompt)) TextField("Country", text: $query, prompt: Text(Self.prompt))
} else {
TextField(Self.prompt, text: $query)
}
Button("Done") { selectCountryAndDismiss() } Button("Done") { selectCountryAndDismiss() }
.keyboardShortcut(.defaultAction) .keyboardShortcut(.defaultAction)
@ -57,12 +53,8 @@ struct TrendingCountry: View {
return Group { return Group {
#if os(macOS) #if os(macOS)
if #available(macOS 12.0, *) {
list list
.listStyle(.inset(alternatesRowBackgrounds: true)) .listStyle(.inset(alternatesRowBackgrounds: true))
} else {
list
}
#else #else
list list
#endif #endif

View File

@ -95,12 +95,7 @@ struct TrendingView: View {
.navigationTitle("Trending") .navigationTitle("Trending")
#endif #endif
#if os(iOS) #if os(iOS)
.refreshControl { refreshControl in
resource.load().onCompletion { _ in
refreshControl.endRefreshing()
}
}
.backport
.refreshable { .refreshable {
DispatchQueue.main.async { DispatchQueue.main.async {
resource.load() resource.load()

View File

@ -48,8 +48,7 @@ struct ThumbnailView: View {
} }
@ViewBuilder var asyncImageIfAvailable: some View { @ViewBuilder var asyncImageIfAvailable: some View {
if #available(iOS 15, macOS 12, *) { CachedAsyncImage(url: url, urlCache: BaseCacheModel.imageCache, transaction: Transaction(animation: .default)) { phase in
CachedAsyncImage(url: url, urlCache: BaseCacheModel.imageCache) { phase in
switch phase { switch phase {
case let .success(image): case let .success(image):
image image
@ -63,9 +62,6 @@ struct ThumbnailView: View {
placeholder placeholder
} }
} }
} else {
webImage
}
} }
var placeholder: some View { var placeholder: some View {

View File

@ -8,7 +8,7 @@ struct OpenSettingsButton: View {
#endif #endif
var body: some View { var body: some View {
let button = Button { Button {
presentationMode.wrappedValue.dismiss() presentationMode.wrappedValue.dismiss()
#if os(macOS) #if os(macOS)
@ -20,13 +20,7 @@ struct OpenSettingsButton: View {
Label("Open Settings", systemImage: "gearshape.2") Label("Open Settings", systemImage: "gearshape.2")
} }
.buttonStyle(.plain) .buttonStyle(.plain)
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
button
.buttonStyle(.borderedProminent) .buttonStyle(.borderedProminent)
} else {
button
}
} }
} }

View File

@ -47,14 +47,6 @@ struct PopularView: View {
} }
} }
.navigationBarTitleDisplayMode(.inline) .navigationBarTitleDisplayMode(.inline)
.refreshControl { refreshControl in
resource?.load().onCompletion { _ in
refreshControl.endRefreshing()
}
.onFailure { self.error = $0 }
.onSuccess { _ in self.error = nil }
}
.backport
.refreshable { .refreshable {
DispatchQueue.main.async { DispatchQueue.main.async {
resource?.load() resource?.load()
@ -62,7 +54,7 @@ struct PopularView: View {
.onSuccess { _ in self.error = nil } .onSuccess { _ in self.error = nil }
} }
} }
.navigationBarTitleDisplayMode(RefreshControl.navigationBarTitleDisplayMode) .navigationBarTitleDisplayMode(.inline)
#endif #endif
#if os(macOS) #if os(macOS)
.toolbar { .toolbar {

View File

@ -281,11 +281,7 @@ struct VideoContextMenuView: View {
let label = Label("Remove…", systemImage: "trash.fill") let label = Label("Remove…", systemImage: "trash.fill")
.foregroundColor(Color("AppRedColor")) .foregroundColor(Color("AppRedColor"))
if #available(iOS 15, macOS 12, *) {
Button(role: .destructive, action: action) { label } Button(role: .destructive, action: action) { label }
} else {
Button(action: action) { label }
}
} }
#endif #endif

View File

@ -1,15 +0,0 @@
//
// UIResponder+Extensions.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 21/09/2021.
//
import Foundation
import UIKit
extension UIResponder {
var parentViewController: UIViewController? {
next as? UIViewController ?? next?.parentViewController
}
}

View File

@ -1,70 +0,0 @@
//
// UIView+Extensions.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 19/09/2021.
//
import Foundation
import UIKit
extension UIView {
/// Returs frame in screen coordinates.
var globalFrame: CGRect {
if let window {
return convert(bounds, to: window.screen.coordinateSpace)
} else {
return .zero
}
}
/// Returns with all the instances of the given view type in the view hierarchy.
func viewsInHierarchy<ViewType: UIView>() -> [ViewType]? {
var views: [ViewType] = []
viewsInHierarchy(views: &views)
return views.isEmpty ? nil : views
}
private func viewsInHierarchy<ViewType: UIView>(views: inout [ViewType]) {
subviews.forEach { eachSubView in
if let matchingView = eachSubView as? ViewType {
views.append(matchingView)
}
eachSubView.viewsInHierarchy(views: &views)
}
}
/// Search ancestral view hierarcy for the given view type.
func searchViewAnchestorsFor<ViewType: UIView>(
_ onViewFound: (ViewType) -> Void
) {
if let matchingView = superview as? ViewType {
onViewFound(matchingView)
} else {
superview?.searchViewAnchestorsFor(onViewFound)
}
}
/// Search ancestral view hierarcy for the given view type.
func searchViewAnchestorsFor<ViewType: UIView>() -> ViewType? {
if let matchingView = superview as? ViewType {
return matchingView
} else {
return superview?.searchViewAnchestorsFor()
}
}
func printViewHierarchyInformation(_ level: Int = 0) {
printViewInformation(level)
subviews.forEach { $0.printViewHierarchyInformation(level + 1) }
}
func printViewInformation(_ level: Int) {
let leadingWhitespace = String(repeating: " ", count: level)
let className = "\(Self.self)"
let superclassName = "\(superclass!)"
let frame = "\(self.frame)"
let id = (accessibilityIdentifier == nil) ? "" : " `\(accessibilityIdentifier!)`"
print("\(leadingWhitespace)\(className): \(superclassName)\(id) \(frame)")
}
}

View File

@ -1,56 +0,0 @@
//
// RefreshControl.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 18/09/2021.
//
import Combine
import Foundation
import SwiftUI
import UIKit
final class RefreshControl: ObservableObject {
static var navigationBarTitleDisplayMode: NavigationBarItem.TitleDisplayMode {
if #available(iOS 15.0, *) {
return .automatic
}
return .inline
}
let onValueChanged: (_ refreshControl: UIRefreshControl) -> Void
internal init(onValueChanged: @escaping ((UIRefreshControl) -> Void)) {
self.onValueChanged = onValueChanged
}
/// Adds a `UIRefreshControl` to the `UIScrollView` provided.
func add(to scrollView: UIScrollView) {
scrollView.refreshControl = UIRefreshControl().withTarget(
self,
action: #selector(onValueChangedAction),
for: .valueChanged
)
.testable(as: "RefreshControl")
}
@objc private func onValueChangedAction(sender: UIRefreshControl) {
onValueChanged(sender)
}
}
extension UIRefreshControl {
/// Convinience method to assign target action inline.
func withTarget(_ target: Any?, action: Selector, for controlEvents: UIControl.Event) -> UIRefreshControl {
addTarget(target, action: action, for: controlEvents)
return self
}
/// Convinience method to match refresh control for UI testing.
func testable(as id: String) -> UIRefreshControl {
isAccessibilityElement = true
accessibilityIdentifier = id
return self
}
}

View File

@ -1,46 +0,0 @@
//
// RefreshControlModifier.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 18/09/2021.
//
import Foundation
import SwiftUI
struct RefreshControlModifier: ViewModifier {
@State private var geometryReaderFrame: CGRect = .zero
let refreshControl: RefreshControl
internal init(onValueChanged: @escaping (UIRefreshControl) -> Void) {
refreshControl = RefreshControl(onValueChanged: onValueChanged)
}
func body(content: Content) -> some View {
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
return content
} else {
return content
.background(
GeometryReader { geometry in
ScrollViewMatcher(
onResolve: { scrollView in
refreshControl.add(to: scrollView)
},
geometryReaderFrame: $geometryReaderFrame
)
.preference(key: FramePreferenceKey.self, value: geometry.frame(in: .global))
.onPreferenceChange(FramePreferenceKey.self) { frame in
self.geometryReaderFrame = frame
}
}
)
}
}
}
extension View {
func refreshControl(onValueChanged: @escaping (_ refreshControl: UIRefreshControl) -> Void) -> some View {
modifier(RefreshControlModifier(onValueChanged: onValueChanged))
}
}

View File

@ -1,18 +0,0 @@
//
// FramePreferenceKey.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 21/09/2021.
//
import Foundation
import SwiftUI
struct FramePreferenceKey: PreferenceKey {
typealias Value = CGRect
static var defaultValue = CGRect.zero
static func reduce(value: inout CGRect, nextValue: () -> CGRect) {
value = nextValue()
}
}

View File

@ -1,106 +0,0 @@
//
// ScrollViewMatcher.swift
// SwiftUI_Pull_to_Refresh
//
// Created by Geri Borbás on 17/09/2021.
//
import Foundation
import SwiftUI
final class ScrollViewMatcher: UIViewControllerRepresentable {
let onMatch: (UIScrollView) -> Void
@Binding var geometryReaderFrame: CGRect
init(onResolve: @escaping (UIScrollView) -> Void, geometryReaderFrame: Binding<CGRect>) {
onMatch = onResolve
_geometryReaderFrame = geometryReaderFrame
}
func makeUIViewController(context _: Context) -> ScrollViewMatcherViewController {
ScrollViewMatcherViewController(onResolve: onMatch, geometryReaderFrame: geometryReaderFrame)
}
func updateUIViewController(_ viewController: ScrollViewMatcherViewController, context _: Context) {
viewController.geometryReaderFrame = geometryReaderFrame
}
}
final class ScrollViewMatcherViewController: UIViewController {
let onMatch: (UIScrollView) -> Void
private var scrollView: UIScrollView? {
didSet {
if oldValue != scrollView,
let scrollView
{
onMatch(scrollView)
}
}
}
var geometryReaderFrame: CGRect {
didSet {
match()
}
}
init(onResolve: @escaping (UIScrollView) -> Void, geometryReaderFrame: CGRect, debug _: Bool = false) {
onMatch = onResolve
self.geometryReaderFrame = geometryReaderFrame
super.init(nibName: nil, bundle: nil)
}
@available(*, unavailable)
required init?(coder _: NSCoder) {
fatalError("Use init(onMatch:) to instantiate ScrollViewMatcherViewController.")
}
func match() {
// matchUsingHierarchy()
matchUsingGeometry()
}
func matchUsingHierarchy() {
if parent != nil {
// Lookup view ancestry for any `UIScrollView`.
view.searchViewAnchestorsFor { (scrollView: UIScrollView) in
self.scrollView = scrollView
}
}
}
func matchUsingGeometry() {
if let parent {
if let scrollViewsInHierarchy: [UIScrollView] = parent.view.viewsInHierarchy() {
// Return first match if only a single scroll view is found in the hierarchy.
if scrollViewsInHierarchy.count == 1,
let firstScrollViewInHierarchy = scrollViewsInHierarchy.first
{
scrollView = firstScrollViewInHierarchy
// Filter by frame origins if multiple matches found.
} else {
if let firstMatchingFrameOrigin = scrollViewsInHierarchy.filter({
$0.globalFrame.origin.close(to: geometryReaderFrame.origin)
}).first {
scrollView = firstMatchingFrameOrigin
}
}
}
}
}
override func didMove(toParent parent: UIViewController?) {
super.didMove(toParent: parent)
match()
}
}
extension CGPoint {
/// Returns `true` if this point is close the other point (considering a ~1 pt tolerance).
func close(to point: CGPoint) -> Bool {
let inset = Double(1)
let rect = CGRect(x: x - inset, y: y - inset, width: inset * 2, height: inset * 2)
return rect.contains(point)
}
}

View File

@ -224,9 +224,7 @@
371F2F1A269B43D300E4A7AB /* NavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371F2F19269B43D300E4A7AB /* NavigationModel.swift */; }; 371F2F1A269B43D300E4A7AB /* NavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371F2F19269B43D300E4A7AB /* NavigationModel.swift */; };
371F2F1B269B43D300E4A7AB /* NavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371F2F19269B43D300E4A7AB /* NavigationModel.swift */; }; 371F2F1B269B43D300E4A7AB /* NavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371F2F19269B43D300E4A7AB /* NavigationModel.swift */; };
371F2F1C269B43D300E4A7AB /* NavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371F2F19269B43D300E4A7AB /* NavigationModel.swift */; }; 371F2F1C269B43D300E4A7AB /* NavigationModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 371F2F19269B43D300E4A7AB /* NavigationModel.swift */; };
3722AEBC274DA396005EA4D6 /* Badge+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBB274DA396005EA4D6 /* Badge+Backport.swift */; };
3722AEBE274DA401005EA4D6 /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBD274DA401005EA4D6 /* Backport.swift */; }; 3722AEBE274DA401005EA4D6 /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBD274DA401005EA4D6 /* Backport.swift */; };
3726386E2948A4B80043702D /* Badge+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBB274DA396005EA4D6 /* Badge+Backport.swift */; };
37270F1C28E06E3E00856150 /* String+Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37270F1B28E06E3E00856150 /* String+Localizable.swift */; }; 37270F1C28E06E3E00856150 /* String+Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37270F1B28E06E3E00856150 /* String+Localizable.swift */; };
37270F1D28E06E3E00856150 /* String+Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37270F1B28E06E3E00856150 /* String+Localizable.swift */; }; 37270F1D28E06E3E00856150 /* String+Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37270F1B28E06E3E00856150 /* String+Localizable.swift */; };
37270F1E28E06E3E00856150 /* String+Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37270F1B28E06E3E00856150 /* String+Localizable.swift */; }; 37270F1E28E06E3E00856150 /* String+Localizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37270F1B28E06E3E00856150 /* String+Localizable.swift */; };
@ -408,7 +406,6 @@
37579D5E27864F5F00FD0B98 /* Help.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37579D5C27864F5F00FD0B98 /* Help.swift */; }; 37579D5E27864F5F00FD0B98 /* Help.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37579D5C27864F5F00FD0B98 /* Help.swift */; };
37579D5F27864F5F00FD0B98 /* Help.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37579D5C27864F5F00FD0B98 /* Help.swift */; }; 37579D5F27864F5F00FD0B98 /* Help.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37579D5C27864F5F00FD0B98 /* Help.swift */; };
3758638A2721B0A9000CB14E /* ChannelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3743B86727216D3600261544 /* ChannelCell.swift */; }; 3758638A2721B0A9000CB14E /* ChannelCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3743B86727216D3600261544 /* ChannelCell.swift */; };
3759234628C26C7B00C052EC /* Refreshable+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3759234528C26C7B00C052EC /* Refreshable+Backport.swift */; };
37599F30272B42810087F250 /* FavoriteItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37599F2F272B42810087F250 /* FavoriteItem.swift */; }; 37599F30272B42810087F250 /* FavoriteItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37599F2F272B42810087F250 /* FavoriteItem.swift */; };
37599F31272B42810087F250 /* FavoriteItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37599F2F272B42810087F250 /* FavoriteItem.swift */; }; 37599F31272B42810087F250 /* FavoriteItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37599F2F272B42810087F250 /* FavoriteItem.swift */; };
37599F32272B42810087F250 /* FavoriteItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37599F2F272B42810087F250 /* FavoriteItem.swift */; }; 37599F32272B42810087F250 /* FavoriteItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37599F2F272B42810087F250 /* FavoriteItem.swift */; };
@ -584,9 +581,6 @@
377ABC48286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; }; 377ABC48286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; };
377ABC49286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; }; 377ABC49286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; };
377ABC4A286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; }; 377ABC4A286E5887009C986F /* Sequence+Unique.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377ABC47286E5887009C986F /* Sequence+Unique.swift */; };
377E17142928265900894889 /* ListRowSeparator+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377E17132928265900894889 /* ListRowSeparator+Backport.swift */; };
377E17152928265900894889 /* ListRowSeparator+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377E17132928265900894889 /* ListRowSeparator+Backport.swift */; };
377E17162928265900894889 /* ListRowSeparator+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377E17132928265900894889 /* ListRowSeparator+Backport.swift */; };
377F9F74294403770043F856 /* Cache in Frameworks */ = {isa = PBXBuildFile; productRef = 377F9F73294403770043F856 /* Cache */; }; 377F9F74294403770043F856 /* Cache in Frameworks */ = {isa = PBXBuildFile; productRef = 377F9F73294403770043F856 /* Cache */; };
377F9F76294403880043F856 /* Cache in Frameworks */ = {isa = PBXBuildFile; productRef = 377F9F75294403880043F856 /* Cache */; }; 377F9F76294403880043F856 /* Cache in Frameworks */ = {isa = PBXBuildFile; productRef = 377F9F75294403880043F856 /* Cache */; };
377F9F7B294403F20043F856 /* VideosCacheModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377F9F7A294403F20043F856 /* VideosCacheModel.swift */; }; 377F9F7B294403F20043F856 /* VideosCacheModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 377F9F7A294403F20043F856 /* VideosCacheModel.swift */; };
@ -630,12 +624,8 @@
3788AC2726F6840700F6BAA9 /* FavoriteItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */; }; 3788AC2726F6840700F6BAA9 /* FavoriteItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */; };
3788AC2826F6840700F6BAA9 /* FavoriteItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */; }; 3788AC2826F6840700F6BAA9 /* FavoriteItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */; };
3788AC2926F6840700F6BAA9 /* FavoriteItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */; }; 3788AC2926F6840700F6BAA9 /* FavoriteItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3788AC2626F6840700F6BAA9 /* FavoriteItemView.swift */; };
378AE93A274EDFAF006A4EE1 /* Badge+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBB274DA396005EA4D6 /* Badge+Backport.swift */; };
378AE93C274EDFB2006A4EE1 /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBD274DA401005EA4D6 /* Backport.swift */; }; 378AE93C274EDFB2006A4EE1 /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBD274DA401005EA4D6 /* Backport.swift */; };
378AE93D274EDFB3006A4EE1 /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBD274DA401005EA4D6 /* Backport.swift */; }; 378AE93D274EDFB3006A4EE1 /* Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBD274DA401005EA4D6 /* Backport.swift */; };
378AE93E274EDFB4006A4EE1 /* Tint+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBF274DAEB8005EA4D6 /* Tint+Backport.swift */; };
378AE93F274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBF274DAEB8005EA4D6 /* Tint+Backport.swift */; };
378AE940274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3722AEBF274DAEB8005EA4D6 /* Tint+Backport.swift */; };
378AE943274EF00A006A4EE1 /* Color+Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378AE942274EF00A006A4EE1 /* Color+Background.swift */; }; 378AE943274EF00A006A4EE1 /* Color+Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378AE942274EF00A006A4EE1 /* Color+Background.swift */; };
378AE944274EF00A006A4EE1 /* Color+Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378AE942274EF00A006A4EE1 /* Color+Background.swift */; }; 378AE944274EF00A006A4EE1 /* Color+Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378AE942274EF00A006A4EE1 /* Color+Background.swift */; };
378AE945274EF00A006A4EE1 /* Color+Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378AE942274EF00A006A4EE1 /* Color+Background.swift */; }; 378AE945274EF00A006A4EE1 /* Color+Background.swift in Sources */ = {isa = PBXBuildFile; fileRef = 378AE942274EF00A006A4EE1 /* Color+Background.swift */; };
@ -920,14 +910,6 @@
37DD9DA32785BBC900539416 /* NoCommentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DA22785BBC900539416 /* NoCommentsView.swift */; }; 37DD9DA32785BBC900539416 /* NoCommentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DA22785BBC900539416 /* NoCommentsView.swift */; };
37DD9DA42785BBC900539416 /* NoCommentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DA22785BBC900539416 /* NoCommentsView.swift */; }; 37DD9DA42785BBC900539416 /* NoCommentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DA22785BBC900539416 /* NoCommentsView.swift */; };
37DD9DA52785BBC900539416 /* NoCommentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DA22785BBC900539416 /* NoCommentsView.swift */; }; 37DD9DA52785BBC900539416 /* NoCommentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DA22785BBC900539416 /* NoCommentsView.swift */; };
37DD9DB12785D58D00539416 /* RefreshControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DAF2785D58D00539416 /* RefreshControl.swift */; };
37DD9DB42785D58D00539416 /* RefreshControlModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DB02785D58D00539416 /* RefreshControlModifier.swift */; };
37DD9DBA2785D60300539416 /* FramePreferenceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DB82785D60200539416 /* FramePreferenceKey.swift */; };
37DD9DBB2785D60300539416 /* FramePreferenceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DB82785D60200539416 /* FramePreferenceKey.swift */; };
37DD9DBC2785D60300539416 /* FramePreferenceKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DB82785D60200539416 /* FramePreferenceKey.swift */; };
37DD9DBD2785D60300539416 /* ScrollViewMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DB92785D60200539416 /* ScrollViewMatcher.swift */; };
37DD9DC62785D63A00539416 /* UIResponder+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DC22785D63A00539416 /* UIResponder+Extensions.swift */; };
37DD9DCB2785E28C00539416 /* UIView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37DD9DC12785D63A00539416 /* UIView+Extensions.swift */; };
37E04C0F275940FB00172673 /* VerticalScrollingFix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E04C0E275940FB00172673 /* VerticalScrollingFix.swift */; }; 37E04C0F275940FB00172673 /* VerticalScrollingFix.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E04C0E275940FB00172673 /* VerticalScrollingFix.swift */; };
37E084AC2753D95F00039B7D /* AccountsNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */; }; 37E084AC2753D95F00039B7D /* AccountsNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */; };
37E084AD2753D95F00039B7D /* AccountsNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */; }; 37E084AD2753D95F00039B7D /* AccountsNavigationLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */; };
@ -1220,9 +1202,7 @@
371CC76F29468BDC00979C1A /* SettingsButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsButtons.swift; sourceTree = "<group>"; }; 371CC76F29468BDC00979C1A /* SettingsButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsButtons.swift; sourceTree = "<group>"; };
371CC7732946963000979C1A /* ListingStyleButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListingStyleButtons.swift; sourceTree = "<group>"; }; 371CC7732946963000979C1A /* ListingStyleButtons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListingStyleButtons.swift; sourceTree = "<group>"; };
371F2F19269B43D300E4A7AB /* NavigationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationModel.swift; sourceTree = "<group>"; }; 371F2F19269B43D300E4A7AB /* NavigationModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationModel.swift; sourceTree = "<group>"; };
3722AEBB274DA396005EA4D6 /* Badge+Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Badge+Backport.swift"; sourceTree = "<group>"; };
3722AEBD274DA401005EA4D6 /* Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Backport.swift; sourceTree = "<group>"; }; 3722AEBD274DA401005EA4D6 /* Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Backport.swift; sourceTree = "<group>"; };
3722AEBF274DAEB8005EA4D6 /* Tint+Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Tint+Backport.swift"; sourceTree = "<group>"; };
37270F1B28E06E3E00856150 /* String+Localizable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Localizable.swift"; sourceTree = "<group>"; }; 37270F1B28E06E3E00856150 /* String+Localizable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+Localizable.swift"; sourceTree = "<group>"; };
3727B74727872A500021C15E /* VisualEffectBlur-macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VisualEffectBlur-macOS.swift"; sourceTree = "<group>"; }; 3727B74727872A500021C15E /* VisualEffectBlur-macOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VisualEffectBlur-macOS.swift"; sourceTree = "<group>"; };
3727B74927872A920021C15E /* VisualEffectBlur-iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VisualEffectBlur-iOS.swift"; sourceTree = "<group>"; }; 3727B74927872A920021C15E /* VisualEffectBlur-iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VisualEffectBlur-iOS.swift"; sourceTree = "<group>"; };
@ -1301,7 +1281,6 @@
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>"; };
3759234528C26C7B00C052EC /* Refreshable+Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Refreshable+Backport.swift"; sourceTree = "<group>"; };
37599F2F272B42810087F250 /* FavoriteItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteItem.swift; sourceTree = "<group>"; }; 37599F2F272B42810087F250 /* FavoriteItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteItem.swift; sourceTree = "<group>"; };
37599F33272B44000087F250 /* FavoritesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritesModel.swift; sourceTree = "<group>"; }; 37599F33272B44000087F250 /* FavoritesModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritesModel.swift; sourceTree = "<group>"; };
37599F37272B4D740087F250 /* FavoriteButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteButton.swift; sourceTree = "<group>"; }; 37599F37272B4D740087F250 /* FavoriteButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoriteButton.swift; sourceTree = "<group>"; };
@ -1362,7 +1341,6 @@
377ABC3F286E4AD5009C986F /* InstancesManifest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstancesManifest.swift; sourceTree = "<group>"; }; 377ABC3F286E4AD5009C986F /* InstancesManifest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InstancesManifest.swift; sourceTree = "<group>"; };
377ABC43286E4B74009C986F /* ManifestedInstance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManifestedInstance.swift; sourceTree = "<group>"; }; 377ABC43286E4B74009C986F /* ManifestedInstance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManifestedInstance.swift; sourceTree = "<group>"; };
377ABC47286E5887009C986F /* Sequence+Unique.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sequence+Unique.swift"; sourceTree = "<group>"; }; 377ABC47286E5887009C986F /* Sequence+Unique.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Sequence+Unique.swift"; sourceTree = "<group>"; };
377E17132928265900894889 /* ListRowSeparator+Backport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ListRowSeparator+Backport.swift"; sourceTree = "<group>"; };
377F9F7A294403F20043F856 /* VideosCacheModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideosCacheModel.swift; sourceTree = "<group>"; }; 377F9F7A294403F20043F856 /* VideosCacheModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideosCacheModel.swift; sourceTree = "<group>"; };
377F9F7E2944175F0043F856 /* FeedCacheModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedCacheModel.swift; sourceTree = "<group>"; }; 377F9F7E2944175F0043F856 /* FeedCacheModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeedCacheModel.swift; sourceTree = "<group>"; };
377FF88A291A60310028EB0B /* OpenVideosModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVideosModel.swift; sourceTree = "<group>"; }; 377FF88A291A60310028EB0B /* OpenVideosModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenVideosModel.swift; sourceTree = "<group>"; };
@ -1501,12 +1479,6 @@
37DCD3162A191A180059A470 /* AVPlayerViewController+FullScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AVPlayerViewController+FullScreen.swift"; sourceTree = "<group>"; }; 37DCD3162A191A180059A470 /* AVPlayerViewController+FullScreen.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AVPlayerViewController+FullScreen.swift"; sourceTree = "<group>"; };
37DD87C6271C9CFE0027CBF9 /* PlayerStreams.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerStreams.swift; sourceTree = "<group>"; }; 37DD87C6271C9CFE0027CBF9 /* PlayerStreams.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerStreams.swift; sourceTree = "<group>"; };
37DD9DA22785BBC900539416 /* NoCommentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoCommentsView.swift; sourceTree = "<group>"; }; 37DD9DA22785BBC900539416 /* NoCommentsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoCommentsView.swift; sourceTree = "<group>"; };
37DD9DAF2785D58D00539416 /* RefreshControl.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshControl.swift; sourceTree = "<group>"; };
37DD9DB02785D58D00539416 /* RefreshControlModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RefreshControlModifier.swift; sourceTree = "<group>"; };
37DD9DB82785D60200539416 /* FramePreferenceKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FramePreferenceKey.swift; sourceTree = "<group>"; };
37DD9DB92785D60200539416 /* ScrollViewMatcher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScrollViewMatcher.swift; sourceTree = "<group>"; };
37DD9DC12785D63A00539416 /* UIView+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+Extensions.swift"; sourceTree = "<group>"; };
37DD9DC22785D63A00539416 /* UIResponder+Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIResponder+Extensions.swift"; sourceTree = "<group>"; };
37E04C0E275940FB00172673 /* VerticalScrollingFix.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalScrollingFix.swift; sourceTree = "<group>"; }; 37E04C0E275940FB00172673 /* VerticalScrollingFix.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VerticalScrollingFix.swift; sourceTree = "<group>"; };
37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsNavigationLink.swift; sourceTree = "<group>"; }; 37E084AB2753D95F00039B7D /* AccountsNavigationLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountsNavigationLink.swift; sourceTree = "<group>"; };
37E64DD026D597EB00C71877 /* SubscribedChannelsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscribedChannelsModel.swift; sourceTree = "<group>"; }; 37E64DD026D597EB00C71877 /* SubscribedChannelsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubscribedChannelsModel.swift; sourceTree = "<group>"; };
@ -1936,13 +1908,9 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
3722AEBD274DA401005EA4D6 /* Backport.swift */, 3722AEBD274DA401005EA4D6 /* Backport.swift */,
3722AEBB274DA396005EA4D6 /* Badge+Backport.swift */,
377E17132928265900894889 /* ListRowSeparator+Backport.swift */,
37136CAB286273060095C0CF /* PersistentSystemOverlays+Backport.swift */, 37136CAB286273060095C0CF /* PersistentSystemOverlays+Backport.swift */,
3759234528C26C7B00C052EC /* Refreshable+Backport.swift */,
37E80F3F287B472300561799 /* ScrollContentBackground+Backport.swift */, 37E80F3F287B472300561799 /* ScrollContentBackground+Backport.swift */,
376E331128AD3B320070E30C /* ScrollDismissesKeyboard+Backport.swift */, 376E331128AD3B320070E30C /* ScrollDismissesKeyboard+Backport.swift */,
3722AEBF274DAEB8005EA4D6 /* Tint+Backport.swift */,
37B7CFE82A19603B001B0564 /* ToolbarBackground+Backport.swift */, 37B7CFE82A19603B001B0564 /* ToolbarBackground+Backport.swift */,
37B7CFEA2A1960EC001B0564 /* ToolbarColorScheme+Backport.swift */, 37B7CFEA2A1960EC001B0564 /* ToolbarColorScheme+Backport.swift */,
3727B74927872A920021C15E /* VisualEffectBlur-iOS.swift */, 3727B74927872A920021C15E /* VisualEffectBlur-iOS.swift */,
@ -2470,40 +2438,10 @@
path = Model; path = Model;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
37DD9DAE2785D58D00539416 /* RefreshControl */ = {
isa = PBXGroup;
children = (
37DD9DC02785D63A00539416 /* Extensions */,
37DD9DB72785D60200539416 /* ScrollViewMatcher */,
37DD9DAF2785D58D00539416 /* RefreshControl.swift */,
37DD9DB02785D58D00539416 /* RefreshControlModifier.swift */,
);
path = RefreshControl;
sourceTree = "<group>";
};
37DD9DB72785D60200539416 /* ScrollViewMatcher */ = {
isa = PBXGroup;
children = (
37DD9DB82785D60200539416 /* FramePreferenceKey.swift */,
37DD9DB92785D60200539416 /* ScrollViewMatcher.swift */,
);
path = ScrollViewMatcher;
sourceTree = "<group>";
};
37DD9DC02785D63A00539416 /* Extensions */ = {
isa = PBXGroup;
children = (
37DD9DC22785D63A00539416 /* UIResponder+Extensions.swift */,
37DD9DC12785D63A00539416 /* UIView+Extensions.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
37DD9DCC2785EE6F00539416 /* Vendor */ = { 37DD9DCC2785EE6F00539416 /* Vendor */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
3749BF6C27ADA135000480FF /* mpv */, 3749BF6C27ADA135000480FF /* mpv */,
37DD9DAE2785D58D00539416 /* RefreshControl */,
); );
path = Vendor; path = Vendor;
sourceTree = "<group>"; sourceTree = "<group>";
@ -2806,7 +2744,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
BuildIndependentTargetsInParallel = 1; BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1410; LastSwiftUpdateCheck = 1500;
LastUpgradeCheck = 1410; LastUpgradeCheck = 1410;
TargetAttributes = { TargetAttributes = {
37095E7E291DC85400301883 = { 37095E7E291DC85400301883 = {
@ -3147,12 +3085,10 @@
37BD07B52698AA4D003EBB87 /* ContentView.swift in Sources */, 37BD07B52698AA4D003EBB87 /* ContentView.swift in Sources */,
37D2E0D428B67EFC00F64D52 /* Delay.swift in Sources */, 37D2E0D428B67EFC00F64D52 /* Delay.swift in Sources */,
3776925229463C310055EC18 /* PlaylistsCacheModel.swift in Sources */, 3776925229463C310055EC18 /* PlaylistsCacheModel.swift in Sources */,
3759234628C26C7B00C052EC /* Refreshable+Backport.swift in Sources */,
374924ED2921669B0017D862 /* PreferenceKeys.swift in Sources */, 374924ED2921669B0017D862 /* PreferenceKeys.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 */,
37DD9DCB2785E28C00539416 /* UIView+Extensions.swift in Sources */,
377FF88F291A99580028EB0B /* HistoryView.swift in Sources */, 377FF88F291A99580028EB0B /* HistoryView.swift in Sources */,
3782B94F27553A6700990149 /* SearchSuggestions.swift in Sources */, 3782B94F27553A6700990149 /* SearchSuggestions.swift in Sources */,
378E50FF26FE8EEE00F49626 /* AccountViewButton.swift in Sources */, 378E50FF26FE8EEE00F49626 /* AccountViewButton.swift in Sources */,
@ -3188,7 +3124,6 @@
37B81AF926D2C9A700675966 /* VideoPlayerSizeModifier.swift in Sources */, 37B81AF926D2C9A700675966 /* VideoPlayerSizeModifier.swift in Sources */,
37C0698227260B2100F7F6CB /* ThumbnailsModel.swift in Sources */, 37C0698227260B2100F7F6CB /* ThumbnailsModel.swift in Sources */,
37BC50A82778A84700510953 /* HistorySettings.swift in Sources */, 37BC50A82778A84700510953 /* HistorySettings.swift in Sources */,
37DD9DB12785D58D00539416 /* RefreshControl.swift in Sources */,
37BDFF1F29488117000C6404 /* ChannelPlaylistListItem.swift in Sources */, 37BDFF1F29488117000C6404 /* ChannelPlaylistListItem.swift in Sources */,
371CC76C29466F5A00979C1A /* AccountsViewModel.swift in Sources */, 371CC76C29466F5A00979C1A /* AccountsViewModel.swift in Sources */,
37B4E805277D0AB4004BF56A /* Orientation.swift in Sources */, 37B4E805277D0AB4004BF56A /* Orientation.swift in Sources */,
@ -3203,7 +3138,6 @@
378AE943274EF00A006A4EE1 /* Color+Background.swift in Sources */, 378AE943274EF00A006A4EE1 /* Color+Background.swift in Sources */,
37F4AE7226828F0900BD60EA /* VerticalCells.swift in Sources */, 37F4AE7226828F0900BD60EA /* VerticalCells.swift in Sources */,
376578852685429C00D4EA09 /* CaseIterable+Next.swift in Sources */, 376578852685429C00D4EA09 /* CaseIterable+Next.swift in Sources */,
3722AEBC274DA396005EA4D6 /* Badge+Backport.swift in Sources */,
3748186626A7627F0084E870 /* Video+Fixtures.swift in Sources */, 3748186626A7627F0084E870 /* Video+Fixtures.swift in Sources */,
37599F34272B44000087F250 /* FavoritesModel.swift in Sources */, 37599F34272B44000087F250 /* FavoritesModel.swift in Sources */,
3717407D2949D40800FDDBC7 /* ChannelLinkView.swift in Sources */, 3717407D2949D40800FDDBC7 /* ChannelLinkView.swift in Sources */,
@ -3216,10 +3150,8 @@
3751B4B227836902000B7DF4 /* SearchPage.swift in Sources */, 3751B4B227836902000B7DF4 /* SearchPage.swift in Sources */,
37CC3F4C270CFE1700608308 /* PlayerQueueView.swift in Sources */, 37CC3F4C270CFE1700608308 /* PlayerQueueView.swift in Sources */,
37FFC440272734C3009FFD26 /* Throttle.swift in Sources */, 37FFC440272734C3009FFD26 /* Throttle.swift in Sources */,
37DD9DB42785D58D00539416 /* RefreshControlModifier.swift in Sources */,
3709528A29283E14001ECA40 /* NoDocumentsView.swift in Sources */, 3709528A29283E14001ECA40 /* NoDocumentsView.swift in Sources */,
3705B182267B4E4900704544 /* TrendingCategory.swift in Sources */, 3705B182267B4E4900704544 /* TrendingCategory.swift in Sources */,
378AE940274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */,
376BE50927347B5F009AD608 /* SettingsHeader.swift in Sources */, 376BE50927347B5F009AD608 /* SettingsHeader.swift in Sources */,
376527BB285F60F700102284 /* PlayerTimeModel.swift in Sources */, 376527BB285F60F700102284 /* PlayerTimeModel.swift in Sources */,
37270F1C28E06E3E00856150 /* String+Localizable.swift in Sources */, 37270F1C28E06E3E00856150 /* String+Localizable.swift in Sources */,
@ -3267,7 +3199,6 @@
37BC50AC2778BCBA00510953 /* HistoryModel.swift in Sources */, 37BC50AC2778BCBA00510953 /* HistoryModel.swift in Sources */,
37AAF29026740715007FC770 /* Channel.swift in Sources */, 37AAF29026740715007FC770 /* Channel.swift in Sources */,
37F5C7E02A1E2AF300927B73 /* ListView.swift in Sources */, 37F5C7E02A1E2AF300927B73 /* ListView.swift in Sources */,
37DD9DBA2785D60300539416 /* FramePreferenceKey.swift in Sources */,
3748186A26A764FB0084E870 /* Thumbnail+Fixtures.swift in Sources */, 3748186A26A764FB0084E870 /* Thumbnail+Fixtures.swift in Sources */,
37B81AFF26D2CA3700675966 /* VideoDetails.swift in Sources */, 37B81AFF26D2CA3700675966 /* VideoDetails.swift in Sources */,
377FC7E5267A084E00A6BBAF /* SearchView.swift in Sources */, 377FC7E5267A084E00A6BBAF /* SearchView.swift in Sources */,
@ -3316,7 +3247,6 @@
37DCD3152A18F7630059A470 /* SafeAreaModel.swift in Sources */, 37DCD3152A18F7630059A470 /* SafeAreaModel.swift in Sources */,
37D526DE2720AC4400ED2F5E /* VideosAPI.swift in Sources */, 37D526DE2720AC4400ED2F5E /* VideosAPI.swift in Sources */,
37484C2526FC83E000287258 /* InstanceForm.swift in Sources */, 37484C2526FC83E000287258 /* InstanceForm.swift in Sources */,
37DD9DBD2785D60300539416 /* ScrollViewMatcher.swift in Sources */,
37B767DB2677C3CA0098BAA8 /* PlayerModel.swift in Sources */, 37B767DB2677C3CA0098BAA8 /* PlayerModel.swift in Sources */,
371CC7742946963000979C1A /* ListingStyleButtons.swift in Sources */, 371CC7742946963000979C1A /* ListingStyleButtons.swift in Sources */,
3788AC2726F6840700F6BAA9 /* FavoriteItemView.swift in Sources */, 3788AC2726F6840700F6BAA9 /* FavoriteItemView.swift in Sources */,
@ -3325,10 +3255,8 @@
373031F528383A89000CFD59 /* PiPDelegate.swift in Sources */, 373031F528383A89000CFD59 /* PiPDelegate.swift in Sources */,
37F5E8BA291BEF69006C15F5 /* BaseCacheModel.swift in Sources */, 37F5E8BA291BEF69006C15F5 /* BaseCacheModel.swift in Sources */,
371AC09F294D13AA0085989E /* UnwatchedFeedCountModel.swift in Sources */, 371AC09F294D13AA0085989E /* UnwatchedFeedCountModel.swift in Sources */,
37DD9DC62785D63A00539416 /* UIResponder+Extensions.swift in Sources */,
370015A928BBAE7F000149FD /* ProgressBar.swift in Sources */, 370015A928BBAE7F000149FD /* ProgressBar.swift in Sources */,
37C3A24927235FAA0087A57A /* ChannelPlaylistCell.swift in Sources */, 37C3A24927235FAA0087A57A /* ChannelPlaylistCell.swift in Sources */,
377E17142928265900894889 /* ListRowSeparator+Backport.swift in Sources */,
373CFACB26966264003CB2C6 /* SearchQuery.swift in Sources */, 373CFACB26966264003CB2C6 /* SearchQuery.swift in Sources */,
37F7AB4D28A9361F00FB46B5 /* UIDevice+Cellular.swift in Sources */, 37F7AB4D28A9361F00FB46B5 /* UIDevice+Cellular.swift in Sources */,
37141673267A8E10006CA35D /* Country.swift in Sources */, 37141673267A8E10006CA35D /* Country.swift in Sources */,
@ -3409,7 +3337,6 @@
374710062755291C00CE0F87 /* SearchTextField.swift in Sources */, 374710062755291C00CE0F87 /* SearchTextField.swift in Sources */,
37B7CFEC2A197844001B0564 /* AppleAVPlayerView.swift in Sources */, 37B7CFEC2A197844001B0564 /* AppleAVPlayerView.swift in Sources */,
37F0F4EB286F397E00C06C2E /* SettingsModel.swift in Sources */, 37F0F4EB286F397E00C06C2E /* SettingsModel.swift in Sources */,
378AE93F274EDFB5006A4EE1 /* Tint+Backport.swift in Sources */,
379ACB4D2A1F8A4100E01914 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */, 379ACB4D2A1F8A4100E01914 /* NSManagedObjectContext+ExecuteAndMergeChanges.swift in Sources */,
37C194C826F6A9C8005D3B96 /* RecentsModel.swift in Sources */, 37C194C826F6A9C8005D3B96 /* RecentsModel.swift in Sources */,
37737786276F9858000521C1 /* Windows.swift in Sources */, 37737786276F9858000521C1 /* Windows.swift in Sources */,
@ -3461,7 +3388,6 @@
3784CDE327772EE40055BBF2 /* Watch.swift in Sources */, 3784CDE327772EE40055BBF2 /* Watch.swift in Sources */,
371AC0B7294D1D6E0085989E /* PlayingIndicatorView.swift in Sources */, 371AC0B7294D1D6E0085989E /* PlayingIndicatorView.swift in Sources */,
37E80F3D287B107F00561799 /* VideoDetailsOverlay.swift in Sources */, 37E80F3D287B107F00561799 /* VideoDetailsOverlay.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 */, 37D2E0D128B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */,
@ -3491,7 +3417,6 @@
37EAD870267B9ED100D9E01B /* Segment.swift in Sources */, 37EAD870267B9ED100D9E01B /* Segment.swift in Sources */,
3788AC2826F6840700F6BAA9 /* FavoriteItemView.swift in Sources */, 3788AC2826F6840700F6BAA9 /* FavoriteItemView.swift in Sources */,
377FF88C291A60310028EB0B /* OpenVideosModel.swift in Sources */, 377FF88C291A60310028EB0B /* OpenVideosModel.swift in Sources */,
378AE93A274EDFAF006A4EE1 /* Badge+Backport.swift in Sources */,
37599F35272B44000087F250 /* FavoritesModel.swift in Sources */, 37599F35272B44000087F250 /* FavoritesModel.swift in Sources */,
376527BC285F60F700102284 /* PlayerTimeModel.swift in Sources */, 376527BC285F60F700102284 /* PlayerTimeModel.swift in Sources */,
37F64FE526FE70A60081B69E /* RedrawOnModifier.swift in Sources */, 37F64FE526FE70A60081B69E /* RedrawOnModifier.swift in Sources */,
@ -3553,7 +3478,6 @@
3748186F26A769D60084E870 /* DetailBadge.swift in Sources */, 3748186F26A769D60084E870 /* DetailBadge.swift in Sources */,
3744A96128B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */, 3744A96128B99ADD005DE0A7 /* PlayerControlsLayout.swift in Sources */,
372915E72687E3B900F5A35B /* Defaults.swift in Sources */, 372915E72687E3B900F5A35B /* Defaults.swift in Sources */,
377E17152928265900894889 /* ListRowSeparator+Backport.swift in Sources */,
371CC76929466ED000979C1A /* AccountsView.swift in Sources */, 371CC76929466ED000979C1A /* AccountsView.swift in Sources */,
37C3A242272359900087A57A /* Double+Format.swift in Sources */, 37C3A242272359900087A57A /* Double+Format.swift in Sources */,
37B795912771DAE0001CF27B /* OpenURLHandler.swift in Sources */, 37B795912771DAE0001CF27B /* OpenURLHandler.swift in Sources */,
@ -3740,7 +3664,6 @@
375EC95F289EEEE000751258 /* QualityProfile.swift in Sources */, 375EC95F289EEEE000751258 /* QualityProfile.swift in Sources */,
37EAD871267B9ED100D9E01B /* Segment.swift in Sources */, 37EAD871267B9ED100D9E01B /* Segment.swift in Sources */,
373C8FE6275B955100CB5936 /* CommentsPage.swift in Sources */, 373C8FE6275B955100CB5936 /* CommentsPage.swift in Sources */,
37DD9DBC2785D60300539416 /* FramePreferenceKey.swift in Sources */,
375EC974289F2ABF00751258 /* MultiselectRow.swift in Sources */, 375EC974289F2ABF00751258 /* MultiselectRow.swift in Sources */,
37EBD8C827AF26B300F1C24B /* AVPlayerBackend.swift in Sources */, 37EBD8C827AF26B300F1C24B /* AVPlayerBackend.swift in Sources */,
378E9C3E2945565500B2D696 /* SubscriptionsView.swift in Sources */, 378E9C3E2945565500B2D696 /* SubscriptionsView.swift in Sources */,
@ -3794,7 +3717,6 @@
376BE50D27349108009AD608 /* BrowsingSettings.swift in Sources */, 376BE50D27349108009AD608 /* BrowsingSettings.swift in Sources */,
37CFB48728AFE2510070024C /* VideoDescription.swift in Sources */, 37CFB48728AFE2510070024C /* VideoDescription.swift in Sources */,
37DD87C9271C9CFE0027CBF9 /* PlayerStreams.swift in Sources */, 37DD87C9271C9CFE0027CBF9 /* PlayerStreams.swift in Sources */,
378AE93E274EDFB4006A4EE1 /* Tint+Backport.swift in Sources */,
37FFC442272734C3009FFD26 /* Throttle.swift in Sources */, 37FFC442272734C3009FFD26 /* Throttle.swift in Sources */,
377FF88D291A60310028EB0B /* OpenVideosModel.swift in Sources */, 377FF88D291A60310028EB0B /* OpenVideosModel.swift in Sources */,
37F4AD2828613B81004D0F66 /* Color+Debug.swift in Sources */, 37F4AD2828613B81004D0F66 /* Color+Debug.swift in Sources */,
@ -3935,7 +3857,6 @@
37D9BA0829507F69002586BD /* PlayerControlsSettings.swift in Sources */, 37D9BA0829507F69002586BD /* PlayerControlsSettings.swift in Sources */,
37599F32272B42810087F250 /* FavoriteItem.swift in Sources */, 37599F32272B42810087F250 /* FavoriteItem.swift in Sources */,
37E8B0EE27B326C00024006F /* TimelineView.swift in Sources */, 37E8B0EE27B326C00024006F /* TimelineView.swift in Sources */,
3726386E2948A4B80043702D /* Badge+Backport.swift in Sources */,
37141675267A8E10006CA35D /* Country.swift in Sources */, 37141675267A8E10006CA35D /* Country.swift in Sources */,
370F500C27CC1821001B35DC /* MPVViewController.swift in Sources */, 370F500C27CC1821001B35DC /* MPVViewController.swift in Sources */,
3782B9542755667600990149 /* String+Format.swift in Sources */, 3782B9542755667600990149 /* String+Format.swift in Sources */,
@ -3972,7 +3893,6 @@
3761ABFF26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */, 3761ABFF26F0F8DE00AA496F /* EnvironmentValues.swift in Sources */,
37C3A24F272360470087A57A /* ChannelPlaylist+Fixtures.swift in Sources */, 37C3A24F272360470087A57A /* ChannelPlaylist+Fixtures.swift in Sources */,
3718B9A02921A9620003DB2E /* VideoDetailsOverlay.swift in Sources */, 3718B9A02921A9620003DB2E /* VideoDetailsOverlay.swift in Sources */,
377E17162928265900894889 /* ListRowSeparator+Backport.swift in Sources */,
37FB28432721B22200A57617 /* ContentItem.swift in Sources */, 37FB28432721B22200A57617 /* ContentItem.swift in Sources */,
37D2E0D228B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */, 37D2E0D228B67DBC00F64D52 /* AnimationCompletionObserverModifier.swift in Sources */,
37AAF2A226741C97007FC770 /* FeedView.swift in Sources */, 37AAF2A226741C97007FC770 /* FeedView.swift in Sources */,
@ -4313,7 +4233,7 @@
INFOPLIST_KEY_UIRequiresFullScreen = YES; INFOPLIST_KEY_UIRequiresFullScreen = YES;
INFOPLIST_KEY_UIStatusBarHidden = NO; INFOPLIST_KEY_UIStatusBarHidden = NO;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 14.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@ -4363,7 +4283,7 @@
INFOPLIST_KEY_UIRequiresFullScreen = YES; INFOPLIST_KEY_UIRequiresFullScreen = YES;
INFOPLIST_KEY_UIStatusBarHidden = NO; INFOPLIST_KEY_UIStatusBarHidden = NO;
INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown"; INFOPLIST_KEY_UISupportedInterfaceOrientations = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortraitUpsideDown";
IPHONEOS_DEPLOYMENT_TARGET = 14.0; IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@ -4418,7 +4338,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Vendor/mpv/macOS/lib", "$(PROJECT_DIR)/Vendor/mpv/macOS/lib",
); );
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.5; MARKETING_VERSION = 1.5;
OTHER_LDFLAGS = "-Wl,-no_compact_unwind"; OTHER_LDFLAGS = "-Wl,-no_compact_unwind";
PRODUCT_BUNDLE_IDENTIFIER = stream.yattee.app; PRODUCT_BUNDLE_IDENTIFIER = stream.yattee.app;
@ -4461,7 +4381,7 @@
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Vendor/mpv/macOS/lib", "$(PROJECT_DIR)/Vendor/mpv/macOS/lib",
); );
MACOSX_DEPLOYMENT_TARGET = 11.0; MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.5; MARKETING_VERSION = 1.5;
OTHER_LDFLAGS = "-Wl,-no_compact_unwind"; OTHER_LDFLAGS = "-Wl,-no_compact_unwind";
PRODUCT_BUNDLE_IDENTIFIER = stream.yattee.app; PRODUCT_BUNDLE_IDENTIFIER = stream.yattee.app;

View File

@ -38,7 +38,7 @@ struct InstancesSettings: View {
if !selectedInstance.isNil, selectedInstance.app.supportsAccounts { if !selectedInstance.isNil, selectedInstance.app.supportsAccounts {
SettingsHeader(text: "Accounts".localized()) SettingsHeader(text: "Accounts".localized())
let list = List(selection: $selectedAccount) { List(selection: $selectedAccount) {
if selectedInstanceAccounts.isEmpty { if selectedInstanceAccounts.isEmpty {
Text("You have no accounts for this location") Text("You have no accounts for this location")
.foregroundColor(.secondary) .foregroundColor(.secondary)
@ -69,13 +69,7 @@ struct InstancesSettings: View {
.tag(account) .tag(account)
} }
} }
if #available(macOS 12.0, *) {
list
.listStyle(.inset(alternatesRowBackgrounds: true)) .listStyle(.inset(alternatesRowBackgrounds: true))
} else {
list
}
} }
if selectedInstance != nil, selectedInstance.app.hasFrontendURL { if selectedInstance != nil, selectedInstance.app.hasFrontendURL {

View File

@ -4,7 +4,6 @@ final class MPVOGLView: NSView {
override init(frame frameRect: CGRect) { override init(frame frameRect: CGRect) {
super.init(frame: frameRect) super.init(frame: frameRect)
autoresizingMask = [.width, .height] autoresizingMask = [.width, .height]
wantsBestResolutionOpenGLSurface = true
} }
@available(*, unavailable) @available(*, unavailable)