Styled and animated zaps
This commit is contained in:
parent
4eaf0e1003
commit
56236d5409
|
@ -1,4 +1,5 @@
|
|||
.env
|
||||
zaply
|
||||
*_templ.go
|
||||
__livereload
|
||||
__livereload
|
||||
public/css/tailwind.css
|
||||
|
|
1
Makefile
1
Makefile
|
@ -5,4 +5,5 @@ dev:
|
|||
|
||||
build:
|
||||
templ generate
|
||||
tailwindcss -i ./public/css/input.css -o ./public/css/tailwind.css
|
||||
go build -o zaply main.go
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
package components
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/ekzyis/zaply/lightning"
|
||||
)
|
||||
|
||||
templ Zap(inv *lightning.Invoice) {
|
||||
<div class="bg-[#212529] w-fit zap-animate-in border border-[#212529] m-3 rounded-lg" id={ inv.PaymentHash }>
|
||||
<div class="flex flex-row gap-3 items-center">
|
||||
<svg width="32" height="32" viewBox="0 0 200 307" fill="#fada5e" xmlns="http://www.w3.org/2000/svg" class="ps-3">
|
||||
<path d="M56 0L107.606 131H90.2129H89L1.52588e-05 131L177 307L106.979 165H121H160H200L56 0Z"/>
|
||||
</svg>
|
||||
<div class="flex flex-col pe-3 py-1">
|
||||
<div class="text-lg text-[#f0f0f0]">{ inv.Description }</div>
|
||||
<div class="text-sm text-slate-300">{ fmt.Sprintf("%.8s / %s", inv.PaymentHash, humanize(inv.Msats)) }</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
func humanize(msats int64) string {
|
||||
sats := msats / 1000
|
||||
if sats == 1 {
|
||||
return fmt.Sprintf("%d sat", sats)
|
||||
} else {
|
||||
return fmt.Sprintf("%d sats", sats)
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
PID=$(pidof zaply)
|
||||
DIRS="env/ lightning/ lnurl/ pages/ server/"
|
||||
DIRS="components/ env/ lightning/ lnurl/ pages/ server/"
|
||||
|
||||
set -e
|
||||
|
||||
|
|
|
@ -6,27 +6,25 @@ templ Overlay() {
|
|||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>zaply</title>
|
||||
<link href="/css/tailwind.css" rel="stylesheet">
|
||||
<link href="/css/zap.css" rel="stylesheet">
|
||||
<script src={ GetBaseUrl(ctx) + "/js/htmx.min.js" } integrity="sha384-HGfztofotfshcF7+8n44JQL2oJmowVChPTg48S+jvZoztPfvwD79OC/LTtG6dMp+" crossorigin="anonymous"></script>
|
||||
<script src={ GetBaseUrl(ctx) + "/js/htmx-sse.js" } crossorigin="anonymous"></script>
|
||||
if GetEnv(ctx) == "development" {
|
||||
<script src={ GetBaseUrl(ctx) + "/js/livereload.js" }></script>
|
||||
}
|
||||
</head>
|
||||
<body>
|
||||
<div hx-ext="sse" sse-connect="/overlay/sse" sse-swap="zap" hx-swap="beforeend" class="fixed bottom-0 right-0" />
|
||||
<script>
|
||||
const sse = new EventSource("/overlay/sse");
|
||||
sse.onmessage = (event) => {
|
||||
// console.log("event", event)
|
||||
};
|
||||
sse.addEventListener("zap", event => {
|
||||
let inv
|
||||
try {
|
||||
inv = JSON.parse(event.data)
|
||||
} catch(err) {
|
||||
console.error("error parsing zap event", err)
|
||||
return
|
||||
}
|
||||
console.log("zap received:", inv.paymentHash, inv.msats, inv.description)
|
||||
document.body.addEventListener('htmx:sseMessage', function (e) {
|
||||
setTimeout(() => {
|
||||
const div = document.getElementById(e.detail.lastEventId)
|
||||
div.classList.add('zap-animate-out')
|
||||
div.addEventListener('animationend', div.remove)
|
||||
}, 60_000)
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
</body>
|
||||
</html>
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
.zap-animate-in {
|
||||
animation: slide-in 0.5s ease-out;
|
||||
}
|
||||
|
||||
.zap-animate-out {
|
||||
animation: fade-out 0.5s ease-out;
|
||||
}
|
||||
|
||||
@keyframes slide-in {
|
||||
0% {
|
||||
transform: translateY(100%);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0%)
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade-out {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
|
@ -2,17 +2,19 @@ package server
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
"github.com/ekzyis/zaply/components"
|
||||
"github.com/ekzyis/zaply/lightning"
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
type Event struct {
|
||||
Id []byte
|
||||
Event []byte
|
||||
Data []byte
|
||||
}
|
||||
|
@ -28,6 +30,10 @@ func (ev *Event) MarshalTo(w io.Writer) error {
|
|||
}
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprintf(w, "id: %s\n", ev.Id); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := fmt.Fprint(w, "\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -61,14 +67,17 @@ func sseHandler(invSrc chan *lightning.Invoice) echo.HandlerFunc {
|
|||
return err
|
||||
}
|
||||
case inv := <-invSrc:
|
||||
data, err := json.Marshal(inv)
|
||||
if err != nil {
|
||||
buf := templ.GetBuffer()
|
||||
defer templ.ReleaseBuffer(buf)
|
||||
|
||||
if err := components.Zap(inv).Render(c.Request().Context(), buf); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
event := Event{
|
||||
Id: []byte(inv.PaymentHash),
|
||||
Event: []byte("zap"),
|
||||
Data: data,
|
||||
Data: buf.Bytes(),
|
||||
}
|
||||
|
||||
log.Printf("sending zap event: %s", inv.PaymentHash)
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: ["./components/**/*.templ", "./pages/**/*.templ"],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
Loading…
Reference in New Issue