2024-12-09 12:18:55 +01:00

101 lines
2.6 KiB
Swift

import SwiftUI
private enum FileFilterType: String, Hashable, CaseIterable, Identifiable {
case images
case text
case videos
case other
var text: String {
switch self {
case .images: return "Image"
case .text: return "Text"
case .videos: return "Video"
case .other: return "Other"
}
}
var id: String {
rawValue
}
func matches(_ type: FileType) -> Bool {
switch self {
case .images: return type.isImage
case .text: return type.isTextFile
case .videos: return type.isVideo
case .other: return type.isOtherFile
}
}
}
struct FileListView: View {
@EnvironmentObject
private var content: Content
@Binding
var selectedFile: FileResource?
@State
private var selectedFileType: FileFilterType = .images
@State
private var searchString = ""
var filesBySelectedType: [FileResource] {
content.files.filter { selectedFileType.matches($0.type) }
}
var filteredFiles: [FileResource] {
guard !searchString.isEmpty else {
return filesBySelectedType
}
return filesBySelectedType.filter { $0.id.contains(searchString) }
}
var body: some View {
VStack(alignment: .center) {
Picker("", selection: $selectedFileType) {
ForEach(FileFilterType.allCases) { type in
Text(type.text).tag(type)
}
}
.pickerStyle(.segmented)
.padding(.trailing, 7)
TextField("", text: $searchString, prompt: Text("Search"))
.textFieldStyle(.roundedBorder)
.padding(.horizontal, 8)
List(filteredFiles, selection: $selectedFile) { file in
Text(file.id).tag(file)
}
.onChange(of: selectedFileType) { oldValue, newValue in
guard oldValue != newValue else {
return
}
if let selectedFile,
newValue.matches(selectedFile.type) {
return
}
selectedFile = filteredFiles.first
}
}
.onAppear {
if selectedFile == nil {
selectedFile = content.files.first
}
}
}
}
#Preview {
NavigationSplitView {
FileListView(selectedFile: .constant(nil))
.environmentObject(Content.mock)
.navigationSplitViewColumnWidth(250)
} detail: {
Text("")
.frame(width: 50)
}
}