From 1bd727ababbb5836e2a5a0e4e7ee79f503b070ad Mon Sep 17 00:00:00 2001 From: wakingrufus Date: Wed, 7 Jan 2026 09:58:49 -0600 Subject: [PATCH] add dates to articles add github stars to projects --- .../github/wakingrufus/website/MyStyles.kt | 4 +- .../github/wakingrufus/website/MyWebsite.kt | 53 +++++++------------ .../website/articles/AdhocPolymorphism.kt | 11 +++- .../wakingrufus/website/articles/Cohost.kt | 2 +- .../github/wakingrufus/website/lib/Website.kt | 10 ++++ .../website/lib/article/Article.kt | 29 +++++++--- .../website/lib/dashboard/DashboardPanel.kt | 53 ++++++++++++++++--- .../website/lib/dashboard/SubPanel.kt | 3 +- 8 files changed, 111 insertions(+), 54 deletions(-) diff --git a/personal-site/src/main/kotlin/com/github/wakingrufus/website/MyStyles.kt b/personal-site/src/main/kotlin/com/github/wakingrufus/website/MyStyles.kt index 1921280..e7d8ddc 100644 --- a/personal-site/src/main/kotlin/com/github/wakingrufus/website/MyStyles.kt +++ b/personal-site/src/main/kotlin/com/github/wakingrufus/website/MyStyles.kt @@ -58,12 +58,12 @@ class MyStyles { } media("screen and (min-width: 481px) and (max-width: 3000px)") { body { - fontSize = 1.25.em + fontSize = 1.0.em } } media("screen and (min-width: 3001px)") { body { - fontSize = 1.5.em + fontSize = 1.25.em } } diff --git a/personal-site/src/main/kotlin/com/github/wakingrufus/website/MyWebsite.kt b/personal-site/src/main/kotlin/com/github/wakingrufus/website/MyWebsite.kt index b2bb266..b1b6cc6 100644 --- a/personal-site/src/main/kotlin/com/github/wakingrufus/website/MyWebsite.kt +++ b/personal-site/src/main/kotlin/com/github/wakingrufus/website/MyWebsite.kt @@ -49,8 +49,6 @@ import kotlinx.html.a import kotlinx.html.div import kotlinx.html.footer import kotlinx.html.h1 -import kotlinx.html.h2 -import kotlinx.html.h3 import kotlinx.html.img import kotlinx.html.li import kotlinx.html.link @@ -245,25 +243,25 @@ val mainPage = htmlPage("index.html") { val myDashboard: DIV.() -> Unit = { dashboard { topicPanel("Open Source Projects") { - subPanel("ktlint-gradle", "https://github.com/JLLeitschuh/ktlint-gradle") { + project("JLLeitschuh", "ktlint-gradle") { description { +"The most popular gradle plugin for ktlint. " +"I joined this project in 2023 and have been doing ongoing maintenance for it." } } - subPanel("khtmx", "https://github.com/wakingrufus/khtmx") { + project("wakingrufus", "khtmx") { description { +"This project provides a multi-platform Kotlin DSL which extends the kotlinx HTML DSL to support HTMX. " +"It also provides a DSL for Spring Boot which allows a seamless integration between Spring Boot routes and HTMX pages and templates." } } - subPanel("spring-funk", "https://github.com/wakingrufus/spring-funk") { + project("wakingrufus", "spring-funk") { description { +"A framework for declarative DSL configuration for Spring Boot. " +"Considered obsolete in Spring Boot 4+ given the introduction of BeanRegistrars. " } } - subPanel("JaMM", "https://github.com/wakingrufus/JaMM") { + project("wakingrufus", "JaMM") { description { +"JaMM is a queue-based music library and player for Linux/Mac/Windows desktop. " +"JaMM is written in JavaFx, and distributed with its own runtime using jlink and jpackage. " @@ -288,7 +286,7 @@ val myDashboard: DIV.() -> Unit = { +"Tourney is a desktop application which allows you to run an Elo gaming league. " } } - subPanel("lib-elo", "https://github.com/wakingrufus/lib-elo") { + project("wakingrufus", "lib-elo") { description { +"lib-elo is kotlin library which implements an Elo game rating system. " } @@ -335,7 +333,7 @@ val myDashboard: DIV.() -> Unit = { } subPanel("Spring Boot") { expandable() - entry("Functional Spring Boot"){ + entry("Functional Spring Boot") { link("$videoCamera Devnexus 2025", "https://www.youtube.com/watch?v=9njQ8Lun36c") link("Slides", "https://wakingrufus.github.io/functional-spring-boot/") } @@ -370,34 +368,19 @@ val myDashboard: DIV.() -> Unit = { entry("Concerns about Cohost", coHost.path) } } - } - dashboard { - h2 { - +"Other Interests" - } - panel("Music") { - // h3 { a(href = essentialMetal.path) { +"Essential Metal" } } - h3 { a(href = music2020.path) { +"Best Music of 2020" } } - h3 { a(href = music2021.path) { +"Best Music of 2021" } } - h3 { a(href = music2022.path) { +"Best Music of 2022" } } - h3 { a(href = music2023.path) { +"Best Music of 2023" } } - h3 { a(href = music2024.path) { +"Best Music of 2024" } } - h3 { a(href = music2025.path) { +"Best Music of 2025" } } - } - panel("TV / Film") { - h3 { - a(href = criterion2021.path) { - +"2021 Criterion Challenge Recap" - } - } - h3 { - a(href = criterion2022.path) { - +"2022 Criterion Challenge Recap" - } + topicPanel("Other Interests") { + subPanel("Music") { + entry("Best Music of 2020", music2020.path) + entry("Best Music of 2021", music2021.path) + entry("Best Music of 2022", music2022.path) + entry("Best Music of 2023", music2023.path) + entry("Best Music of 2024", music2024.path) + entry("Best Music of 2025", music2025.path) } - h3 { - a(href = "https://generationq.neocities.org/") { +"Generation Q" } - +": Star Trek TNG Podcast" + subPanel("Movies") { + entry("Letterboxd", "https://letterboxd.com/wakingrufus/") + entry("2021 Criterion Challenge Recap", criterion2021.path) + entry("2022 Criterion Challenge Recap", criterion2022.path) } } } diff --git a/personal-site/src/main/kotlin/com/github/wakingrufus/website/articles/AdhocPolymorphism.kt b/personal-site/src/main/kotlin/com/github/wakingrufus/website/articles/AdhocPolymorphism.kt index 19a123e..958ade9 100644 --- a/personal-site/src/main/kotlin/com/github/wakingrufus/website/articles/AdhocPolymorphism.kt +++ b/personal-site/src/main/kotlin/com/github/wakingrufus/website/articles/AdhocPolymorphism.kt @@ -1,7 +1,15 @@ package com.github.wakingrufus.website.articles import com.github.wakingrufus.website.lib.article.article -import com.github.wakingrufus.website.lib.code.* +import com.github.wakingrufus.website.lib.code.FUNCTION +import com.github.wakingrufus.website.lib.code.block +import com.github.wakingrufus.website.lib.code.call +import com.github.wakingrufus.website.lib.code.kotlin +import com.github.wakingrufus.website.lib.code.number +import com.github.wakingrufus.website.lib.code.on +import com.github.wakingrufus.website.lib.code.plain +import com.github.wakingrufus.website.lib.code.sampleCode +import com.github.wakingrufus.website.lib.code.string import com.github.wakingrufus.website.lib.htmlPage import com.github.wakingrufus.website.myFooter import kotlinx.html.ARTICLE @@ -313,6 +321,7 @@ This is a simple pattern I have found to write more testable functional Kotlin, val adhocPolymorphism = htmlPage("adhoc-polymorphism.html") { article("Testing Functional Kotlin") { + date("March 21, 2020") htmlSection(dependencyInjection) footer(myFooter) } diff --git a/personal-site/src/main/kotlin/com/github/wakingrufus/website/articles/Cohost.kt b/personal-site/src/main/kotlin/com/github/wakingrufus/website/articles/Cohost.kt index 67b526a..0e7e50e 100644 --- a/personal-site/src/main/kotlin/com/github/wakingrufus/website/articles/Cohost.kt +++ b/personal-site/src/main/kotlin/com/github/wakingrufus/website/articles/Cohost.kt @@ -10,8 +10,8 @@ import kotlinx.html.p val coHost = htmlPage("cohost.html") { article("Concerns about Cohost") { + date("November, 2022") htmlSection { - h3 { +"November, 2022" } p { +"With the recent buyout of Twitter by Elon Musk, many people have been discovering Mastodon/Fediverse. " +"I have been on the Fediverse since 2017, and I am a big fan of it, so I am glad that so many others are starting to discover its merits. " diff --git a/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/Website.kt b/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/Website.kt index 289f429..e32b480 100644 --- a/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/Website.kt +++ b/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/Website.kt @@ -134,6 +134,16 @@ fun BODY.pageTitle(title: String) { } } +fun BODY.pageSubTitle(title: String) { + return h3(classes = "") { + style = css { + backgroundColor = MyStyles.BACKGROUND_COLOR + textAlign = TextAlign.center + } + +title + } +} + fun htmlPage(path: String, builder: HtmlPage.() -> Unit): HtmlPage { return HtmlPage(path).apply(builder) } \ No newline at end of file diff --git a/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/article/Article.kt b/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/article/Article.kt index 83f6f57..b6adfb0 100644 --- a/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/article/Article.kt +++ b/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/article/Article.kt @@ -5,10 +5,22 @@ import com.github.wakingrufus.website.WebsiteDsl import com.github.wakingrufus.website.lib.HtmlPage import com.github.wakingrufus.website.lib.content import com.github.wakingrufus.website.lib.css +import com.github.wakingrufus.website.lib.pageSubTitle import com.github.wakingrufus.website.lib.pageTitle import com.github.wakingrufus.website.standardHead -import kotlinx.css.* -import kotlinx.html.* +import kotlinx.css.backgroundColor +import kotlinx.css.em +import kotlinx.css.marginLeft +import kotlinx.css.marginRight +import kotlinx.css.maxWidth +import kotlinx.css.pct +import kotlinx.html.ARTICLE +import kotlinx.html.BODY +import kotlinx.html.FOOTER +import kotlinx.html.article +import kotlinx.html.footer +import kotlinx.html.nav +import kotlinx.html.style @WebsiteDsl class ArticleBuilder(val title: String) { @@ -17,6 +29,7 @@ class ArticleBuilder(val title: String) { private var content: ARTICLE.() -> Unit = {} private val sections: MutableList
= mutableListOf() private var source: String? = null + private var subTitle: String? = null fun nav(nav: Navigation.() -> Unit) { this.nav = Navigation().apply(nav) @@ -38,6 +51,10 @@ class ArticleBuilder(val title: String) { this.source = source } + fun date(date: String) { + this.subTitle = date + } + fun getContent(): ARTICLE.() -> Unit = { sections.forEach { this.apply(it.content) @@ -47,6 +64,7 @@ class ArticleBuilder(val title: String) { operator fun invoke(page: BODY) { page.apply { pageTitle(this@ArticleBuilder.title) + this@ArticleBuilder.subTitle?.let { pageSubTitle(it) } content { style = css { marginLeft = 1.em @@ -58,11 +76,8 @@ class ArticleBuilder(val title: String) { } article { style = css { - if(nav != null){ - // display = Display.inlineBlock - if (nav != null) { - maxWidth = 79.pct - } + if (nav != null) { + maxWidth = 79.pct } } getContent().invoke(this) diff --git a/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/dashboard/DashboardPanel.kt b/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/dashboard/DashboardPanel.kt index 456c2ef..3b96546 100644 --- a/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/dashboard/DashboardPanel.kt +++ b/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/dashboard/DashboardPanel.kt @@ -18,14 +18,18 @@ import kotlinx.css.borderTopWidth import kotlinx.css.cursor import kotlinx.css.display import kotlinx.css.em +import kotlinx.css.marginBottom +import kotlinx.css.marginTop import kotlinx.css.maxWidth import kotlinx.css.paddingBottom import kotlinx.css.paddingLeft import kotlinx.css.paddingRight import kotlinx.css.paddingTop +import kotlinx.css.pct import kotlinx.css.px import kotlinx.css.textAlign import kotlinx.css.verticalAlign +import kotlinx.css.width import kotlinx.html.DETAILS import kotlinx.html.DIV import kotlinx.html.a @@ -33,6 +37,7 @@ import kotlinx.html.details import kotlinx.html.div import kotlinx.html.h2 import kotlinx.html.h3 +import kotlinx.html.img import kotlinx.html.p import kotlinx.html.span import kotlinx.html.style @@ -61,8 +66,13 @@ class DashboardPanel { } @WebsiteDsl - fun subPanel(title: String, href: String? = null, content: SubPanel.() -> Unit) { - subPanels.add(SubPanel(title, href).apply(content)) + fun subPanel(title: String, href: String? = null, imageUrl: String? = null, content: SubPanel.() -> Unit) { + subPanels.add(SubPanel(title, href, imageUrl).apply(content)) + } + + @WebsiteDsl + fun project(org: String, name: String, description: SubPanel.() -> Unit) { + subPanel(name, "https://github.com/$org/$name", "https://img.shields.io/github/stars/$org/$name", description) } private fun DIV.summary() { @@ -94,11 +104,37 @@ class DashboardPanel { } private fun DIV.subPanelSummary(subPanel: SubPanel) { - h3 { - if (subPanel.link == null) { - +subPanel.name - } else { - a(href = subPanel.link) { +subPanel.name } + div { + style = css { + marginTop = 8.px + display = Display.block + } + h3 { + style = css { + display = Display.inlineBlock + width = 49.pct + marginTop = 2.px + marginBottom = 2.px + } + if (subPanel.link == null) { + +subPanel.name + } else { + a(href = subPanel.link) { +subPanel.name } + } + } + div { + style = css { + display = Display.inlineBlock + width = 49.pct + textAlign = TextAlign.right + verticalAlign = VerticalAlign.middle + } + if (subPanel.image != null) { + a(href = subPanel.link) { + img(src = subPanel.image) { + } + } + } } } } @@ -125,6 +161,9 @@ class DashboardPanel { private fun DIV.renderSubPanelContent(subPanel: SubPanel) { p { + style = css { + paddingRight = 4.px + } subPanel.content.invoke(this) } div { diff --git a/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/dashboard/SubPanel.kt b/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/dashboard/SubPanel.kt index e876140..47df21c 100644 --- a/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/dashboard/SubPanel.kt +++ b/personal-site/src/main/kotlin/com/github/wakingrufus/website/lib/dashboard/SubPanel.kt @@ -6,7 +6,8 @@ import kotlinx.html.P @WebsiteDsl data class SubPanel( val name: String, - val link: String? = null + val link: String? = null, + val image: String? = null ) { var entries: MutableList = mutableListOf() var content: P.() -> Unit = {}