From cdc84cdf4ce249d72377cc373ce6af37f3ade30b Mon Sep 17 00:00:00 2001 From: Christoph Hagen Date: Mon, 24 Feb 2025 19:12:15 +0100 Subject: [PATCH] Move required files to settings --- .../Generator/HeaderElement.swift | 5 --- .../Model/Content+Generation.swift | 2 -- CHDataManagement/Model/Page.swift | 18 ++-------- CHDataManagement/Model/Post.swift | 3 +- .../Model/Settings/GeneralSettings.swift | 15 +++++--- .../Model/Settings/Settings.swift | 5 +-- .../Preview Content/Page+Mock.swift | 3 +- CHDataManagement/Storage/Storage.swift | 24 ------------- .../Views/Pages/AddPageView.swift | 3 +- .../Views/Pages/PageDetailView.swift | 32 ----------------- .../General/GeneralSettingsDetailView.swift | 35 ++++++++++++++++++- 11 files changed, 54 insertions(+), 91 deletions(-) diff --git a/CHDataManagement/Generator/HeaderElement.swift b/CHDataManagement/Generator/HeaderElement.swift index 52bc4ee..33322d1 100644 --- a/CHDataManagement/Generator/HeaderElement.swift +++ b/CHDataManagement/Generator/HeaderElement.swift @@ -1,9 +1,4 @@ -#warning("Add remaining header elements") -// -// -// - // TODO: Move to settings? extension HeaderElement { diff --git a/CHDataManagement/Model/Content+Generation.swift b/CHDataManagement/Model/Content+Generation.swift index 915408d..a10a168 100644 --- a/CHDataManagement/Model/Content+Generation.swift +++ b/CHDataManagement/Model/Content+Generation.swift @@ -312,8 +312,6 @@ extension Content { let results = results.makeResults(for: page, in: language) let pageGenerator = PageGenerator(content: self) - results.require(files: page.requiredFiles) - let relativePageUrl = page.absoluteUrl(in: language) let filePath = relativePageUrl + ".html" let pageUrl = settings.general.url + relativePageUrl diff --git a/CHDataManagement/Model/Page.swift b/CHDataManagement/Model/Page.swift index b0158b8..2fb8a70 100644 --- a/CHDataManagement/Model/Page.swift +++ b/CHDataManagement/Model/Page.swift @@ -40,10 +40,6 @@ final class Page: Item, DateItem, LocalizedItem { @Published var tags: [Tag] - /// Additional files to copy, because the page content references them - @Published - var requiredFiles: [FileResource] - var savedData: Data? init(content: Content, @@ -56,8 +52,7 @@ final class Page: Item, DateItem, LocalizedItem { endDate: Date?, german: LocalizedPage, english: LocalizedPage, - tags: [Tag], - requiredFiles: [FileResource]) { + tags: [Tag]) { self.externalLink = externalLink self.isDraft = isDraft self.createdDate = createdDate @@ -68,7 +63,6 @@ final class Page: Item, DateItem, LocalizedItem { self.german = german self.english = english self.tags = tags - self.requiredFiles = requiredFiles super.init(content: content, id: id) } @@ -186,9 +180,6 @@ final class Page: Item, DateItem, LocalizedItem { } func remove(_ file: FileResource) { - if requiredFiles.contains(file) { - requiredFiles.remove(file) - } english.linkPreview.remove(file) german.linkPreview.remove(file) } @@ -210,8 +201,7 @@ extension Page: StorageItem { endDate: data.endDate, german: .init(context: context, data: data.german), english: .init(context: context, data: data.english), - tags: data.tags.compactMap(context.tag), - requiredFiles: data.requiredFiles?.compactMap(context.file) ?? []) + tags: data.tags.compactMap(context.tag)) savedData = data } @@ -226,7 +216,6 @@ extension Page: StorageItem { let endDate: Date? let german: LocalizedPage.Data let english: LocalizedPage.Data - let requiredFiles: [String]? } @@ -240,8 +229,7 @@ extension Page: StorageItem { startDate: startDate, endDate: endDate, german: german.data, - english: english.data, - requiredFiles: requiredFiles.nonEmpty?.map { $0.id }.sorted()) + english: english.data) } func saveToDisk(_ data: Data) -> Bool { diff --git a/CHDataManagement/Model/Post.swift b/CHDataManagement/Model/Post.swift index 8e8a20d..f696e7b 100644 --- a/CHDataManagement/Model/Post.swift +++ b/CHDataManagement/Model/Post.swift @@ -172,8 +172,7 @@ final class Post: Item, DateItem, LocalizedItem { endDate: endDate, german: german, english: english, - tags: tags, - requiredFiles: []) + tags: tags) } } diff --git a/CHDataManagement/Model/Settings/GeneralSettings.swift b/CHDataManagement/Model/Settings/GeneralSettings.swift index 941cd2a..039952d 100644 --- a/CHDataManagement/Model/Settings/GeneralSettings.swift +++ b/CHDataManagement/Model/Settings/GeneralSettings.swift @@ -27,7 +27,10 @@ final class GeneralSettings: ObservableObject { @Published var urlForPushNotification: String? - init(url: String, linkPreviewImageWidth: Int, linkPreviewImageHeight: Int, remoteUserForUpload: String, remotePortForUpload: Int, remotePathForUpload: String, urlForPushNotification: String?) { + @Published + var requiredFiles: [FileResource] + + init(url: String, linkPreviewImageWidth: Int, linkPreviewImageHeight: Int, remoteUserForUpload: String, remotePortForUpload: Int, remotePathForUpload: String, urlForPushNotification: String?, requiredFiles: [FileResource]) { self.url = url self.linkPreviewImageWidth = linkPreviewImageWidth self.linkPreviewImageHeight = linkPreviewImageHeight @@ -35,12 +38,13 @@ final class GeneralSettings: ObservableObject { self.remotePortForUpload = remotePortForUpload self.remotePathForUpload = remotePathForUpload self.urlForPushNotification = urlForPushNotification + self.requiredFiles = requiredFiles } } extension GeneralSettings { - convenience init(data: Data) { + convenience init(context: LoadingContext, data: Data) { self.init( url: data.url, linkPreviewImageWidth: data.linkPreviewImageWidth, @@ -48,7 +52,8 @@ extension GeneralSettings { remoteUserForUpload: data.remoteUserForUpload, remotePortForUpload: data.remotePortForUpload, remotePathForUpload: data.remotePathForUpload, - urlForPushNotification: data.urlForPushNotification) + urlForPushNotification: data.urlForPushNotification, + requiredFiles: data.requiredFiles?.compactMap(context.file) ?? []) } var data: Data { @@ -59,7 +64,8 @@ extension GeneralSettings { remoteUserForUpload: remoteUserForUpload, remotePortForUpload: remotePortForUpload, remotePathForUpload: remotePathForUpload, - urlForPushNotification: urlForPushNotification) + urlForPushNotification: urlForPushNotification, + requiredFiles: requiredFiles.nonEmpty?.map { $0.id }.sorted()) } struct Data: Codable, Equatable { @@ -70,5 +76,6 @@ extension GeneralSettings { let remotePortForUpload: Int let remotePathForUpload: String let urlForPushNotification: String? + let requiredFiles: [String]? } } diff --git a/CHDataManagement/Model/Settings/Settings.swift b/CHDataManagement/Model/Settings/Settings.swift index 79cb86c..dbe345b 100644 --- a/CHDataManagement/Model/Settings/Settings.swift +++ b/CHDataManagement/Model/Settings/Settings.swift @@ -57,7 +57,7 @@ extension Settings { convenience init(context: LoadingContext, data: Settings.Data) { self.init( - general: .init(data: data.general), + general: .init(context: context, data: data.general), paths: .init(data: data.paths), navigation: .init(context: context, data: data.navigation), posts: .init(context: context, data: data.posts), @@ -112,7 +112,8 @@ extension GeneralSettings { remoteUserForUpload: "user", remotePortForUpload: 22, remotePathForUpload: "/home/user/web", - urlForPushNotification: nil) + urlForPushNotification: nil, + requiredFiles: []) } extension AudioPlayerSettings { diff --git a/CHDataManagement/Preview Content/Page+Mock.swift b/CHDataManagement/Preview Content/Page+Mock.swift index 3bf69b6..8b35d04 100644 --- a/CHDataManagement/Preview Content/Page+Mock.swift +++ b/CHDataManagement/Preview Content/Page+Mock.swift @@ -29,8 +29,7 @@ extension Page { originalUrl: "projects/electronics/my-first-project/en.html"), tags: [ content.tags.first(where: { $0.id == "electronics" })! - ], - requiredFiles: []) + ]) ] } diff --git a/CHDataManagement/Storage/Storage.swift b/CHDataManagement/Storage/Storage.swift index 895def1..6bc24ca 100644 --- a/CHDataManagement/Storage/Storage.swift +++ b/CHDataManagement/Storage/Storage.swift @@ -431,30 +431,6 @@ final class Storage: ObservableObject { return contentScope.encode(settings, to: settingsDataFileName) } - // MARK: Image generation data - - func calculateImages(generatedBy imageSet: Set, in folder: String) -> [String : Set] { - #warning("TODO: Move to file resource") - guard let outputScope else { return [:] } - guard let allImages = outputScope.fileNames(inRelativeFolder: folder) else { - print("Failed to get list of generated images in output folder") - return [:] - } - guard !allImages.isEmpty else { - print("No images found in output folder \(folder)") - return [:] - } - print("Found \(allImages.count) generated images") - let images = Set(allImages) - return imageSet.reduce(into: [:]) { result, imageName in - let prefix = imageName.fileNameWithoutExtension + "@" - let versions = images.filter { $0.hasPrefix(prefix) } - if !versions.isEmpty { - result[imageName] = Set(versions) - } - } - } - // MARK: Output files /** diff --git a/CHDataManagement/Views/Pages/AddPageView.swift b/CHDataManagement/Views/Pages/AddPageView.swift index d285ccd..056a3eb 100644 --- a/CHDataManagement/Views/Pages/AddPageView.swift +++ b/CHDataManagement/Views/Pages/AddPageView.swift @@ -79,8 +79,7 @@ struct AddPageView: View { english: .init(content: content, urlString: "page", title: "A Title"), - tags: [], - requiredFiles: []) + tags: []) content.add(page) selectedPage = page dismissSheet() diff --git a/CHDataManagement/Views/Pages/PageDetailView.swift b/CHDataManagement/Views/Pages/PageDetailView.swift index aec73b4..2e9d64f 100644 --- a/CHDataManagement/Views/Pages/PageDetailView.swift +++ b/CHDataManagement/Views/Pages/PageDetailView.swift @@ -12,9 +12,6 @@ struct PageDetailView: View { @ObservedObject private var page: Page - @State - private var showFileSelectionSheet = false - private var transferImage: (language: ContentLanguage, image: FileResource)? { page.localized(in: language.next).linkPreview.image.map { (language.next, $0) } } @@ -23,14 +20,6 @@ struct PageDetailView: View { self.page = page } - private var requiredFilesText: String { - switch page.requiredFiles.count { - case 0: return "No files" - case 1: return "1 file" - default: return "\(page.requiredFiles.count) files" - } - } - var body: some View { ScrollView { VStack(alignment: .leading) { @@ -79,24 +68,6 @@ struct PageDetailView: View { footer: "The date when the page content ended") .disabled(page.isExternalUrl) - GenericPropertyView( - title: "Required files", - footer: "The additional files required by the page") { - HStack { - Image(systemSymbol: .squareAndPencilCircleFill) - .resizable() - .aspectRatio(contentMode: .fit) - .frame(height: 20) - Text(requiredFilesText) - Spacer() - } - .padding(.vertical, 8) - .contentShape(Rectangle()) - .onTapGesture { - showFileSelectionSheet = true - } - } - LocalizedPageDetailView( isExternalPage: page.isExternalUrl, page: page.localized(in: language), @@ -105,9 +76,6 @@ struct PageDetailView: View { } .padding() } - .sheet(isPresented: $showFileSelectionSheet) { - MultiFileSelectionView(selectedFiles: $page.requiredFiles, insertSorted: true) - } } } diff --git a/CHDataManagement/Views/Settings/General/GeneralSettingsDetailView.swift b/CHDataManagement/Views/Settings/General/GeneralSettingsDetailView.swift index 0d40657..2a6101d 100644 --- a/CHDataManagement/Views/Settings/General/GeneralSettingsDetailView.swift +++ b/CHDataManagement/Views/Settings/General/GeneralSettingsDetailView.swift @@ -5,6 +5,18 @@ struct GeneralSettingsDetailView: View { @ObservedObject var generalSettings: GeneralSettings + @State + private var showFileSelectionSheet = false + + private var requiredFilesText: String { + let count = generalSettings.requiredFiles.count + switch count { + case 0: return "No files" + case 1: return "1 file" + default: return "\(count) files" + } + } + var body: some View { ScrollView { VStack(alignment: .leading) { @@ -19,7 +31,7 @@ struct GeneralSettingsDetailView: View { footer: "The maximum width of a link preview image") IntegerPropertyView( - title: "Link Preview Image Height", + title: "Linfk Preview Image Height", value: $generalSettings.linkPreviewImageHeight, footer: "The maximum height of a link preview image") @@ -47,8 +59,29 @@ struct GeneralSettingsDetailView: View { title: "Push Notification Access Token", text: $generalSettings.pushNotificationAccessToken, footer: "The access token to use for sending push notifications") + + GenericPropertyView( + title: "Required files", + footer: "The additional files required by the page") { + HStack { + Image(systemSymbol: .squareAndPencilCircleFill) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(height: 20) + Text(requiredFilesText) + Spacer() + } + .padding(.vertical, 8) + .contentShape(Rectangle()) + .onTapGesture { + showFileSelectionSheet = true + } + } } .padding() } + .sheet(isPresented: $showFileSelectionSheet) { + MultiFileSelectionView(selectedFiles: $generalSettings.requiredFiles, insertSorted: true) + } } }