Rework storage structs, link preview
This commit is contained in:
@ -1,13 +0,0 @@
|
||||
|
||||
struct FileDescriptions {
|
||||
|
||||
let fileId: String
|
||||
|
||||
let german: String?
|
||||
|
||||
let english: String?
|
||||
}
|
||||
|
||||
extension FileDescriptions: Codable {
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
/**
|
||||
This struct holds metadata about a file resource that is stored in the content folder.
|
||||
*/
|
||||
struct FileResourceFile {
|
||||
|
||||
/// The file/image description in German
|
||||
let englishDescription: String?
|
||||
|
||||
/// The file/image description in English
|
||||
let germanDescription: String?
|
||||
|
||||
/// The list of generated image versions for this image
|
||||
let generatedImages: [String]?
|
||||
|
||||
/// A custom file path in the output folder where this file is located
|
||||
let customOutputPath: String?
|
||||
|
||||
/// A version string of this resource, mostly for assets
|
||||
let version: String?
|
||||
|
||||
/// A URL where the resource was copied/downloaded from
|
||||
let sourceUrl: String?
|
||||
|
||||
/// The date when the file was added
|
||||
let addedDate: Date
|
||||
|
||||
/// The date when the file was last modified
|
||||
let modifiedDate: Date
|
||||
}
|
||||
|
||||
|
||||
extension FileResourceFile: Codable {
|
||||
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
struct PageFile {
|
||||
|
||||
let isDraft: Bool
|
||||
|
||||
let externalLink: String?
|
||||
|
||||
let tags: [String]
|
||||
|
||||
let hideDate: Bool?
|
||||
|
||||
let createdDate: Date
|
||||
|
||||
let startDate: Date
|
||||
|
||||
let endDate: Date?
|
||||
|
||||
let german: LocalizedPageFile
|
||||
|
||||
let english: LocalizedPageFile
|
||||
|
||||
/**
|
||||
Specifies additional files which should be copied to the destination when generating the content.
|
||||
- Note: This property defaults to an empty set.
|
||||
*/
|
||||
let requiredFiles: [String]?
|
||||
}
|
||||
|
||||
extension PageFile: Codable {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
The structure to store the metadata of a localized page
|
||||
*/
|
||||
struct LocalizedPageFile {
|
||||
|
||||
let url: String
|
||||
|
||||
let title: String
|
||||
|
||||
let linkPreviewImage: String?
|
||||
|
||||
let linkPreviewTitle: String?
|
||||
|
||||
let linkPreviewDescription: String?
|
||||
|
||||
let lastModifiedDate: Date?
|
||||
|
||||
let originalURL: String?
|
||||
|
||||
let hideTitle: Bool?
|
||||
}
|
||||
|
||||
extension LocalizedPageFile: Codable {
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
struct PostFile {
|
||||
|
||||
let isDraft: Bool
|
||||
|
||||
let createdDate: Date
|
||||
|
||||
let startDate: Date
|
||||
|
||||
let endDate: Date?
|
||||
|
||||
let tags: [String]
|
||||
|
||||
let german: LocalizedPostFile
|
||||
|
||||
let english: LocalizedPostFile
|
||||
|
||||
let linkedPageId: String?
|
||||
}
|
||||
|
||||
extension PostFile: Codable {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
The structure to store the metadata of a localized post
|
||||
*/
|
||||
struct LocalizedPostFile {
|
||||
|
||||
let images: [String]
|
||||
|
||||
let title: String?
|
||||
|
||||
let content: String
|
||||
|
||||
let lastModifiedDate: Date?
|
||||
|
||||
let pageLinkText: String?
|
||||
|
||||
let linkPreviewImage: String?
|
||||
|
||||
let linkPreviewTitle: String?
|
||||
|
||||
let linkPreviewDescription: String?
|
||||
}
|
||||
|
||||
extension LocalizedPostFile: Codable {
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
|
||||
struct AudioPlayerSettingsFile: Codable {
|
||||
|
||||
let playlistCoverImageSize: Int
|
||||
|
||||
let smallCoverImageSize: Int
|
||||
|
||||
let audioPlayerJsFile: String?
|
||||
|
||||
let audioPlayerCssFile: String?
|
||||
|
||||
let german: LocalizedAudioPlayerSettingsFile
|
||||
|
||||
let english: LocalizedAudioPlayerSettingsFile
|
||||
}
|
||||
|
||||
struct LocalizedAudioPlayerSettingsFile: Codable {
|
||||
|
||||
let playlistText: String
|
||||
}
|
||||
|
||||
extension AudioPlayerSettingsFile: LocalizedItem {
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
struct LocalizedNavigationSettingsFile {
|
||||
|
||||
let rootUrl: String
|
||||
}
|
||||
|
||||
extension LocalizedNavigationSettingsFile: Codable {
|
||||
|
||||
}
|
||||
|
||||
extension LocalizedNavigationSettingsFile {
|
||||
|
||||
static var `default`: LocalizedNavigationSettingsFile {
|
||||
.init(rootUrl: "/")
|
||||
}
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
|
||||
struct LocalizedPageSettingsFile {
|
||||
|
||||
let emptyPageTitle: String
|
||||
|
||||
let emptyPageText: String
|
||||
|
||||
init(emptyPageTitle: String, emptyPageText: String) {
|
||||
self.emptyPageTitle = emptyPageTitle
|
||||
self.emptyPageText = emptyPageText
|
||||
}
|
||||
}
|
||||
|
||||
extension LocalizedPageSettingsFile: Codable {
|
||||
|
||||
}
|
||||
|
||||
extension LocalizedPageSettingsFile {
|
||||
|
||||
static var `default`: LocalizedPageSettingsFile {
|
||||
.init(emptyPageTitle: "Empty Page", emptyPageText: "This page is empty.")
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
|
||||
struct LocalizedPostSettingsFile {
|
||||
|
||||
/// The page title for the post feed
|
||||
let feedTitle: String
|
||||
|
||||
/// The page description for the post feed
|
||||
let feedDescription: String
|
||||
|
||||
/// The path to the feed in the final website, appended with the page number
|
||||
let feedUrlPrefix: String
|
||||
|
||||
/**
|
||||
The text to display when linking to a page
|
||||
|
||||
Each post may define a custom text.
|
||||
*/
|
||||
let defaultPageLinkText: String?
|
||||
}
|
||||
|
||||
extension LocalizedPostSettingsFile: Codable { }
|
||||
|
||||
extension LocalizedPostSettingsFile {
|
||||
|
||||
static var `default`: LocalizedPostSettingsFile {
|
||||
.init(feedTitle: "A title",
|
||||
feedDescription: "A description",
|
||||
feedUrlPrefix: "blog",
|
||||
defaultPageLinkText: "View")
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
struct NavigationSettingsFile {
|
||||
|
||||
/// The tags to show in the navigation bar
|
||||
let navigationItems: [String]
|
||||
|
||||
let german: LocalizedNavigationSettingsFile
|
||||
|
||||
let english: LocalizedNavigationSettingsFile
|
||||
}
|
||||
|
||||
extension NavigationSettingsFile: Codable {
|
||||
|
||||
}
|
||||
|
||||
extension NavigationSettingsFile {
|
||||
|
||||
static var `default`: NavigationSettingsFile {
|
||||
.init(
|
||||
navigationItems: [],
|
||||
german: .default,
|
||||
english: .default)
|
||||
}
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
|
||||
struct PageSettingsFile {
|
||||
|
||||
let contentWidth: Int
|
||||
|
||||
let largeImageWidth: Int
|
||||
|
||||
let pageLinkImageSize: Int
|
||||
|
||||
let defaultCssFile: String?
|
||||
|
||||
let codeHighlightingJsFile: String?
|
||||
|
||||
let modelViewerJsFile: String?
|
||||
|
||||
let imageCompareJsFile: String?
|
||||
|
||||
let imageCompareCssFile: String?
|
||||
|
||||
let german: LocalizedPageSettingsFile
|
||||
|
||||
let english: LocalizedPageSettingsFile
|
||||
}
|
||||
|
||||
extension PageSettingsFile: Codable {
|
||||
|
||||
}
|
||||
|
||||
extension PageSettingsFile {
|
||||
|
||||
static var `default`: PageSettingsFile {
|
||||
.init(contentWidth: 600,
|
||||
largeImageWidth: 1200,
|
||||
pageLinkImageSize: 180,
|
||||
defaultCssFile: nil,
|
||||
codeHighlightingJsFile: nil,
|
||||
modelViewerJsFile: nil,
|
||||
imageCompareJsFile: nil,
|
||||
imageCompareCssFile: nil,
|
||||
german: .default,
|
||||
english: .default)
|
||||
}
|
||||
}
|
||||
|
||||
extension PageSettingsFile: LocalizedItem {
|
||||
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
|
||||
struct PathSettingsFile {
|
||||
|
||||
let assetsOutputFolderPath: String
|
||||
|
||||
let pagesOutputFolderPath: String
|
||||
|
||||
let imagesOutputFolderPath: String
|
||||
|
||||
let filesOutputFolderPath: String
|
||||
|
||||
let videosOutputFolderPath: String
|
||||
|
||||
let tagsOutputFolderPath: String
|
||||
|
||||
let audioOutputFolderPath: String
|
||||
|
||||
init(assetsOutputFolderPath: String,
|
||||
pagesOutputFolderPath: String,
|
||||
imagesOutputFolderPath: String,
|
||||
filesOutputFolderPath: String,
|
||||
videosOutputFolderPath: String,
|
||||
tagsOutputFolderPath: String,
|
||||
audioOutputFolderPath: String) {
|
||||
self.assetsOutputFolderPath = assetsOutputFolderPath
|
||||
self.pagesOutputFolderPath = pagesOutputFolderPath
|
||||
self.imagesOutputFolderPath = imagesOutputFolderPath
|
||||
self.filesOutputFolderPath = filesOutputFolderPath
|
||||
self.videosOutputFolderPath = videosOutputFolderPath
|
||||
self.tagsOutputFolderPath = tagsOutputFolderPath
|
||||
self.audioOutputFolderPath = audioOutputFolderPath
|
||||
}
|
||||
}
|
||||
|
||||
extension PathSettingsFile: Codable {
|
||||
|
||||
}
|
||||
|
||||
extension PathSettingsFile {
|
||||
|
||||
static var `default`: PathSettingsFile {
|
||||
PathSettingsFile(
|
||||
assetsOutputFolderPath: "asset",
|
||||
pagesOutputFolderPath: "page",
|
||||
imagesOutputFolderPath: "image",
|
||||
filesOutputFolderPath: "file",
|
||||
videosOutputFolderPath: "video",
|
||||
tagsOutputFolderPath: "tag",
|
||||
audioOutputFolderPath: "audio")
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
struct PostSettingsFile {
|
||||
|
||||
/// The number of posts to show in a single page of the news feed
|
||||
let postsPerPage: Int
|
||||
|
||||
/// The maximum width of the main content
|
||||
let contentWidth: Int
|
||||
|
||||
let swiperCssFile: String?
|
||||
|
||||
let swiperJsFile: String?
|
||||
|
||||
let defaultCssFile: String?
|
||||
|
||||
let german: LocalizedPostSettingsFile
|
||||
|
||||
let english: LocalizedPostSettingsFile
|
||||
}
|
||||
|
||||
extension PostSettingsFile: Codable { }
|
||||
|
||||
extension PostSettingsFile {
|
||||
|
||||
static var `default`: PostSettingsFile {
|
||||
.init(postsPerPage: 25,
|
||||
contentWidth: 600,
|
||||
swiperCssFile: nil,
|
||||
swiperJsFile: nil,
|
||||
defaultCssFile: nil,
|
||||
german: .default,
|
||||
english: .default)
|
||||
}
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
struct SettingsFile {
|
||||
|
||||
let paths: PathSettingsFile
|
||||
|
||||
/// The tags to show in the navigation bar
|
||||
let navigation: NavigationSettingsFile
|
||||
|
||||
let posts: PostSettingsFile
|
||||
|
||||
let pages: PageSettingsFile
|
||||
|
||||
let audioPlayer: AudioPlayerSettingsFile
|
||||
|
||||
let tagOverview: TagOverviewFile?
|
||||
}
|
||||
|
||||
extension SettingsFile: Codable { }
|
||||
|
||||
extension SettingsFile {
|
||||
|
||||
static var `default`: SettingsFile {
|
||||
.init(
|
||||
paths: .default,
|
||||
navigation: .default,
|
||||
posts: .default,
|
||||
pages: .default,
|
||||
audioPlayer: AudioPlayerSettings.default.file,
|
||||
tagOverview: nil
|
||||
)
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
|
||||
struct TagOverviewFile {
|
||||
|
||||
let german: LocalizedTagOverviewFile
|
||||
|
||||
let english: LocalizedTagOverviewFile
|
||||
}
|
||||
|
||||
extension TagOverviewFile: Codable {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
The structure to store the metadata of a localized page
|
||||
*/
|
||||
struct LocalizedTagOverviewFile {
|
||||
|
||||
let url: String
|
||||
|
||||
let title: String
|
||||
|
||||
let linkPreviewImage: String?
|
||||
|
||||
let linkPreviewTitle: String?
|
||||
|
||||
let linkPreviewDescription: String?
|
||||
}
|
||||
|
||||
extension LocalizedTagOverviewFile: Codable {
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
import Foundation
|
||||
|
||||
struct TagFile {
|
||||
|
||||
let id: String
|
||||
|
||||
let isVisible: Bool
|
||||
|
||||
let german: LocalizedTagFile
|
||||
|
||||
let english: LocalizedTagFile
|
||||
|
||||
}
|
||||
|
||||
extension TagFile: Codable {
|
||||
|
||||
}
|
||||
|
||||
struct LocalizedTagFile {
|
||||
|
||||
/// The id of the tag, used also as a url component
|
||||
let urlComponent: String
|
||||
|
||||
/// A custom name, different from the tag id
|
||||
let name: String
|
||||
|
||||
let linkPreviewTitle: String?
|
||||
|
||||
let linkPreviewDescription: String?
|
||||
|
||||
/// The image id of the thumbnail
|
||||
let linkPreviewImage: String?
|
||||
|
||||
/// The original url in the previous site layout
|
||||
let originalURL: String?
|
||||
|
||||
}
|
||||
|
||||
extension LocalizedTagFile: Codable {
|
||||
|
||||
}
|
@ -312,6 +312,7 @@ struct SecurityBookmark {
|
||||
do {
|
||||
data = try Data(contentsOf: url)
|
||||
} catch {
|
||||
#warning("Get these errors")
|
||||
print("Storage: Failed to read file \(url.path()): \(error)")
|
||||
return
|
||||
}
|
||||
|
@ -34,6 +34,7 @@ final class Storage: ObservableObject {
|
||||
|
||||
// MARK: Properties
|
||||
|
||||
#warning("Rework to make this non-optional by creating a wrapper class")
|
||||
@Published
|
||||
var contentScope: SecurityBookmark?
|
||||
|
||||
@ -72,13 +73,13 @@ final class Storage: ObservableObject {
|
||||
return contentScope.write(pageContent, to: path)
|
||||
}
|
||||
|
||||
func save(pageMetadata: PageFile, for pageId: String) -> Bool {
|
||||
func save(pageMetadata: Page.Data, for pageId: String) -> Bool {
|
||||
guard let contentScope else { return false }
|
||||
let path = pageMetadataPath(page: pageId)
|
||||
return contentScope.encode(pageMetadata, to: path)
|
||||
}
|
||||
|
||||
func loadAllPages() -> [String : PageFile]? {
|
||||
func loadAllPages() -> [String : Page.Data]? {
|
||||
contentScope?.decodeJsonFiles(in: pagesFolderName)
|
||||
}
|
||||
|
||||
@ -144,13 +145,13 @@ final class Storage: ObservableObject {
|
||||
postsFolderName + "/" + postFileName(postId)
|
||||
}
|
||||
|
||||
func save(post: PostFile, for postId: String) -> Bool {
|
||||
func save(post: Post.Data, for postId: String) -> Bool {
|
||||
guard let contentScope else { return false }
|
||||
let path = postFilePath(post: postId)
|
||||
return contentScope.encode(post, to: path)
|
||||
}
|
||||
|
||||
func loadAllPosts() -> [String : PostFile]? {
|
||||
func loadAllPosts() -> [String : Post.Data]? {
|
||||
contentScope?.decodeJsonFiles(in: postsFolderName)
|
||||
}
|
||||
|
||||
@ -183,13 +184,13 @@ final class Storage: ObservableObject {
|
||||
tagsFolderName + "/" + tagFileName(tagId: tagId)
|
||||
}
|
||||
|
||||
func save(tagMetadata: TagFile, for tagId: String) -> Bool {
|
||||
func save(tagMetadata: Tag.Data, for tagId: String) -> Bool {
|
||||
guard let contentScope else { return false }
|
||||
let path = tagFilePath(tag: tagId)
|
||||
return contentScope.encode(tagMetadata, to: path)
|
||||
}
|
||||
|
||||
func loadAllTags() -> [String : TagFile]? {
|
||||
func loadAllTags() -> [String : Tag.Data]? {
|
||||
contentScope?.decodeJsonFiles(in: tagsFolderName)
|
||||
}
|
||||
|
||||
@ -311,9 +312,9 @@ final class Storage: ObservableObject {
|
||||
|
||||
- Returns: A dictionary with the file ids as keys and the metadata file as a value.
|
||||
*/
|
||||
func loadAllFiles() -> [String : (data: FileResourceFile, isExternal: Bool)]? {
|
||||
func loadAllFiles() -> [String : (data: FileResource.Data, isExternal: Bool)]? {
|
||||
guard let contentScope else { return nil }
|
||||
guard let list: [String : FileResourceFile] = contentScope.decodeJsonFiles(in: fileInfoFolderName) else {
|
||||
guard let list: [String : FileResource.Data] = contentScope.decodeJsonFiles(in: fileInfoFolderName) else {
|
||||
return nil
|
||||
}
|
||||
guard let existingFiles = contentScope.fileNames(inRelativeFolder: filesFolderName).map(Set.init) else {
|
||||
@ -326,7 +327,7 @@ final class Storage: ObservableObject {
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
func save(fileInfo: FileResourceFile, for fileId: String) -> Bool {
|
||||
func save(fileInfo: FileResource.Data, for fileId: String) -> Bool {
|
||||
guard let contentScope else { return false }
|
||||
let path = fileInfoPath(file: fileId)
|
||||
return contentScope.encode(fileInfo, to: path)
|
||||
@ -359,12 +360,12 @@ final class Storage: ObservableObject {
|
||||
|
||||
// MARK: Settings
|
||||
|
||||
func loadSettings() -> SettingsFile? {
|
||||
func loadSettings() -> Settings.Data? {
|
||||
guard let contentScope else { return nil }
|
||||
return contentScope.decode(at: settingsDataFileName)
|
||||
}
|
||||
|
||||
func save(settings: SettingsFile) -> Bool {
|
||||
func save(settings: Settings.Data) -> Bool {
|
||||
guard let contentScope else { return false }
|
||||
return contentScope.encode(settings, to: settingsDataFileName)
|
||||
}
|
||||
|
Reference in New Issue
Block a user