Simplify images, tag overview

This commit is contained in:
Christoph Hagen
2025-01-04 08:44:26 +01:00
parent 4d4275e072
commit 22e7d9a05a
49 changed files with 603 additions and 509 deletions

View File

@ -74,12 +74,14 @@ extension Content {
completed += 1
status("Generating required images: \(completed) / \(count)")
}
if imageGenerator.generate(job: image) {
if imageGenerator.generate(version: image) {
continue
}
results.failed(image: image)
}
imageGenerator.save()
imageGenerator.printAvifCommands()
//let images = Set(self.images.map { $0.id })
//imageGenerator.recalculateGeneratedImages(by: images)
}
@ -244,11 +246,16 @@ extension Content {
- Note: Run on background thread
*/
private func generateTagOverviewPagesInternal() {
guard let tagOverview else {
print("Generator: No tag overview page to generate")
return
}
status("Generating tag overview page")
for language in ContentLanguage.allCases {
guard shouldGenerateWebsite else { return }
let results = results.makeResults(for: .tagOverview, in: language)
#warning("Create layout for tag overview page")
let generator = TagOverviewGenerator(content: self, language: language, results: results)
generator.generatePage(tags: tags, overview: tagOverview)
}
}

View File

@ -146,7 +146,27 @@ extension Content {
self.files = files.values.sorted { $0.id }
self.posts = posts.values.sorted(ascending: false) { $0.startDate }
self.tagOverview = tagOverview
self.settings = .init(file: settings, tags: tags, pages: pages, files: files, posts: posts, tagOverview: tagOverview)
self.settings = .init(file: settings, files: files) { raw in
#warning("Notify about missing links")
guard let type = ItemType(rawValue: raw, posts: posts, pages: pages, tags: tags) else {
return nil
}
switch type {
case .general:
return nil
case .post(let post):
return post
case .feed:
return nil // TODO: Provide feed object
case .page(let page):
return page
case .tagPage(let tag):
return tag
case .tagOverview:
return tagOverview
}
}
print("Content loaded")
}

View File

@ -34,6 +34,7 @@ final class Content: ObservableObject {
@Published
private(set) var isGeneratingWebsite = false
@Published
private(set) var shouldGenerateWebsite = false
init(settings: Settings,

View File

@ -76,6 +76,33 @@ final class FileResource: Item {
Image(systemSymbol: .exclamationmarkTriangle)
}
/// The path to the output folder where image versions are stored (no leading slash)
var outputImageFolder: String {
"\(content.settings.paths.imagesOutputFolderPath)/\(id.fileNameWithoutExtension)"
}
func outputPath(width: Int, height: Int, type: FileType?) -> String {
let prefix = "/\(outputImageFolder)/\(width)x\(height)"
guard let ext = type?.fileExtension else {
return prefix
}
return prefix + "." + ext
}
func imageSet(width: Int, height: Int, language: ContentLanguage, quality: CGFloat = 0.7) -> ImageSet {
let description = self.localized(in: language)
return .init(
image: self,
maxWidth: width,
maxHeight: height,
description: description,
quality: quality)
}
func imageVersion(width: Int, height: Int, type: FileType) -> ImageVersion {
.init(image: self, type: type, maximumWidth: width, maximumHeight: height)
}
// MARK: Paths
/**

View File

@ -103,6 +103,10 @@ enum FileType: String {
case aac
case m4b
case m4a
// MARK: Other
case noExtension
@ -143,7 +147,7 @@ enum FileType: String {
return .image
case .mp4, .m4v, .webm:
return .video
case .mp3, .aac:
case .mp3, .aac, .m4b, .m4a:
return .audio
case .js, .css, .ttf:
return .asset
@ -160,65 +164,38 @@ enum FileType: String {
}
}
var fileExtension: String {
var fileExtension: String? {
switch self {
case .noExtension, .unknown: return ""
case .noExtension, .unknown: return nil
default:
return rawValue
}
}
var isImage: Bool {
switch self {
case .jpg, .png, .avif, .webp, .gif, .svg, .tiff:
return true
default:
return false
}
category == .image
}
var isVideo: Bool {
switch self {
case .mp4, .m4v, .webm:
return true
default:
return false
}
category == .video
}
var isAudio: Bool {
switch self {
case .mp3, .aac:
return true
default:
return false
}
category == .audio
}
var isAsset: Bool {
switch self {
case .js, .css, .ttf:
return true
default:
return false
}
category == .asset
}
var isTextFile: Bool {
switch self {
case .html, .cpp, .swift, .css, .js, .json, .conf, .yaml:
return true
default:
return false
switch category {
case .text, .code: return true
default: break
}
}
var isOtherFile: Bool {
switch self {
case .noExtension, .zip, .cddx, .pdf, .key, .psd:
return true
default:
return false
case .css, .js: return true
default: return false
}
}

View File

@ -0,0 +1,9 @@
protocol LinkPreviewItem {
var linkPreviewImage: FileResource? { get }
var linkPreviewTitle: String? { get }
var linkPreviewDescription: String? { get }
}

View File

@ -71,3 +71,7 @@ final class LocalizedPage: ObservableObject {
!content.containsPage(withUrlComponent: urlComponent)
}
}
extension LocalizedPage: LinkPreviewItem {
}

View File

@ -44,3 +44,7 @@ final class LocalizedPost: ObservableObject {
self.linkPreviewDescription = linkPreviewDescription
}
}
extension LocalizedPost: LinkPreviewItem {
}

View File

@ -45,3 +45,14 @@ final class LocalizedTag: ObservableObject {
!content.containsTag(withUrlComponent: urlComponent)
}
}
extension LocalizedTag: LinkPreviewItem {
var linkPreviewTitle: String? {
self.name
}
var linkPreviewDescription: String? {
description
}
}

View File

@ -12,39 +12,16 @@ final class NavigationSettings: ObservableObject {
@Published
var english: LocalizedNavigationSettings
init(navigationItems: [Item], german: LocalizedNavigationSettings, english: LocalizedNavigationSettings) {
init(navigationItems: [Item],
german: LocalizedNavigationSettings,
english: LocalizedNavigationSettings) {
self.navigationItems = navigationItems
self.german = german
self.english = english
}
init(file: NavigationSettingsFile,
tags: [String : Tag],
pages: [String : Page],
files: [String : FileResource],
posts: [String : Post],
tagOverview: TagOverviewPage?) {
#warning("Notify about missing links")
self.navigationItems = file.navigationItems.compactMap { raw in
guard let type = ItemType(rawValue: raw, posts: posts, pages: pages, tags: tags) else {
return nil
}
switch type {
case .general:
return nil
case .post(let post):
return post
case .feed:
return nil // TODO: Provide feed object
case .page(let page):
return page
case .tagPage(let tag):
return tag
case .tagOverview:
return tagOverview
}
}
init(file: NavigationSettingsFile, map: (String) -> Item?) {
self.navigationItems = file.navigationItems.compactMap(map)
self.german = LocalizedNavigationSettings(file: file.german)
self.english = LocalizedNavigationSettings(file: file.english)
}

View File

@ -37,20 +37,8 @@ final class Settings: ObservableObject {
}
}
init(file: SettingsFile,
tags: [String : Tag],
pages: [String : Page],
files: [String : FileResource],
posts: [String : Post],
tagOverview: TagOverviewPage?) {
self.navigation = NavigationSettings(
file: file.navigation,
tags: tags,
pages: pages,
files: files,
posts: posts,
tagOverview: tagOverview)
init(file: SettingsFile, files: [String : FileResource], map: (String) -> Item?) {
self.navigation = NavigationSettings(file: file.navigation, map: map)
self.posts = PostSettings(file: file.posts, files: files)
self.pages = PageSettings(file: file.pages, files: files)