Add screen slider component

This commit is contained in:
Christoph Hagen
2025-02-20 23:44:12 +01:00
parent a8bc7298ff
commit d4c0da0a32
6 changed files with 328 additions and 10 deletions

View File

@ -13,6 +13,8 @@ enum ContentBlock: String, CaseIterable {
case labels
case screens
var processor: BlockProcessor.Type {
switch self {
case .audio: return AudioBlock.self
@ -21,6 +23,7 @@ enum ContentBlock: String, CaseIterable {
case .button: return ButtonBlock.self
case .buttons: return ButtonsBlock.self
case .labels: return LabelsBlock.self
case .screens: return PhoneScreensBlock.self
}
}
}

View File

@ -0,0 +1,104 @@
struct PhoneScreensBlock: OrderedKeyBlockProcessor {
enum Key: String {
case id
case frame
case tall
case wide
}
static let blockId: ContentBlock = .screens
let content: Content
let results: PageGenerationResults
let language: ContentLanguage
init(content: Content, results: PageGenerationResults, language: ContentLanguage) {
self.content = content
self.results = results
self.language = language
}
func process(_ arguments: [(key: Key, value: String)], markdown: Substring) -> String {
print("Processing Phone Screens Block")
guard let frameId = arguments.first(where: {$0.key == .frame })?.value else {
invalid(markdown)
return ""
}
guard let frameFile = content.file(frameId) else {
results.missing(file: frameId, source: "Wallpaper Block")
return ""
}
guard let id = arguments.first(where: {$0.key == .id })?.value else {
invalid(markdown)
return ""
}
let remaining = arguments.filter { $0.key == .tall || $0.key == .wide }
var images = [WallpaperSlider.Image]()
var tall: FileResource?
var wide: FileResource?
for (key, fileId) in remaining {
guard let file = content.file(fileId) else {
print("Missing file: \(fileId)")
results.missing(file: fileId, source: "Wallpaper Block")
return ""
}
if key == .tall {
if tall != nil {
print("Another tall image: \(file.id)")
invalid(markdown)
return ""
}
if let other = wide {
let image = WallpaperSlider.Image(
tall: file,
wide: other,
language: language,
results: results)
images.append(image)
wide = nil
continue
}
tall = file
continue
}
// key == .wide
if wide != nil {
print("Another wide image: \(file.id)")
invalid(markdown)
return ""
}
guard let other = tall else {
wide = file
continue
}
let image = WallpaperSlider.Image(
tall: other,
wide: file,
language: language,
results: results)
images.append(image)
tall = nil
}
if tall != nil || wide != nil {
invalid(markdown)
print("Wide/tall does not have the same number of items")
return ""
}
let frame = WallpaperSlider.Frame(frame: frameFile, language: language, results: results)
let slider = WallpaperSlider(frame: frame, images: images, id: id)
results.require(footer: slider.script)
results.require(headers: .swiperJs, .swiperCss)
results.require(header: .style(slider.style))
return slider.content
}
}

View File

@ -52,6 +52,8 @@ enum HeaderElement {
case manifest(FileResource)
case style(String)
var order: Int {
switch self {
case .charset: 1
@ -69,6 +71,7 @@ enum HeaderElement {
case .ogDescription: 104
case .ogImage: 105
case .ogUrl: 106
case .style: 200
}
}
@ -136,6 +139,8 @@ extension HeaderElement {
return "<meta name='robots' content='noindex'>"
case .manifest(let file):
return "<link rel='manifest' href='\(file.absoluteUrl)'>"
case .style(let style):
return "<style>\(style)</style>"
}
}
}
@ -174,6 +179,8 @@ extension HeaderElement: CustomStringConvertible {
return "robots"
case .manifest:
return "manifest"
case .style:
return "style"
}
}
}

View File

@ -1,19 +1,25 @@
enum KnownHeaderElement: Int {
enum KnownHeaderElement {
case codeHightlighting = 4
case codeHightlighting
case modelViewer = 3
case modelViewer
/// CSS File to style the audio player
case audioPlayerCss = 1
case audioPlayerCss
/// JavaScript file for the audio player
case audioPlayerJs = 2
case audioPlayerJs
case imageCompareJs = 5
case imageCompareJs
case imageCompareCss = 6
case imageCompareCss
case swiperCss
case swiperJs
case style(String)
func header(content: Content) -> HeaderElement? {
switch self {
@ -41,15 +47,32 @@ enum KnownHeaderElement: Int {
if let file = content.settings.pages.imageCompareCssFile {
return .css(file: file, order: HeaderElement.imageCompareCssOrder)
}
case .swiperCss:
if let swiperCss = content.settings.posts.swiperCssFile {
return .css(file: swiperCss, order: HeaderElement.swiperCssFileOrder)
}
case .swiperJs:
if let swiperJs = content.settings.posts.swiperJsFile {
return .js(file: swiperJs, defer: true)
}
case .style(let code):
return .style(code)
}
return nil
}
}
extension KnownHeaderElement: Comparable {
extension KnownHeaderElement: Equatable {
static func < (lhs: KnownHeaderElement, rhs: KnownHeaderElement) -> Bool {
lhs.rawValue < rhs.rawValue
static func == (lhs: KnownHeaderElement, rhs: KnownHeaderElement) -> Bool {
lhs.description == rhs.description
}
}
extension KnownHeaderElement: Hashable {
func hash(into hasher: inout Hasher) {
hasher.combine(description)
}
}
@ -69,6 +92,12 @@ extension KnownHeaderElement: CustomStringConvertible {
return "image-compare-js"
case .imageCompareCss:
return "image-compare-css"
case .swiperCss:
return "swiper-css"
case .swiperJs:
return "swiper-js"
case .style(let style):
return "style: " + style
}
}
}