2025-05-02 10:00:59 +02:00

95 lines
3.4 KiB
Swift

import Foundation
final class FeedPageGenerator {
let results: PageGenerationResults
let content: Content
init(content: Content, results: PageGenerationResults) {
self.content = content
self.results = results
}
private func makeHeaders(requiredItems: Set<KnownHeaderElement>, results: PageGenerationResults) -> Set<HeaderElement> {
var result = content.postPageHeaders
for item in requiredItems {
guard let header = item.header(content: content) else {
results.warning("Header \(item) not configured in settings")
continue
}
result.insert(header)
}
return result
}
func generatePage(language: ContentLanguage,
posts: [FeedEntryData],
title: String?,
description: String?,
image: FileResource?,
pageUrl: String,
pageTitle: String?,
pageNumber: Int,
totalPages: Int,
languageButtonUrl: String,
linkPrefix: String) -> String {
var footer = ""
var requiredHeaders = Set<KnownHeaderElement>()
if posts.contains(where: { $0.requiresSwiper }) {
// Sort swiper style sheet before default style sheet
requiredHeaders.formUnion([.swiperJs, .swiperCss])
footer = swiperInitScript(posts: posts)
}
let headers = makeHeaders(requiredItems: requiredHeaders, results: results)
results.require(files: headers.compactMap { $0.requiredFile })
results.require(headers: requiredHeaders)
let iconUrl = content.settings.navigation.localized(in: language).rootUrl
let languageButton = NavigationBar.Link(
text: language.next.rawValue,
url: languageButtonUrl)
let imageUrl = image?.linkPreviewImage(results: results)
let requiredIcons: Set<PageIcon> = posts.reduce(into: []) { icons, post in
icons.formUnion(post.labels.map { $0.icon })
}
let pageHeader = PageHeader(
language: language,
title: title ?? pageTitle,
description: description,
image: imageUrl,
pageUrl: pageUrl,
iconUrl: iconUrl,
languageButton: languageButton,
links: content.navigationBar(in: language),
headers: headers,
icons: requiredIcons)
let page = GenericPage(
header: pageHeader,
additionalFooter: footer) { content in
if let pageTitle {
content += "<h1 class='separated-headline'>\(pageTitle)</h1>\n"
}
for post in posts {
content += FeedEntry(data: post).content
}
if totalPages > 1 {
content += PostFeedPageNavigation(
linkPrefix: linkPrefix,
currentPage: pageNumber,
numberOfPages: totalPages).content
}
}
return page.content
}
func swiperInitScript(posts: [FeedEntryData]) -> String {
let ids = posts.filter { $0.requiresSwiper }.map { $0.entryId }
return ImageGallery.combinedFootor(ids: ids)
}
}