M Dockerfile => Dockerfile +2 -3
@@ 10,12 10,11 @@ RUN go mod download && go mod verify
COPY . .
-RUN --mount=type=cache,target=/root/.cache/go-build \
-CGO_ENABLED=0 GOOS=linux go build -ldflags=-X=main.version=${VERSION} -v -o /tixe ./tixe.go
+RUN CGO_ENABLED=0 GOOS=linux go build -ldflags=-X=main.version=${VERSION} -v -o /tixe ./tixe.go
# tester
FROM builder AS tester
-RUN --mount=type=cache,target=/root/.cache/go-build go test -v ./...
+RUN go test -v ./...
# release
FROM alpine:3.18 AS release
A scripts/demobuildpublish.elv => scripts/demobuildpublish.elv +7 -0
@@ 0,0 1,7 @@
+#!/usr/bin/env elvish
+
+var version = 'demo-'(git describe --tags)
+var image = 'registry.liljamo.dev/skye/tixe:'$version
+
+docker build -t $image . --build-arg 'VERSION='$version
+docker push $image
A static/demo.js => static/demo.js +21 -0
@@ 0,0 1,21 @@
+const formsToTrack = [
+ { "submit_id": "settings_submit_displayname", "form_id": "settings_form_displayname", "event": "settings-update-displayname" },
+ { "submit_id": "linkedit_submit_delete", "form_id": "linkedit_form_delete", "event": "linkedit-delete" },
+ { "submit_id": "linkedit_submit_visual", "form_id": "linkedit_form_visual", "event": "linkedit-update-visual" },
+ { "submit_id": "linkedit_submit_link", "form_id": "linkedit_form_link", "event": "linkedit-update-link" },
+ { "submit_id": "tags_submit_delete", "form_id": "tags_form_delete", "event": "tags-delete" },
+ { "submit_id": "tags_submit_new", "form_id": "tags_form_new", "event": "tags-new" },
+ { "submit_id": "index_submit_link_new", "form_id": "index_form_link_new", "event": "index-link-new" },
+];
+
+for (var i = 0; i < formsToTrack.length; i++) {
+ const obj = formsToTrack[i];
+ const submit = document.getElementById(obj.submit_id);
+
+ if (submit == null) {
+ continue;
+ }
+
+ submit.setAttribute("type", "button");
+ submit.setAttribute("onclick", `umami.track('${obj.event}').then(function() {document.getElementById('${obj.form_id}').submit()})`)
+}
M static/styles.css => static/styles.css +18 -4
@@ 767,6 767,11 @@ video {
border-bottom-width: 2px;
}
+.bg-rose-200 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(254 205 211 / var(--tw-bg-opacity));
+}
+
.bg-slate-50 {
--tw-bg-opacity: 1;
background-color: rgb(248 250 252 / var(--tw-bg-opacity));
@@ 877,6 882,10 @@ video {
padding-right: 1rem;
}
+.text-center {
+ text-align: center;
+}
+
.text-lg {
font-size: 1.125rem;
line-height: 1.75rem;
@@ 901,15 910,20 @@ video {
font-weight: 700;
}
-.text-transparent {
- color: transparent;
-}
-
.text-amber-500 {
--tw-text-opacity: 1;
color: rgb(245 158 11 / var(--tw-text-opacity));
}
+.text-orange-500 {
+ --tw-text-opacity: 1;
+ color: rgb(249 115 22 / var(--tw-text-opacity));
+}
+
+.text-transparent {
+ color: transparent;
+}
+
.opacity-0 {
opacity: 0;
}
M template/templates/common/base.tmpl => template/templates/common/base.tmpl +18 -4
@@ 2,6 2,8 @@
<!DOCTYPE html>
<html>
<head>
+ <script async src="https://umami.liljamo.dev/script.js" data-website-id="f8cea9a6-6aff-4c31-b9ce-d99852500703"></script>
+
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ 13,9 15,20 @@
<body>
<main>
<div class="flex flex-col w-full items-center p-4">
+ <div class="flex flex-col w-full items-center justify-center bg-rose-200">
+ <p>This is a demo instance.</p>
+ <p class="text-center max-w-4xl">
+ Data on this instance is <span class="font-bold">wiped every hour</span>, on the hour.
+ During that time (usually a minute or two), the site will be unreachable.
+ </p>
+ <p class="text-center max-w-4xl">
+ umami is used to collect usage data on the demo, the data is
+ viewable <a data-umami-event="demo-header-umami-share" class="text-orange-500 font-bold hover:underline" href="https://umami.liljamo.dev/share/zz12HvMPd6Ii9wGC/tixe%20demo" target="_blank">here</a>
+ </p>
+ </div>
<div class="flex w-full max-w-4xl items-center gap-4">
<div class="w-max">
- <a class="bg-size-200 bg-pos-0 hover:bg-pos-100
+ <a data-umami-event="header-home" class="bg-size-200 bg-pos-0 hover:bg-pos-100
bg-gradient-to-br from-slate-600 via-blue-400 to-rose-500
bg-clip-text text-lg font-bold text-transparent
transition-all duration-500"
@@ 25,7 38,7 @@
</div>
<div class="flex flex-row-reverse w-full pr-4">
{{ if eq .notauthed nil }}
- <a class="hover:underline" href="/tags">tags</a>
+ <a data-umami-event="header-tags" class="hover:underline" href="/tags">tags</a>
{{ end }}
</div>
<div class="flex flex-col min-w-max">
@@ 34,7 47,7 @@
{{ else if ne .user nil }}
<div class="group w-fit">
<div class="group-hover:animate-wiggle">
- <a class="font-bold animate-starshoot1 hover:underline" href="/settings">{{ .user.DisplayName }}</a>
+ <a data-umami-event="header-settings" class="font-bold animate-starshoot1 hover:underline" href="/settings">{{ .user.DisplayName }}</a>
</div>
<div class="absolute group-hover:animate-starmove">
<svg class="z-50 invisible opacity-0 h-4 w-4 fill-yellow-200 stroke-yellow-400 group-hover:visible group-hover:animate-starspin" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ 42,7 55,7 @@
</svg>
</div>
</div>
- <a class="self-end text-sm hover:underline" href="/auth/logout">Logout</a>
+ <a data-umami-event="header-logout" class="self-end text-sm hover:underline" href="/auth/logout">Logout</a>
{{ end }}
</div>
</div>
@@ 51,6 64,7 @@
</div>
</div>
</main>
+ <script src="/static/demo.js"></script>
</body>
</html>
{{ end }}
M template/templates/index.tmpl => template/templates/index.tmpl +4 -4
@@ 9,7 9,7 @@
</div>
<div class="select-none">New link</div>
</summary>
- <form class="flex flex-col p-1 origin-top group-open/summary:animate-[newlink_300ms_ease-in-out]" action="/api/link/new" method="POST">
+ <form id="index_form_link_new" class="flex flex-col p-1 origin-top group-open/summary:animate-[newlink_300ms_ease-in-out]" action="/api/link/new" method="POST">
<p class="text-sm" for="visual">Visual</p>
<div class="flex gap-2">
<input class="tixe-input h-8 w-full" type="text" placeholder="..." name="visual" id="visual"/>
@@ 17,7 17,7 @@
<p class="text-sm" for="link">Link</p>
<div class="flex gap-2">
<input class="tixe-input h-8 w-full" type="text" placeholder="..." name="link" id="link"/>
- <button class="group/submit w-fit h-8 p-1 border-2 rounded-md drop-shadow-md bg-slate-50 hover:bg-slate-200 transition-colors" type="submit">
+ <button id="index_submit_link_new" class="group/submit w-fit h-8 p-1 border-2 rounded-md drop-shadow-md bg-slate-50 hover:bg-slate-200 transition-colors" type="submit">
<svg class="absolute h-5 w-5 stroke-emerald-600 group-hover/submit:stroke-emerald-700 transition-colors" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 12L12 12M12 12L9 12M12 12L12 9M12 12L12 15" stroke-width="1.5" stroke-linecap="round"/>
</svg>
@@ 31,10 31,10 @@
<div class="flex flex-wrap justify-center gap-1">
{{ range $link := .data.Links }}
<div class="m-2 p-2 border-2 rounded-md min-w-[12rem] inline-block">
- <a class="hover:underline" href="{{ $link.Link }}" target="blank">{{ $link.Visual }}</a>
+ <a data-umami-event="index-link-open" class="hover:underline" href="{{ $link.Link }}" target="blank">{{ $link.Visual }}</a>
<p class="text-xs">Insert description here</p>
<div class="flex flex-row-reverse">
- <a href="/link/{{ $link.Id }}">
+ <a data-umami-event="index-link-edit" href="/link/{{ $link.Id }}">
<div class="group h-5 w-5">
<div class="pointer-events-none absolute translate-x-[-22%] translate-y-[-18%] group-hover:animate-penmove">
<svg class="h-5 w-5 stroke-slate-600 origin-bottom-left group-hover:animate-penrotate" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
M template/templates/linkedit.tmpl => template/templates/linkedit.tmpl +7 -7
@@ 1,7 1,7 @@
{{ define "content" }}
<div class="flex flex-col gap-2">
<div class="flex w-full justify-center">
- <a class="text-lg hover:underline" href={{ .data.Link }} target="blank">{{ .data.Visual }}</a>
+ <a data-umami-event="linkedit-open" class="text-lg hover:underline" href={{ .data.Link }} target="blank">{{ .data.Visual }}</a>
</div>
<div class="flex w-36">
@@ 21,27 21,27 @@
</svg>
</div>
<div class="pl-1 hidden peer-checked:block">
- <form action="/api/link/{{ .data.Id }}/delete" method="POST">
- <button class="hover:underline" type="submit">Confirm</button>
+ <form id="linkedit_form_delete" action="/api/link/{{ .data.Id }}/delete" method="POST">
+ <button id="linkedit_submit_delete" class="hover:underline" type="submit">Confirm</button>
</form>
</div>
</div>
</div>
- <form class="flex flex-col" action="/api/link/{{ .data.Id }}/visual" method="POST">
+ <form id="linkedit_form_visual" class="flex flex-col" action="/api/link/{{ .data.Id }}/visual" method="POST">
<p class="text-sm" for="visual">Visual</p>
<div class="flex gap-2">
<input class="tixe-input w-full" type="text" value="{{ .data.Visual }}" name="visual" id="visual"/>
- <button class="w-fit p-1 border-2 rounded-md drop-shadow-md bg-slate-50 hover:bg-slate-200 transition-colors" type="submit">
+ <button id="linkedit_submit_visual" class="w-fit p-1 border-2 rounded-md drop-shadow-md bg-slate-50 hover:bg-slate-200 transition-colors" type="submit">
Update
</button>
</div>
</form>
- <form class="flex flex-col" action="/api/link/{{ .data.Id }}/link" method="POST">
+ <form id="linkedit_form_link" class="flex flex-col" action="/api/link/{{ .data.Id }}/link" method="POST">
<p class="text-sm" for="link">Link</p>
<div class="flex gap-2">
<input class="tixe-input w-full" type="text" value="{{ .data.Link }}" name="link" id="link"/>
- <button class="w-fit p-1 border-2 rounded-md drop-shadow-md bg-slate-50 hover:bg-slate-200 transition-colors" type="submit">
+ <button id="linkedit_submit_link" class="w-fit p-1 border-2 rounded-md drop-shadow-md bg-slate-50 hover:bg-slate-200 transition-colors" type="submit">
Update
</button>
</div>
M template/templates/login.tmpl => template/templates/login.tmpl +1 -1
@@ 1,6 1,6 @@
{{ define "content" }}
<p class="text-xl p-2 border-b-2">Login</p>
-<a class="w-max p-2 border-2
+<a data-umami-event="login-oidc" class="w-max p-2 border-2
rounded-md drop-shadow-md
bg-slate-50 hover:bg-slate-200 transition-colors"
href="/auth/login">
M template/templates/settings.tmpl => template/templates/settings.tmpl +2 -2
@@ 7,11 7,11 @@
Settings
</p>
-<form class="flex flex-col" action="/api/settings/user/display_name" method="POST">
+<form id="settings_form_displayname" class="flex flex-col" action="/api/settings/user/display_name" method="POST">
<p class="text-sm" for="display_name">Display Name</p>
<div class="flex gap-2">
<input class="tixe-input w-full" type="text" placeholder="{{ .user.DisplayName }}" name="display_name" id="display_name"/>
- <button class="w-fit p-1 border-2 rounded-md drop-shadow-md bg-slate-50 hover:bg-slate-200 transition-colors" type="submit">
+ <button id="settings_submit_displayname" class="w-fit p-1 border-2 rounded-md drop-shadow-md bg-slate-50 hover:bg-slate-200 transition-colors" type="submit">
Update
</button>
</div>
M template/templates/tags.tmpl => template/templates/tags.tmpl +4 -4
@@ 6,11 6,11 @@
>
Tags
</p>
-<form class="flex flex-col" action="/api/tags/new" method="POST">
+<form id="tags_form_new" class="flex flex-col" action="/api/tags/new" method="POST">
<p class="text-sm" for="tag">New Tag</p>
<div class="flex gap-2">
<input class="tixe-input h-8 w-full" type="text" placeholder="..." name="tag" id="tag"/>
- <button class="group w-fit h-8 p-1 border-2 rounded-md drop-shadow-md bg-slate-50 hover:bg-slate-200 transition-colors" type="submit">
+ <button id="tags_submit_new" class="group w-fit h-8 p-1 border-2 rounded-md drop-shadow-md bg-slate-50 hover:bg-slate-200 transition-colors" type="submit">
<svg class="absolute h-5 w-5 stroke-emerald-600 group-hover:stroke-emerald-700 transition-colors" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 12L12 12M12 12L9 12M12 12L12 9M12 12L12 15" stroke-width="1.5" stroke-linecap="round"/>
</svg>
@@ 31,9 31,9 @@
<div class="flex flex-row-reverse w-full">
<p>{{ $tag.TimesUsed }}</p>
</div>
- <form class="min-w-max" action="/api/tags/delete" method="POST">
+ <form id="tags_form_delete" class="min-w-max" action="/api/tags/delete" method="POST">
<input class="hidden" type="text" name="id" id="id" value="{{ $tag.Id }}"/>
- <button class="flex items-center" type="submit">
+ <button id="tags_submit_delete" class="flex items-center" type="submit">
<div class="group h-5 w-5">
<div class="absolute group-hover:animate-lidjump">
<svg class="group-hover:animate-lidflip h-fit w-5 stroke-rose-600" viewBox="0 0 24 12" fill="none" xmlns="http://www.w3.org/2000/svg">