123 lines
4.3 KiB
Swift
123 lines
4.3 KiB
Swift
import Foundation
|
|
|
|
final class PostListPageGenerator {
|
|
|
|
private let language: ContentLanguage
|
|
|
|
private let content: Content
|
|
|
|
private let imageGenerator: ImageGenerator
|
|
|
|
private let navigationBarLinks: [NavigationBar.Link]
|
|
|
|
private let showTitle: Bool
|
|
|
|
private let pageTitle: String
|
|
|
|
private let pageDescription: String
|
|
|
|
/// The url of the page, excluding the extension
|
|
private let pageUrlPrefix: String
|
|
|
|
init(language: ContentLanguage, content: Content, imageGenerator: ImageGenerator, navigationBarLinks: [NavigationBar.Link], showTitle: Bool, pageTitle: String, pageDescription: String, pageUrlPrefix: String) {
|
|
self.language = language
|
|
self.content = content
|
|
self.imageGenerator = imageGenerator
|
|
self.navigationBarLinks = navigationBarLinks
|
|
self.showTitle = showTitle
|
|
self.pageTitle = pageTitle
|
|
self.pageDescription = pageDescription
|
|
self.pageUrlPrefix = pageUrlPrefix
|
|
}
|
|
|
|
private var mainContentMaximumWidth: CGFloat {
|
|
CGFloat(content.settings.posts.contentWidth)
|
|
}
|
|
|
|
private var postsPerPage: Int {
|
|
content.settings.posts.postsPerPage
|
|
}
|
|
|
|
func createPages(for posts: [Post]) -> Bool {
|
|
let totalCount = posts.count
|
|
guard totalCount > 0 else {
|
|
return true
|
|
}
|
|
|
|
let numberOfPages = (totalCount + postsPerPage - 1) / postsPerPage // Round up
|
|
for pageIndex in 1...numberOfPages {
|
|
let startIndex = (pageIndex - 1) * postsPerPage
|
|
let endIndex = min(pageIndex * postsPerPage, totalCount)
|
|
let postsOnPage = posts[startIndex..<endIndex]
|
|
guard createPostFeedPage(pageIndex, pageCount: numberOfPages, posts: postsOnPage, bar: navigationBarLinks) else {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
private func createPostFeedPage(_ pageIndex: Int, pageCount: Int, posts: ArraySlice<Post>, bar: [NavigationBar.Link]) -> Bool {
|
|
let posts: [FeedEntryData] = posts.map { post in
|
|
let localized: LocalizedPost = post.localized(in: language)
|
|
|
|
let linkUrl = post.linkedPage.map {
|
|
FeedEntryData.Link(
|
|
url: content.absoluteUrlToPage($0, language: language),
|
|
text: language == .english ? "View" : "Anzeigen") // TODO: Add to settings
|
|
}
|
|
|
|
let tags: [FeedEntryData.Tag] = post.tags.filter { $0.isVisible }.map { tag in
|
|
.init(name: tag.localized(in: language).name,
|
|
url: content.absoluteUrlToTag(tag, language: language))
|
|
}
|
|
|
|
return FeedEntryData(
|
|
entryId: post.id,
|
|
title: localized.title,
|
|
textAboveTitle: post.dateText(in: language),
|
|
link: linkUrl,
|
|
tags: tags,
|
|
text: [localized.content], // TODO: Convert from markdown to html
|
|
images: localized.images.map(createImageSet))
|
|
}
|
|
|
|
let feed = PageInFeed(
|
|
language: language,
|
|
title: pageTitle,
|
|
showTitle: showTitle,
|
|
description: pageDescription,
|
|
navigationBarLinks: bar,
|
|
pageNumber: pageIndex,
|
|
totalPages: pageCount,
|
|
posts: posts)
|
|
let fileContent = feed.content
|
|
if pageIndex == 1 {
|
|
return save(fileContent, to: "\(pageUrlPrefix).html")
|
|
} else {
|
|
return save(fileContent, to: "\(pageUrlPrefix)-\(pageIndex).html")
|
|
}
|
|
}
|
|
|
|
private func createImageSet(for image: FileResource) -> FeedEntryData.Image {
|
|
imageGenerator.generateImageSet(
|
|
for: image.id,
|
|
maxWidth: mainContentMaximumWidth,
|
|
maxHeight: mainContentMaximumWidth)
|
|
return .init(
|
|
rawImagePath: content.absoluteUrlToFile(image),
|
|
width: Int(mainContentMaximumWidth),
|
|
height: Int(mainContentMaximumWidth),
|
|
altText: image.getDescription(for: language))
|
|
}
|
|
|
|
private func save(_ content: String, to relativePath: String) -> Bool {
|
|
do {
|
|
try self.content.storage.write(content: content, to: relativePath)
|
|
return true
|
|
} catch {
|
|
print("Failed to write page \(relativePath)")
|
|
return false
|
|
}
|
|
}
|
|
}
|