Generate pages, image descriptions

This commit is contained in:
Christoph Hagen
2024-12-06 21:59:36 +01:00
parent 18eb64f289
commit 5fb689ac7c
42 changed files with 1653 additions and 273 deletions

View File

@ -0,0 +1,19 @@
struct ContentPageVideo: HtmlProducer {
let filePath: String
let videoType: String
let options: [VideoOption]
func populate(_ result: inout String) {
result += "<video\(optionString)>Video not supported."
result += "<source src='\(filePath)' type='\(videoType)'>"
result += "</video>"
}
private var optionString: String {
options.map { " " + $0.rawValue }.joined()
}
}

View File

@ -0,0 +1,34 @@
struct DownloadButtons {
struct Item {
let filePath: String
let text: String
let downloadFileName: String?
}
let items: [Item]
init(items: [Item]) {
self.items = items
}
var content: String {
var result = "<p style='display: flex'>"
for item in items {
addButton(of: item, to: &result)
}
result += "</p>"
return result
}
private func addButton(of item: Item, to result: inout String) {
let downloadText = item.downloadFileName.map { " download='\($0)'" } ?? ""
result += "<a class='download-button' href='\(item.filePath)'\(downloadText)>"
result += "\(item.text)<span class='icon icon-download'></span>"
result += "</a>"
}
}

View File

@ -0,0 +1,42 @@
struct HikingStatistics {
private let time: String?
private let elevationUp: String?
private let elevationDown: String?
private let distance: String?
private let calories: String?
init(time: String?, elevationUp: String?, elevationDown: String?, distance: String?, calories: String?) {
self.time = time
self.elevationUp = elevationUp
self.elevationDown = elevationDown
self.distance = distance
self.calories = calories
}
var content: String {
var result = "<div class='stats-container'>"
if let time {
result += "<div><svg><use href='#icon-clock'></use></svg>\(time)</div>"
}
if let elevationUp {
result += "<div><svg><use href='#icon-arrow-up'></use></svg>\(elevationUp)</div>"
}
if let elevationDown {
result += "<div><svg><use href='#icon-arrow-down'></use></svg>\(elevationDown)</div>"
}
if let distance {
result += "<div><svg><use href='#icon-sign'></use></svg>\(distance)</div>"
}
if let calories {
result += "<div><svg><use href='#icon-flame'></use></svg>\(calories)</div>"
}
result += "</div>"
return result
}
}

View File

@ -0,0 +1,29 @@
protocol HtmlProducer {
func populate(_ result: inout String)
}
extension HtmlProducer {
var content: String {
var result = ""
populate(&result)
return result
}
}
struct TagList: HtmlProducer {
let tags: [FeedEntryData.Tag]
func populate(_ result: inout String) {
guard !tags.isEmpty else {
return
}
result += "<div class='tags'>"
for tag in tags {
result += "<span class='tag' onclick=\"location.href='\(tag.url)'; event.stopPropagation();\">\(tag.name)</span>"
}
result += "</div>"
}
}