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, results: PageGenerationResults) -> Set { 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() 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 = 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 += "

\(pageTitle)

\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) } }