Make unplayable tvOS media files focusable with unsupported alert

This commit is contained in:
Arkadiusz Fal
2026-04-17 05:59:00 +02:00
parent 4c8a3ee5ba
commit 39580d713b
3 changed files with 54 additions and 0 deletions

View File

@@ -4953,6 +4953,26 @@
}
}
},
"mediaBrowser.unsupportedFile.title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Unsupported file"
}
}
}
},
"mediaBrowser.unsupportedFile.message %@" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "%@ cannot be played. This file type is not supported."
}
}
}
},
"mediaBrowser.sort.dateCreated" : {
"localizations" : {
"en" : {

View File

@@ -22,6 +22,9 @@ struct MediaBrowserView: View {
@State private var sortOrder: MediaBrowserSortOrder
@State private var sortAscending: Bool
@State private var showViewOptions = false
#if os(tvOS)
@State private var unsupportedFile: MediaFile?
#endif
private var listStyle: VideoListStyle {
appEnvironment?.settingsManager.listStyle ?? .inset
@@ -165,8 +168,14 @@ struct MediaBrowserView: View {
} else if file.isPlayable {
playableFileRow(for: file)
} else {
#if os(tvOS)
MediaFileTVOSUnsupportedButton(onTap: { unsupportedFile = file }) {
MediaFileRow(file: file, sortOrder: sortOrder)
}
#else
MediaFileRow(file: file, sortOrder: sortOrder)
#endif
}
}
}
}
@@ -174,6 +183,20 @@ struct MediaBrowserView: View {
.padding(.top, 16)
}
)
#if os(tvOS)
.alert(
String(localized: "mediaBrowser.unsupportedFile.title"),
isPresented: Binding(
get: { unsupportedFile != nil },
set: { if !$0 { unsupportedFile = nil } }
),
presenting: unsupportedFile
) { _ in
Button(String(localized: "common.ok"), role: .cancel) { unsupportedFile = nil }
} message: { file in
Text(String(localized: "mediaBrowser.unsupportedFile.message \(file.name)"))
}
#endif
}
@ViewBuilder

View File

@@ -35,6 +35,17 @@ struct MediaFileTVOSTapButton<Label: View>: View {
.buttonStyle(.plain)
}
}
/// tvOS-only: wraps an unplayable row in a Button so the focus engine can land on it.
struct MediaFileTVOSUnsupportedButton<Label: View>: View {
let onTap: () -> Void
@ViewBuilder let label: () -> Label
var body: some View {
Button(action: onTap) { label() }
.buttonStyle(.plain)
}
}
#else
/// iOS/macOS: per-region gesture used by MediaFileRow's icon and text areas.
/// Only attaches a gesture when the action differs from `.playVideo`, letting