Skip to content

Commit

Permalink
GH-2254 Initialize ui based on jte + htmx + tailwindcss + preact (opt…
Browse files Browse the repository at this point in the history
…ional)
  • Loading branch information
dzikoysk committed Oct 27, 2024
1 parent 7d08eaa commit 4bd797c
Show file tree
Hide file tree
Showing 17 changed files with 200 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ reposilite-test/workspace/javadocs/
reposilite-test/workspace/logs/
reposilite-test/workspace/plugins/*.jar
reposilite-backend/src/generated/kotlin/com/reposilite/ReposiliteProperties.kt
.build/

### Kotlin ###
.kotlin/
Expand Down
5 changes: 5 additions & 0 deletions reposilite-backend/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ dependencies {

val javalin = "6.3.0"
api("io.javalin:javalin:$javalin")
implementation("io.javalin:javalin-rendering:$javalin")

val javalinOpenApi = "6.3.0"
api("io.javalin.community.openapi:javalin-openapi-plugin:$javalinOpenApi")
Expand All @@ -51,6 +52,10 @@ dependencies {
val javalinRouting = "6.3.0"
api("io.javalin.community.routing:routing-dsl:$javalinRouting")

val jte = "3.1.13"
implementation("gg.jte:jte:$jte")
implementation("gg.jte:jte-watcher:$jte")

val bcrypt = "0.10.2"
implementation("at.favre.lib:bcrypt:$bcrypt")

Expand Down
35 changes: 35 additions & 0 deletions reposilite-backend/src/main/kotlin/com/reposilite/ui/UiPlugin.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package com.reposilite.ui

import com.reposilite.plugin.api.Facade
import com.reposilite.plugin.api.Plugin
import com.reposilite.plugin.api.ReposilitePlugin
import com.reposilite.plugin.event
import com.reposilite.ui.jtx.JtexConfig
import com.reposilite.ui.jtx.JtexPlugin
import com.reposilite.web.api.HttpServerConfigurationEvent
import io.javalin.http.Context
import io.javalin.router.JavalinDefaultRouting

@Plugin(name = "ui")
internal class UiPlugin : ReposilitePlugin() {

override fun initialize(): Facade? {
event { event: HttpServerConfigurationEvent ->
event.config.registerPlugin(
JtexPlugin {
it.mode = JtexConfig.Mode.RESOURCE
it.path = "ui"
}
)

event.config.router.mount { routing: JavalinDefaultRouting ->
routing
.get("/") { ctx: Context -> ctx.render("index.jte") }
.post("/clicked") { ctx: Context -> ctx.result("Panda") }
}
}

return null
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.reposilite.ui.jtx

import gg.jte.resolve.DirectoryCodeResolver
import java.nio.file.Path

class JtexDictionaryCodeResolver(path: Path) : DirectoryCodeResolver(path) {

override fun resolveRequired(name: String?): String {
val content = super.resolveRequired(name)
return content
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.reposilite.ui.jtx

import gg.jte.ContentType
import gg.jte.TemplateEngine
import gg.jte.resolve.DirectoryCodeResolver
import gg.jte.resolve.ResourceCodeResolver
import gg.jte.watcher.DirectoryWatcher
import io.javalin.config.JavalinConfig
import io.javalin.plugin.Plugin
import io.javalin.rendering.template.JavalinJte
import java.nio.file.Paths
import java.util.function.Consumer

class JtexConfig {

enum class Mode {
RESOURCE,
DIRECTORY,
}

@JvmField var mode: Mode = Mode.RESOURCE
@JvmField var path: String = "src/main/resources"
@JvmField var sseRefreshEndpoint: String = "/refreshDevMode"
}

class JtexPlugin(userConfig: Consumer<JtexConfig>) : Plugin<JtexConfig>(userConfig = userConfig, defaultConfig = JtexConfig()) {

override fun onStart(config: JavalinConfig) {
val codeResolver = when(pluginConfig.mode) {
JtexConfig.Mode.RESOURCE -> ResourceCodeResolver(pluginConfig.path)
JtexConfig.Mode.DIRECTORY -> JtexDictionaryCodeResolver(Paths.get(pluginConfig.path).toAbsolutePath().normalize())
}
Paths.get("jte-classes")
val templatingEngine = TemplateEngine.create(codeResolver, Paths.get(".build"), ContentType.Html)
templatingEngine.setProjectNamespace(".compiled")
config.fileRenderer(JavalinJte(templatingEngine))

config.router.mount {
it.sse(pluginConfig.sseRefreshEndpoint) { sseClient ->
if (codeResolver is DirectoryCodeResolver) {
val watcher = DirectoryWatcher(templatingEngine, codeResolver)

watcher.start { templates ->
System.out.println("[watcher] Template changed, available at http://localhost:${config.jetty.defaultPort}")
sseClient.sendEvent("refresh", "Template changed, refresh browser event")
}

sseClient.onClose(watcher::stop)
sseClient.keepAlive()
}
}
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ com.reposilite.status.application.StatusPlugin
com.reposilite.storage.StoragePlugin
com.reposilite.status.application.FailurePlugin
com.reposilite.token.application.AccessTokenPlugin
com.reposilite.web.application.WebPlugin
com.reposilite.web.application.WebPlugin
com.reposilite.ui.UiPlugin
Empty file.
12 changes: 12 additions & 0 deletions reposilite-backend/src/main/resources/ui/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# UI

# Option 1

1. Run application as usual and open http://localhost:8080 in your browser.
2. Whenever a JTE file is changes, hit CTRL + SHIFT + F9 to recompile the template.
3. Refresh the browser to see the changes.

# Option 2

1. Run JtexPlugin in directory mode and provide absolute path to the UI directory in resources
2. Whenever a JTE file changes, the page will be reloaded automatically
26 changes: 26 additions & 0 deletions reposilite-backend/src/main/resources/ui/component/Foo.jte
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<div id="app"></div>

<script type="importmap">
{
"imports": {
"preact": "https://esm.sh/[email protected]",
"preact/": "https://esm.sh/[email protected]/",
"htm/preact": "https://esm.sh/[email protected]/preact?external=preact"
}
}
</script>

@raw
<script type="module">
import { render } from 'preact';
import { useState } from 'preact/hooks';
import { html } from 'htm/preact';
export function App() {
const [count, setCount] = useState(0);
return html`<button onClick=${() => setCount(count + 1)}>Increment ${count}</button>`;
}
render(html`<${App}><//>`, document.getElementById("app"))
</script>
@endraw
3 changes: 3 additions & 0 deletions reposilite-backend/src/main/resources/ui/component/Footer.jte
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<footer>

</footer>
11 changes: 11 additions & 0 deletions reposilite-backend/src/main/resources/ui/component/Head.jte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@param String title

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${title}</title>

@template.lib.HTMX()
@template.lib.Tailwind()
@template.lib.DevMode()
</head>
5 changes: 5 additions & 0 deletions reposilite-backend/src/main/resources/ui/component/Header.jte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
@param String title

<header class="border-b-1 border-gray-50 h-16 flex items-center w-full">
<p class="px-2">${title}</p>
</header>
16 changes: 16 additions & 0 deletions reposilite-backend/src/main/resources/ui/index.jte
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html lang="en">
@template.component.Head(title = "Reposilite")

<body class="min-h-full text-white min-w-full bg-black">
@template.component.Header(title = "Reposilite")

<button hx-post="/clicked" hx-swap="innerHTML">
Click me
</button>

@template.component.Foo()

@template.component.Footer()
</body>
</html>
7 changes: 7 additions & 0 deletions reposilite-backend/src/main/resources/ui/lib/DevMode.jte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
const eventSource = new EventSource("refreshDevMode");
eventSource.addEventListener("refresh", (data) => {
console.info(data)
location.reload()
})
</script>
1 change: 1 addition & 0 deletions reposilite-backend/src/main/resources/ui/lib/HTMX.jte
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<script src="https://unpkg.com/[email protected]"></script>
1 change: 1 addition & 0 deletions reposilite-backend/src/main/resources/ui/lib/Tailwind.jte
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<script src="https://cdn.tailwindcss.com"></script>
7 changes: 7 additions & 0 deletions reposilite-backend/src/main/resources/ui/lib/fonts/Inter.jte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<link rel="stylesheet" href="https://rsms.me/inter/inter.css">

<style>
* {
font-family: 'Inter', sans-serif;
}
</style>

0 comments on commit 4bd797c

Please sign in to comment.