Generate tag overview, add file action
This commit is contained in:
@ -2,15 +2,36 @@ import SwiftUI
|
||||
|
||||
struct FileDetailView: View {
|
||||
|
||||
@EnvironmentObject
|
||||
private var content: Content
|
||||
|
||||
@ObservedObject
|
||||
var file: FileResource
|
||||
|
||||
@State
|
||||
private var showFileSelection = false
|
||||
|
||||
@State
|
||||
private var selectedFile: FileResource?
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading) {
|
||||
DetailTitle(
|
||||
title: "File",
|
||||
text: "A file that can be used in a post or page")
|
||||
|
||||
VStack(alignment: .leading) {
|
||||
Button("Show in Finder", action: showFileInFinder)
|
||||
Button("Mark as changed", action: markFileAsChanged)
|
||||
Button("Delete resource", action: deleteFile)
|
||||
if file.isExternallyStored {
|
||||
Button("Import file", action: replaceFile)
|
||||
} else {
|
||||
Button("Replace file", action: replaceFile)
|
||||
Button("Make external", action: convertToExternal)
|
||||
}
|
||||
}
|
||||
|
||||
IdPropertyView(
|
||||
id: $file.id,
|
||||
title: "Name",
|
||||
@ -28,15 +49,108 @@ struct FileDetailView: View {
|
||||
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)
|
||||
Text("\(Int(file.size.width)) x \(Int(file.size.height)) (\(file.aspectRatio))")
|
||||
.foregroundStyle(.secondary)
|
||||
if let imageDimensions = file.imageDimensions {
|
||||
GenericPropertyView(title: "Image dimensions") {
|
||||
Text("\(Int(imageDimensions.width)) x \(Int(imageDimensions.height)) (\(file.aspectRatio))")
|
||||
}
|
||||
#warning("Add button to show image versions")
|
||||
}
|
||||
if let fileSize = file.fileSize {
|
||||
GenericPropertyView(title: "File size") {
|
||||
Text(formatBytes(fileSize))
|
||||
}
|
||||
}
|
||||
Spacer()
|
||||
}.padding()
|
||||
.onAppear {
|
||||
if file.fileSize == nil {
|
||||
file.determineFileSize()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func formatBytes(_ bytes: Int) -> String {
|
||||
let formatter = ByteCountFormatter()
|
||||
formatter.allowedUnits = [.useMB, .useKB, .useBytes] // Customize units if needed
|
||||
formatter.countStyle = .file
|
||||
return formatter.string(fromByteCount: Int64(bytes))
|
||||
}
|
||||
|
||||
private func showFileInFinder() {
|
||||
content.storage.openFinderWindow(withSelectedFile: file.id)
|
||||
}
|
||||
|
||||
private func markFileAsChanged() {
|
||||
DispatchQueue.main.async {
|
||||
file.determineImageDimensions()
|
||||
file.determineFileSize()
|
||||
// Force regeneration of images and/or file copying
|
||||
file.removeFileFromOutputFolder()
|
||||
// Trigger content view update to reload image
|
||||
file.didChange()
|
||||
}
|
||||
}
|
||||
|
||||
private func replaceFile() {
|
||||
guard let url = openFilePanel() else {
|
||||
print("File '\(file.id)': No file selected as replacement")
|
||||
return
|
||||
}
|
||||
guard content.storage.importExternalFile(at: url, fileId: file.id) else {
|
||||
print("File '\(file.id)': Failed to replace file")
|
||||
return
|
||||
}
|
||||
|
||||
markFileAsChanged()
|
||||
if file.isExternallyStored {
|
||||
DispatchQueue.main.async {
|
||||
file.isExternallyStored = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func openFilePanel() -> URL? {
|
||||
let panel = NSOpenPanel()
|
||||
|
||||
panel.canChooseFiles = true
|
||||
panel.canChooseDirectories = false
|
||||
panel.allowsMultipleSelection = false
|
||||
panel.showsHiddenFiles = false
|
||||
panel.title = "Select file to replace"
|
||||
panel.prompt = ""
|
||||
|
||||
let response = panel.runModal()
|
||||
guard response == .OK else {
|
||||
print("File '\(file.id)': Failed to select file to replace")
|
||||
return nil
|
||||
}
|
||||
|
||||
return panel.url
|
||||
}
|
||||
|
||||
private func convertToExternal() {
|
||||
guard !file.isExternallyStored else {
|
||||
return
|
||||
}
|
||||
|
||||
guard content.storage.delete(file: file.id) else {
|
||||
print("File '\(file.id)': Failed to delete file to make it external")
|
||||
return
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
file.fileSize = nil
|
||||
file.isExternallyStored = true
|
||||
}
|
||||
}
|
||||
|
||||
private func deleteFile() {
|
||||
if !file.isExternallyStored {
|
||||
guard content.storage.delete(file: file.id) else {
|
||||
print("File '\(file.id)': Failed to delete file in content folder")
|
||||
return
|
||||
}
|
||||
}
|
||||
content.remove(file)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user