2025-01-29 09:16:29 +01:00

112 lines
3.2 KiB
Swift

import SwiftUI
struct FileListView: View {
@EnvironmentObject
private var content: Content
@Binding
var selectedFile: FileResource?
@State
private var selectedFileType: FileTypeCategory? = nil
@State
private var searchString = ""
let allowedType: FileTypeCategory?
init(selectedFile: Binding<FileResource?>, allowedType: FileTypeCategory? = nil) {
self._selectedFile = selectedFile
self.allowedType = allowedType
}
var filesBySelectedType: [FileResource] {
guard let selectedFileType else {
return content.files
}
return content.files.filter { selectedFileType == $0.type.category }
}
var filteredFiles: [FileResource] {
guard !searchString.isEmpty else {
return filesBySelectedType
}
return filesBySelectedType.filter { $0.id.contains(searchString) }
}
var body: some View {
VStack(alignment: .center) {
if allowedType == nil {
Picker("", selection: $selectedFileType) {
let all: FileTypeCategory? = nil
Text("All").tag(all)
ForEach(FileTypeCategory.allCases) { type in
Text(type.text).tag(type)
}
}
.pickerStyle(.menu)
.padding(.trailing, 7)
}
TextField("", text: $searchString, prompt: Text("Search"))
.textFieldStyle(.roundedBorder)
.padding(.horizontal, 8)
List(filteredFiles) { file in
HStack {
Text(file.id)
Spacer()
}
.listRowBackground(RoundedRectangle(cornerRadius: 5)
.fill(selectedFile == file ? Color.blue : Color.clear)
.padding(.horizontal, 10)
)
.contentShape(Rectangle())
.onTapGesture {
selectedFile = file
}
}
.onChange(of: selectedFileType) { oldValue, newValue in
guard oldValue != newValue else {
return
}
let newFile = filteredFiles.first
guard let selectedFile else {
if let newFile {
DispatchQueue.main.async {
selectedFile = newFile
}
}
return
}
if newValue == selectedFile.type.category {
return
}
DispatchQueue.main.async {
self.selectedFile = newFile
}
}
}
.onAppear {
if let allowedType {
selectedFileType = allowedType
}
if selectedFile == nil {
selectedFile = content.files.first
}
}
}
}
#Preview {
NavigationSplitView {
FileListView(selectedFile: .constant(nil))
.environmentObject(Content.mock)
.navigationSplitViewColumnWidth(250)
} detail: {
Text("")
.frame(width: 50)
}
}