site upgrades

This commit is contained in:
Sergey Chernov 2026-03-27 22:36:23 +03:00
parent a98fe51983
commit 86e8b2e2bc
5 changed files with 104 additions and 8 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2025 Sergey S. Chernov real.sergeych@gmail.com
* Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -117,10 +117,27 @@ val generateDocsIndex by tasks.registering {
}
}
val generateSiteVersion by tasks.registering(Copy::class) {
group = "documentation"
description = "Generates lyng-version.js from :lynglib version"
val outDir = layout.buildDirectory.dir("generated-resources")
val versionText = project(":lynglib").version.toString()
inputs.property("lyngVersion", versionText)
from(layout.projectDirectory.dir("src/version-template")) {
include("lyng-version.js")
filter<org.apache.tools.ant.filters.ReplaceTokens>(
"tokens" to mapOf("LYNG_VERSION" to versionText)
)
}
into(outDir)
}
// Ensure any ProcessResources task depends on docs index generation so the JSON is packaged
tasks.configureEach {
if (name.endsWith("ProcessResources")) {
dependsOn(generateDocsIndex)
dependsOn(generateDocsIndex, generateSiteVersion)
}
}
@ -143,4 +160,4 @@ tasks.named<Copy>("jsProcessResources").configure {
}
}
// Optional: configure toolchain if needed by the project; uses root Kotlin version from version catalog
// Optional: configure toolchain if needed by the project; uses root Kotlin version from version catalog

View File

@ -70,6 +70,7 @@ fun App() {
PageTemplate(title = when {
isDocsRoute -> null
route.startsWith("authors") -> "Authors"
route.startsWith("reference") -> "Reference"
route.isBlank() -> null
else -> null
@ -118,6 +119,7 @@ fun App() {
Div({ classes("col-12", if (isDocsRoute) "col-lg-9" else "col-lg-12") }) {
when {
route.isBlank() -> HomePage()
route.startsWith("authors") -> AuthorsPage()
route.startsWith("tryling") -> TryLyngPage(route)
route.startsWith("search") -> SearchPage(route)
!isDocsRoute -> ReferencePage()

View File

@ -0,0 +1,63 @@
/*
* Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import androidx.compose.runtime.Composable
import org.jetbrains.compose.web.dom.*
@Composable
fun AuthorsPage() {
Div({ classes("text-center", "mb-4") }) {
P({
classes("lead", "text-muted", "mb-0", "mx-auto")
attr("style", "max-width: 42rem;")
}) {
Text("Designed and built with care. Special thanks to everyone around Lyng who helped shape the language, the tools, and the site into what it is now.")
}
}
Div({ classes("row", "g-4", "justify-content-center") }) {
listOf(
Triple(
"Sergey Chernov",
"Initial idea and architecture, language concept, design, implementation.",
Pair("@sergeych", "https://www.gravatar.com/avatar/7e3a56ff8a090fc9ffbd1909dea94904?s=128&d=identicon")
),
Triple(
"Yulia Nezhinskaya",
"System analysis, math and feature design.",
Pair("@AlterEgoJuliaN", "https://www.gravatar.com/avatar/53a90bca30c85a81db8f0c0d8dea43a1?s=128&d=identicon")
)
).forEach { (name, bio, profile) ->
Div({ classes("col-12", "col-lg-5") }) {
Div({ classes("h-100", "p-4", "border", "rounded-4", "bg-body-tertiary", "text-center") }) {
Img(
src = profile.second,
alt = name,
attrs = {
classes("rounded-circle", "mb-3")
attr("width", "88")
attr("height", "88")
}
)
H2({ classes("h4", "mb-1") }) { Text(name) }
P({ classes("text-primary", "small", "mb-2") }) { Text(profile.first) }
P({ classes("text-muted", "mb-0") }) { Text(bio) }
}
}
}
}
}

View File

@ -287,8 +287,8 @@ fun HomePage() {
}
}
// Bottom section with a small Telegram button
Div({ classes("text-center", "mt-5", "pb-4") }) {
// Bottom section with Telegram and authors links
Div({ classes("text-center", "mt-5", "d-flex", "justify-content-center", "gap-2", "flex-wrap") }) {
A(attrs = {
classes("btn", "btn-outline-primary", "btn-sm")
attr("href", "https://t.me/lynglang")
@ -298,6 +298,13 @@ fun HomePage() {
I({ classes("bi", "bi-telegram", "me-1") })
Text("Join our Telegram channel")
}
A(attrs = {
classes("btn", "btn-outline-secondary", "btn-sm")
attr("href", "#/authors")
}) {
I({ classes("bi", "bi-people", "me-1") })
Text("Meet the authors")
}
}
}

View File

@ -332,16 +332,22 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/highlight.min.js"></script>
<!-- and it's easy to individually load additional languages -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.11.1/languages/go.min.js"></script>
<script src="lyng-version.js"></script>
</head>
<body>
<!-- Top-left version ribbon -->
<div class="corner-ribbon bg-danger text-white">
<span style="margin-left: -5em">
v1.5.2
<span id="lyng-version-ribbon" style="margin-left: -5em">
</span>
</div>
<script>
document.addEventListener("DOMContentLoaded", function () {
var ribbon = document.getElementById("lyng-version-ribbon");
if (ribbon) ribbon.textContent = "v" + (window.LYNG_VERSION || "");
});
</script>
<!-- Fixed top navbar for the whole site -->
<a href="#root" class="visually-hidden-focusable position-absolute top-0 start-0 m-2 px-2 py-1 bg-body border rounded">Skip
to content</a>
@ -384,6 +390,7 @@
<!-- Will be populated at runtime -->
<li><a class="dropdown-item" href="#/docs/tutorial.md" data-route="docs">Tutorial</a></li>
<li><a class="dropdown-item" href="#/reference" data-route="reference">Reference</a></li>
<li><a class="dropdown-item" href="#/authors" data-route="authors">Authors</a></li>
<li>
<hr class="dropdown-divider">
</li>
@ -485,7 +492,7 @@
var activeLink = null;
if (!hash || hash === '#' || hash === '#/') {
activeLink = document.querySelector('#topbarNav .nav-link[data-route="home"]');
} else if (hash.startsWith('#/docs/')) {
} else if (hash.startsWith('#/docs/') || hash.startsWith('#/authors')) {
// Mark Docs menu root as active
activeLink = document.querySelector('#topbarNav .nav-link.dropdown-toggle');
} else if (hash.startsWith('#/reference')) {