Move required files to settings
This commit is contained in:
parent
ccf1ef3734
commit
cdc84cdf4c
@ -1,9 +1,4 @@
|
|||||||
|
|
||||||
#warning("Add remaining header elements")
|
|
||||||
// <meta name="msapplication-TileColor" content="#da532c">
|
|
||||||
// <meta name="theme-color" content="#ffffff">
|
|
||||||
// <meta name="msapplication-config" content="/assets/icons/browserconfig.xml?v=1">
|
|
||||||
|
|
||||||
// TODO: Move to settings?
|
// TODO: Move to settings?
|
||||||
extension HeaderElement {
|
extension HeaderElement {
|
||||||
|
|
||||||
|
@ -312,8 +312,6 @@ extension Content {
|
|||||||
let results = results.makeResults(for: page, in: language)
|
let results = results.makeResults(for: page, in: language)
|
||||||
let pageGenerator = PageGenerator(content: self)
|
let pageGenerator = PageGenerator(content: self)
|
||||||
|
|
||||||
results.require(files: page.requiredFiles)
|
|
||||||
|
|
||||||
let relativePageUrl = page.absoluteUrl(in: language)
|
let relativePageUrl = page.absoluteUrl(in: language)
|
||||||
let filePath = relativePageUrl + ".html"
|
let filePath = relativePageUrl + ".html"
|
||||||
let pageUrl = settings.general.url + relativePageUrl
|
let pageUrl = settings.general.url + relativePageUrl
|
||||||
|
@ -40,10 +40,6 @@ final class Page: Item, DateItem, LocalizedItem {
|
|||||||
@Published
|
@Published
|
||||||
var tags: [Tag]
|
var tags: [Tag]
|
||||||
|
|
||||||
/// Additional files to copy, because the page content references them
|
|
||||||
@Published
|
|
||||||
var requiredFiles: [FileResource]
|
|
||||||
|
|
||||||
var savedData: Data?
|
var savedData: Data?
|
||||||
|
|
||||||
init(content: Content,
|
init(content: Content,
|
||||||
@ -56,8 +52,7 @@ final class Page: Item, DateItem, LocalizedItem {
|
|||||||
endDate: Date?,
|
endDate: Date?,
|
||||||
german: LocalizedPage,
|
german: LocalizedPage,
|
||||||
english: LocalizedPage,
|
english: LocalizedPage,
|
||||||
tags: [Tag],
|
tags: [Tag]) {
|
||||||
requiredFiles: [FileResource]) {
|
|
||||||
self.externalLink = externalLink
|
self.externalLink = externalLink
|
||||||
self.isDraft = isDraft
|
self.isDraft = isDraft
|
||||||
self.createdDate = createdDate
|
self.createdDate = createdDate
|
||||||
@ -68,7 +63,6 @@ final class Page: Item, DateItem, LocalizedItem {
|
|||||||
self.german = german
|
self.german = german
|
||||||
self.english = english
|
self.english = english
|
||||||
self.tags = tags
|
self.tags = tags
|
||||||
self.requiredFiles = requiredFiles
|
|
||||||
|
|
||||||
super.init(content: content, id: id)
|
super.init(content: content, id: id)
|
||||||
}
|
}
|
||||||
@ -186,9 +180,6 @@ final class Page: Item, DateItem, LocalizedItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func remove(_ file: FileResource) {
|
func remove(_ file: FileResource) {
|
||||||
if requiredFiles.contains(file) {
|
|
||||||
requiredFiles.remove(file)
|
|
||||||
}
|
|
||||||
english.linkPreview.remove(file)
|
english.linkPreview.remove(file)
|
||||||
german.linkPreview.remove(file)
|
german.linkPreview.remove(file)
|
||||||
}
|
}
|
||||||
@ -210,8 +201,7 @@ extension Page: StorageItem {
|
|||||||
endDate: data.endDate,
|
endDate: data.endDate,
|
||||||
german: .init(context: context, data: data.german),
|
german: .init(context: context, data: data.german),
|
||||||
english: .init(context: context, data: data.english),
|
english: .init(context: context, data: data.english),
|
||||||
tags: data.tags.compactMap(context.tag),
|
tags: data.tags.compactMap(context.tag))
|
||||||
requiredFiles: data.requiredFiles?.compactMap(context.file) ?? [])
|
|
||||||
savedData = data
|
savedData = data
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +216,6 @@ extension Page: StorageItem {
|
|||||||
let endDate: Date?
|
let endDate: Date?
|
||||||
let german: LocalizedPage.Data
|
let german: LocalizedPage.Data
|
||||||
let english: LocalizedPage.Data
|
let english: LocalizedPage.Data
|
||||||
let requiredFiles: [String]?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -240,8 +229,7 @@ extension Page: StorageItem {
|
|||||||
startDate: startDate,
|
startDate: startDate,
|
||||||
endDate: endDate,
|
endDate: endDate,
|
||||||
german: german.data,
|
german: german.data,
|
||||||
english: english.data,
|
english: english.data)
|
||||||
requiredFiles: requiredFiles.nonEmpty?.map { $0.id }.sorted())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func saveToDisk(_ data: Data) -> Bool {
|
func saveToDisk(_ data: Data) -> Bool {
|
||||||
|
@ -172,8 +172,7 @@ final class Post: Item, DateItem, LocalizedItem {
|
|||||||
endDate: endDate,
|
endDate: endDate,
|
||||||
german: german,
|
german: german,
|
||||||
english: english,
|
english: english,
|
||||||
tags: tags,
|
tags: tags)
|
||||||
requiredFiles: [])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,7 +27,10 @@ final class GeneralSettings: ObservableObject {
|
|||||||
@Published
|
@Published
|
||||||
var urlForPushNotification: String?
|
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.url = url
|
||||||
self.linkPreviewImageWidth = linkPreviewImageWidth
|
self.linkPreviewImageWidth = linkPreviewImageWidth
|
||||||
self.linkPreviewImageHeight = linkPreviewImageHeight
|
self.linkPreviewImageHeight = linkPreviewImageHeight
|
||||||
@ -35,12 +38,13 @@ final class GeneralSettings: ObservableObject {
|
|||||||
self.remotePortForUpload = remotePortForUpload
|
self.remotePortForUpload = remotePortForUpload
|
||||||
self.remotePathForUpload = remotePathForUpload
|
self.remotePathForUpload = remotePathForUpload
|
||||||
self.urlForPushNotification = urlForPushNotification
|
self.urlForPushNotification = urlForPushNotification
|
||||||
|
self.requiredFiles = requiredFiles
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension GeneralSettings {
|
extension GeneralSettings {
|
||||||
|
|
||||||
convenience init(data: Data) {
|
convenience init(context: LoadingContext, data: Data) {
|
||||||
self.init(
|
self.init(
|
||||||
url: data.url,
|
url: data.url,
|
||||||
linkPreviewImageWidth: data.linkPreviewImageWidth,
|
linkPreviewImageWidth: data.linkPreviewImageWidth,
|
||||||
@ -48,7 +52,8 @@ extension GeneralSettings {
|
|||||||
remoteUserForUpload: data.remoteUserForUpload,
|
remoteUserForUpload: data.remoteUserForUpload,
|
||||||
remotePortForUpload: data.remotePortForUpload,
|
remotePortForUpload: data.remotePortForUpload,
|
||||||
remotePathForUpload: data.remotePathForUpload,
|
remotePathForUpload: data.remotePathForUpload,
|
||||||
urlForPushNotification: data.urlForPushNotification)
|
urlForPushNotification: data.urlForPushNotification,
|
||||||
|
requiredFiles: data.requiredFiles?.compactMap(context.file) ?? [])
|
||||||
}
|
}
|
||||||
|
|
||||||
var data: Data {
|
var data: Data {
|
||||||
@ -59,7 +64,8 @@ extension GeneralSettings {
|
|||||||
remoteUserForUpload: remoteUserForUpload,
|
remoteUserForUpload: remoteUserForUpload,
|
||||||
remotePortForUpload: remotePortForUpload,
|
remotePortForUpload: remotePortForUpload,
|
||||||
remotePathForUpload: remotePathForUpload,
|
remotePathForUpload: remotePathForUpload,
|
||||||
urlForPushNotification: urlForPushNotification)
|
urlForPushNotification: urlForPushNotification,
|
||||||
|
requiredFiles: requiredFiles.nonEmpty?.map { $0.id }.sorted())
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Data: Codable, Equatable {
|
struct Data: Codable, Equatable {
|
||||||
@ -70,5 +76,6 @@ extension GeneralSettings {
|
|||||||
let remotePortForUpload: Int
|
let remotePortForUpload: Int
|
||||||
let remotePathForUpload: String
|
let remotePathForUpload: String
|
||||||
let urlForPushNotification: String?
|
let urlForPushNotification: String?
|
||||||
|
let requiredFiles: [String]?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ extension Settings {
|
|||||||
|
|
||||||
convenience init(context: LoadingContext, data: Settings.Data) {
|
convenience init(context: LoadingContext, data: Settings.Data) {
|
||||||
self.init(
|
self.init(
|
||||||
general: .init(data: data.general),
|
general: .init(context: context, data: data.general),
|
||||||
paths: .init(data: data.paths),
|
paths: .init(data: data.paths),
|
||||||
navigation: .init(context: context, data: data.navigation),
|
navigation: .init(context: context, data: data.navigation),
|
||||||
posts: .init(context: context, data: data.posts),
|
posts: .init(context: context, data: data.posts),
|
||||||
@ -112,7 +112,8 @@ extension GeneralSettings {
|
|||||||
remoteUserForUpload: "user",
|
remoteUserForUpload: "user",
|
||||||
remotePortForUpload: 22,
|
remotePortForUpload: 22,
|
||||||
remotePathForUpload: "/home/user/web",
|
remotePathForUpload: "/home/user/web",
|
||||||
urlForPushNotification: nil)
|
urlForPushNotification: nil,
|
||||||
|
requiredFiles: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
extension AudioPlayerSettings {
|
extension AudioPlayerSettings {
|
||||||
|
@ -29,8 +29,7 @@ extension Page {
|
|||||||
originalUrl: "projects/electronics/my-first-project/en.html"),
|
originalUrl: "projects/electronics/my-first-project/en.html"),
|
||||||
tags: [
|
tags: [
|
||||||
content.tags.first(where: { $0.id == "electronics" })!
|
content.tags.first(where: { $0.id == "electronics" })!
|
||||||
],
|
])
|
||||||
requiredFiles: [])
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,30 +431,6 @@ final class Storage: ObservableObject {
|
|||||||
return contentScope.encode(settings, to: settingsDataFileName)
|
return contentScope.encode(settings, to: settingsDataFileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Image generation data
|
|
||||||
|
|
||||||
func calculateImages(generatedBy imageSet: Set<String>, in folder: String) -> [String : Set<String>] {
|
|
||||||
#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
|
// MARK: Output files
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,8 +79,7 @@ struct AddPageView: View {
|
|||||||
english: .init(content: content,
|
english: .init(content: content,
|
||||||
urlString: "page",
|
urlString: "page",
|
||||||
title: "A Title"),
|
title: "A Title"),
|
||||||
tags: [],
|
tags: [])
|
||||||
requiredFiles: [])
|
|
||||||
content.add(page)
|
content.add(page)
|
||||||
selectedPage = page
|
selectedPage = page
|
||||||
dismissSheet()
|
dismissSheet()
|
||||||
|
@ -12,9 +12,6 @@ struct PageDetailView: View {
|
|||||||
@ObservedObject
|
@ObservedObject
|
||||||
private var page: Page
|
private var page: Page
|
||||||
|
|
||||||
@State
|
|
||||||
private var showFileSelectionSheet = false
|
|
||||||
|
|
||||||
private var transferImage: (language: ContentLanguage, image: FileResource)? {
|
private var transferImage: (language: ContentLanguage, image: FileResource)? {
|
||||||
page.localized(in: language.next).linkPreview.image.map { (language.next, $0) }
|
page.localized(in: language.next).linkPreview.image.map { (language.next, $0) }
|
||||||
}
|
}
|
||||||
@ -23,14 +20,6 @@ struct PageDetailView: View {
|
|||||||
self.page = page
|
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 {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
@ -79,24 +68,6 @@ struct PageDetailView: View {
|
|||||||
footer: "The date when the page content ended")
|
footer: "The date when the page content ended")
|
||||||
.disabled(page.isExternalUrl)
|
.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(
|
LocalizedPageDetailView(
|
||||||
isExternalPage: page.isExternalUrl,
|
isExternalPage: page.isExternalUrl,
|
||||||
page: page.localized(in: language),
|
page: page.localized(in: language),
|
||||||
@ -105,9 +76,6 @@ struct PageDetailView: View {
|
|||||||
}
|
}
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
.sheet(isPresented: $showFileSelectionSheet) {
|
|
||||||
MultiFileSelectionView(selectedFiles: $page.requiredFiles, insertSorted: true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,18 @@ struct GeneralSettingsDetailView: View {
|
|||||||
@ObservedObject
|
@ObservedObject
|
||||||
var generalSettings: GeneralSettings
|
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 {
|
var body: some View {
|
||||||
ScrollView {
|
ScrollView {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
@ -19,7 +31,7 @@ struct GeneralSettingsDetailView: View {
|
|||||||
footer: "The maximum width of a link preview image")
|
footer: "The maximum width of a link preview image")
|
||||||
|
|
||||||
IntegerPropertyView(
|
IntegerPropertyView(
|
||||||
title: "Link Preview Image Height",
|
title: "Linfk Preview Image Height",
|
||||||
value: $generalSettings.linkPreviewImageHeight,
|
value: $generalSettings.linkPreviewImageHeight,
|
||||||
footer: "The maximum height of a link preview image")
|
footer: "The maximum height of a link preview image")
|
||||||
|
|
||||||
@ -47,8 +59,29 @@ struct GeneralSettingsDetailView: View {
|
|||||||
title: "Push Notification Access Token",
|
title: "Push Notification Access Token",
|
||||||
text: $generalSettings.pushNotificationAccessToken,
|
text: $generalSettings.pushNotificationAccessToken,
|
||||||
footer: "The access token to use for sending push notifications")
|
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()
|
.padding()
|
||||||
}
|
}
|
||||||
|
.sheet(isPresented: $showFileSelectionSheet) {
|
||||||
|
MultiFileSelectionView(selectedFiles: $generalSettings.requiredFiles, insertSorted: true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user