Unified detail views, model
This commit is contained in:
@ -5,44 +5,29 @@ struct FileDetailView: View {
|
||||
@ObservedObject
|
||||
var file: FileResource
|
||||
|
||||
@State
|
||||
private var newId: String
|
||||
|
||||
init(file: FileResource) {
|
||||
self.file = file
|
||||
self.newId = file.id
|
||||
}
|
||||
|
||||
private let allowedCharactersInPostId = CharacterSet.alphanumerics.union(CharacterSet(charactersIn: "-.")).inverted
|
||||
|
||||
private var idExists: Bool {
|
||||
file.content.files.contains { $0.id == newId }
|
||||
}
|
||||
|
||||
private var containsInvalidCharacters: Bool {
|
||||
newId.rangeOfCharacter(from: allowedCharactersInPostId) != nil
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
Text("File Name")
|
||||
.font(.headline)
|
||||
HStack {
|
||||
TextField("", text: $newId)
|
||||
.textFieldStyle(.roundedBorder)
|
||||
Button(action: setNewId) {
|
||||
Text("Update")
|
||||
}
|
||||
.disabled(newId.isEmpty || containsInvalidCharacters || idExists)
|
||||
}
|
||||
Text("German Description")
|
||||
.font(.headline)
|
||||
TextField("", text: $file.german)
|
||||
.textFieldStyle(.roundedBorder)
|
||||
Text("English Description")
|
||||
.font(.headline)
|
||||
TextField("", text: $file.english)
|
||||
.textFieldStyle(.roundedBorder)
|
||||
DetailTitle(
|
||||
title: "File",
|
||||
text: "A file that can be used in a post or page")
|
||||
|
||||
IdPropertyView(
|
||||
id: $file.id,
|
||||
title: "Name",
|
||||
footer: "The unique name of the file, which is also used to reference it in posts and pages.",
|
||||
validation: file.isValid,
|
||||
update: { file.update(id: $0) })
|
||||
|
||||
StringPropertyView(
|
||||
title: "German Description",
|
||||
text: $file.german,
|
||||
footer: "The description for the file in German. Descriptions are used for images and to explain the content of a file.")
|
||||
|
||||
StringPropertyView(
|
||||
title: "English Description",
|
||||
text: $file.english,
|
||||
footer: "The description for the file in English. Descriptions are used for images and to explain the content of a file.")
|
||||
|
||||
if file.type.isImage {
|
||||
Text("Image size")
|
||||
.font(.headline)
|
||||
@ -53,12 +38,6 @@ struct FileDetailView: View {
|
||||
Spacer()
|
||||
}.padding()
|
||||
}
|
||||
|
||||
private func setNewId() {
|
||||
if !file.update(id: newId) {
|
||||
newId = file.id
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension FileDetailView: MainContentView {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import SwiftUI
|
||||
|
||||
private enum FileFilterType: String, Hashable, CaseIterable, Identifiable {
|
||||
enum FileFilterType: String, Hashable, CaseIterable, Identifiable {
|
||||
case images
|
||||
case text
|
||||
case videos
|
||||
@ -38,11 +38,19 @@ struct FileListView: View {
|
||||
var selectedFile: FileResource?
|
||||
|
||||
@State
|
||||
private var selectedFileType: FileFilterType = .images
|
||||
private var selectedFileType: FileFilterType
|
||||
|
||||
@State
|
||||
private var searchString = ""
|
||||
|
||||
let allowedType: FileFilterType?
|
||||
|
||||
init(selectedFile: Binding<FileResource?>, allowedType: FileFilterType? = nil) {
|
||||
self._selectedFile = selectedFile
|
||||
self.allowedType = allowedType
|
||||
self.selectedFileType = allowedType ?? .images
|
||||
}
|
||||
|
||||
var filesBySelectedType: [FileResource] {
|
||||
content.files.filter { selectedFileType.matches($0.type) }
|
||||
}
|
||||
@ -63,6 +71,7 @@ struct FileListView: View {
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
.padding(.trailing, 7)
|
||||
.disabled(allowedType != nil)
|
||||
TextField("", text: $searchString, prompt: Text("Search"))
|
||||
.textFieldStyle(.roundedBorder)
|
||||
.padding(.horizontal, 8)
|
||||
|
@ -2,15 +2,18 @@ import SwiftUI
|
||||
|
||||
struct FileSelectionView: View {
|
||||
|
||||
@Binding
|
||||
private var selectedFile: FileResource?
|
||||
|
||||
@Environment(\.dismiss)
|
||||
private var dismiss
|
||||
|
||||
init(selectedFile: Binding<FileResource?>) {
|
||||
@Binding
|
||||
private var selectedFile: FileResource?
|
||||
|
||||
let allowedType: FileFilterType?
|
||||
|
||||
init(selectedFile: Binding<FileResource?>, allowedType: FileFilterType? = nil) {
|
||||
self._selectedFile = selectedFile
|
||||
self.newSelection = selectedFile.wrappedValue
|
||||
self.allowedType = allowedType
|
||||
}
|
||||
|
||||
@State
|
||||
@ -18,7 +21,7 @@ struct FileSelectionView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
FileListView(selectedFile: $newSelection)
|
||||
FileListView(selectedFile: $newSelection, allowedType: allowedType)
|
||||
.frame(minHeight: 500, idealHeight: 600)
|
||||
HStack {
|
||||
Button("Cancel") {
|
||||
|
Reference in New Issue
Block a user