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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -175,24 +175,14 @@ struct QualitySettings: View {
}
}
if #available(macOS 12.0, *) {
#if os(macOS)
List {
list
}
.listStyle(.inset(alternatesRowBackgrounds: true))
#else
#if os(macOS)
List {
list
#endif
} else {
#if os(macOS)
List {
list
}
#else
list
#endif
}
}
.listStyle(.inset(alternatesRowBackgrounds: true))
#else
list
#endif
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -48,23 +48,19 @@ struct ThumbnailView: View {
}
@ViewBuilder var asyncImageIfAvailable: some View {
if #available(iOS 15, macOS 12, *) {
CachedAsyncImage(url: url, urlCache: BaseCacheModel.imageCache) { phase in
switch phase {
case let .success(image):
image
.resizable()
case .failure:
placeholder.onAppear {
guard let url else { return }
thumbnails.insertUnloadable(url)
}
default:
placeholder
CachedAsyncImage(url: url, urlCache: BaseCacheModel.imageCache, transaction: Transaction(animation: .default)) { phase in
switch phase {
case let .success(image):
image
.resizable()
case .failure:
placeholder.onAppear {
guard let url else { return }
thumbnails.insertUnloadable(url)
}
default:
placeholder
}
} else {
webImage
}
}

View File

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

View File

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

View File

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