tailwind debug mode and build mode for prod and other adjustments.

This commit is contained in:
fiatjaf
2023-10-26 16:02:18 -03:00
parent e7d1b37ca7
commit f9e099c840
20 changed files with 141 additions and 127 deletions

View File

@@ -5,7 +5,7 @@ tmp_dir = "tmp"
[build]
args_bin = []
bin = "./tmp/main"
cmd = "go build -tags=nocache -o ./tmp/main ."
cmd = "just debug-build"
delay = 0
exclude_dir = ["tmp", "vendor", "testdata", "node_modules"]
exclude_file = []

3
.gitignore vendored
View File

@@ -2,4 +2,5 @@ njump
local/
tmp/
node_modules/
.sass-cache/
.sass-cache/
static/tailwind-bundle.min.css

View File

@@ -1,4 +1,7 @@
build:
dev:
TAILWIND_DEBUG=true go run .
build: tailwind
CC=$(which musl-gcc) go build -ldflags='-s -w -linkmode external -extldflags "-static"' -o ./njump
deploy: build
@@ -7,8 +10,11 @@ deploy: build
ssh turgot 'mv njump/njump-new njump/njump'
ssh root@turgot 'systemctl start njump'
refresh_build: scss prettier
debug-build: tailwind
go build -tags=nocache -o ./tmp/main .
prettier:
prettier -w templates/*.html
tailwind:
tailwind -i tailwind.css -o static/tailwind-bundle.min.css --minify

30
main.go
View File

@@ -3,8 +3,11 @@ package main
import (
"context"
"embed"
"fmt"
"html/template"
"net/http"
"os"
"strings"
"time"
"github.com/kelseyhightower/envconfig"
@@ -14,8 +17,9 @@ import (
type Settings struct {
Port string `envconfig:"PORT" default:"2999"`
DiskCachePath string `envconfig:"DISK_CACHE_PATH" default:"/tmp/njump-cache"`
Domain string `envconfig:"DOMAIN" default:"njump.me"`
DiskCachePath string `envconfig:"DISK_CACHE_PATH" default:"/tmp/njump-cache"`
TailwindDebug bool `envconfig:"TAILWIND_DEBUG"`
}
//go:embed static/*
@@ -25,8 +29,9 @@ var static embed.FS
var templates embed.FS
var (
s Settings
log = zerolog.New(os.Stderr).Output(zerolog.ConsoleWriter{Out: os.Stdout}).With().Timestamp().Logger()
s Settings
log = zerolog.New(os.Stderr).Output(zerolog.ConsoleWriter{Out: os.Stdout}).With().Timestamp().Logger()
tailwindDebugStuff template.HTML
)
func updateArchives(ctx context.Context) {
@@ -56,6 +61,25 @@ func main() {
}
}
// if we're in tailwind debug mode, initialize the runtime tailwind stuff
if s.TailwindDebug {
configb, err := os.ReadFile("tailwind.config.js")
if err != nil {
log.Fatal().Err(err).Msg("failed to load tailwind.config.js")
return
}
config := strings.Replace(string(configb), "module.exports", "tailwind.config", 1)
styleb, err := os.ReadFile("tailwind.css")
if err != nil {
log.Fatal().Err(err).Msg("failed to load tailwind.css")
return
}
style := string(styleb)
tailwindDebugStuff = template.HTML(fmt.Sprintf("<script src=\"https://cdn.tailwindcss.com?plugins=typography\"></script><script>\n%s</script><style type=\"text/tailwindcss\">%s</style>", config, style))
}
// initialize disk cache
defer cache.initialize()()

View File

@@ -28,12 +28,11 @@ var (
//tmpl:bind head_common.html
type HeadCommonPartial struct {
IsProfile bool
IsProfile bool
TailwindDebugStuff template.HTML
}
func (*HeadCommonPartial) TemplateText() string {
return tmplHeadCommon
}
func (*HeadCommonPartial) TemplateText() string { return tmplHeadCommon }
var (
//go:embed templates/top.html
@@ -44,9 +43,7 @@ var (
//tmpl:bind top.html
type TopPartial struct{}
func (*TopPartial) TemplateText() string {
return tmplTop
}
func (*TopPartial) TemplateText() string { return tmplTop }
var (
//go:embed templates/details.html
@@ -68,9 +65,7 @@ type DetailsPartial struct {
KindDescription string
}
func (*DetailsPartial) TemplateText() string {
return tmplDetails
}
func (*DetailsPartial) TemplateText() string { return tmplDetails }
var (
//go:embed templates/clients.html
@@ -83,9 +78,7 @@ type ClientsPartial struct {
Clients []ClientReference
}
func (*ClientsPartial) TemplateText() string {
return tmplClients
}
func (*ClientsPartial) TemplateText() string { return tmplClients }
var (
//go:embed templates/footer.html
@@ -96,9 +89,7 @@ var (
//tmpl:bind footer.html
type FooterPartial struct{}
func (*FooterPartial) TemplateText() string {
return tmplFooter
}
func (*FooterPartial) TemplateText() string { return tmplFooter }
var (
//go:embed templates/telegram_instant_view.html
@@ -119,9 +110,7 @@ type TelegramInstantViewPage struct {
CreatedAt string
}
func (*TelegramInstantViewPage) TemplateText() string {
return tmplTelegramInstantView
}
func (*TelegramInstantViewPage) TemplateText() string { return tmplTelegramInstantView }
var (
//go:embed templates/homepage.html
@@ -139,9 +128,7 @@ type HomePage struct {
LastNotes []string
}
func (*HomePage) TemplateText() string {
return tmplHomePage
}
func (*HomePage) TemplateText() string { return tmplHomePage }
var (
//go:embed templates/archive.html
@@ -163,9 +150,7 @@ type ArchivePage struct {
PrevPage int
}
func (*ArchivePage) TemplateText() string {
return tmplArchive
}
func (*ArchivePage) TemplateText() string { return tmplArchive }
var (
//go:embed templates/other.html
@@ -185,9 +170,7 @@ type OtherPage struct {
KindDescription string
}
func (*OtherPage) TemplateText() string {
return tmplOther
}
func (*OtherPage) TemplateText() string { return tmplOther }
var (
//go:embed templates/note.html
@@ -225,9 +208,7 @@ type NotePage struct {
VideoType string
}
func (*NotePage) TemplateText() string {
return tmplNote
}
func (*NotePage) TemplateText() string { return tmplNote }
var (
//go:embed templates/profile.html
@@ -258,9 +239,7 @@ type ProfilePage struct {
Title string
}
func (*ProfilePage) TemplateText() string {
return tmplProfile
}
func (*ProfilePage) TemplateText() string { return tmplProfile }
var (
//go:embed templates/relay.html
@@ -281,9 +260,7 @@ type RelayPage struct {
ModifiedAt string
}
func (*RelayPage) TemplateText() string {
return tmplRelay
}
func (*RelayPage) TemplateText() string { return tmplRelay }
var (
//go:embed templates/sitemap.xml
@@ -309,6 +286,4 @@ type SitemapPage struct {
Data []string
}
func (*SitemapPage) TemplateText() string {
return tmplSitemap
}
func (*SitemapPage) TemplateText() string { return tmplSitemap }

View File

@@ -85,7 +85,7 @@ func renderArchive(w http.ResponseWriter, r *http.Request) {
if !isSitemap {
ArchiveTemplate.Render(w, &ArchivePage{
HeadCommonPartial: HeadCommonPartial{IsProfile: false},
HeadCommonPartial: HeadCommonPartial{IsProfile: false, TailwindDebugStuff: tailwindDebugStuff},
Title: title,
PathPrefix: pathPrefix,

View File

@@ -239,7 +239,7 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
})
case Note:
err = NoteTemplate.Render(w, &NotePage{
HeadCommonPartial: HeadCommonPartial{IsProfile: false},
HeadCommonPartial: HeadCommonPartial{IsProfile: false, TailwindDebugStuff: tailwindDebugStuff},
DetailsPartial: detailsData,
ClientsPartial: ClientsPartial{
Clients: generateClientList(code, data.event),
@@ -268,7 +268,7 @@ func renderEvent(w http.ResponseWriter, r *http.Request) {
})
case Other:
err = OtherTemplate.Render(w, &OtherPage{
HeadCommonPartial: HeadCommonPartial{IsProfile: false},
HeadCommonPartial: HeadCommonPartial{IsProfile: false, TailwindDebugStuff: tailwindDebugStuff},
DetailsPartial: detailsData,
IsParameterizedReplaceable: data.event.Kind >= 30000 && data.event.Kind < 40000,
Naddr: data.naddr,

View File

@@ -7,7 +7,7 @@ import (
func renderHomepage(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Cache-Control", "max-age=3600")
err := HomePageTemplate.Render(w, &HomePage{
HeadCommonPartial: HeadCommonPartial{IsProfile: false},
HeadCommonPartial: HeadCommonPartial{IsProfile: false, TailwindDebugStuff: tailwindDebugStuff},
Host: s.Domain,
})
if err != nil {

View File

@@ -31,7 +31,7 @@ func renderProfile(w http.ResponseWriter, r *http.Request, code string) {
if !isSitemap {
err = ProfileTemplate.Render(w, &ProfilePage{
HeadCommonPartial: HeadCommonPartial{IsProfile: true},
HeadCommonPartial: HeadCommonPartial{IsProfile: true, TailwindDebugStuff: tailwindDebugStuff},
DetailsPartial: DetailsPartial{
HideDetails: true,
CreatedAt: data.createdAt,

View File

@@ -64,7 +64,7 @@ func renderRelayPage(w http.ResponseWriter, r *http.Request) {
if !isSitemap {
RelayTemplate.Render(w, &RelayPage{
HeadCommonPartial: HeadCommonPartial{IsProfile: false},
HeadCommonPartial: HeadCommonPartial{IsProfile: false, TailwindDebugStuff: tailwindDebugStuff},
ClientsPartial: ClientsPartial{
Clients: generateRelayBrowserClientList(hostname),
},

28
tailwind.config.js Normal file
View File

@@ -0,0 +1,28 @@
module.exports = {
content: ['./templates/*.html', './*.go'],
darkMode: ['class', '.theme--dark'],
theme: {
extend: {
fontFamily: {
sans: ['Helvetica', 'ui-sans-serif', 'system-ui']
},
colors: {
lavender: '#fdf0f5',
strongpink: '#e32a6d',
crimson: '#bc1150',
garnet: '#42091e'
},
typography: ({theme}) => ({
/* for markdown html content */
DEFAULT: {
css: {
'--tw-prose-headings': theme('colors.strongpink'),
'--tw-prose-invert-headings': theme('colors.strongpink'),
'--tw-prose-links': theme('colors.gray[700]'),
'--tw-prose-invert-links': theme('colors.neutral[50]')
}
}
})
}
}
}

18
tailwind.css Normal file
View File

@@ -0,0 +1,18 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer utilities {
.imgclip {
clip-path: url(#svg-shape);
}
.gradient {
mask-image: linear-gradient(
to bottom,
rgb(0, 0, 0) 50%,
rgba(0, 0, 0, 0) 100%
);
}
.safari {
margin: 1cm 3cm;
}
}

View File

@@ -4,7 +4,7 @@
<head>
<title>{{.Title}}</title>
{{template "head_common" .}}
{{template "head_common" .HeadCommonPartial}}
</head>
<body class="mb-16 print:text-black text-gray-600 dark:text-neutral-50 bg-white dark:bg-neutral-800">

View File

@@ -62,7 +62,7 @@
on click increment localStorage['nj:{{.ID}}']"
>
<a
class="block sm:inline basis-full text-left sm:text-center text-sm text-white bg-zinc-700 no-underline px-3 py-2 sm:py-2.5 sm:rounded-lg hover:bg-gray-700"
class="block sm:inline basis-full text-left sm:text-center text-sm text-white bg-zinc-700 no-underline px-3 py-2 sm:py-1.5 sm:rounded-lg hover:bg-gray-700"
href="{{.URL}}"
>
<span class="inline text-white hidden basis-1/5 ml-1.5">Open in</span>

View File

@@ -39,53 +39,13 @@
{{end}}
<meta name="theme-color" content="#e42a6d" />
<script src="https://unpkg.com/hyperscript.org@0.9.12"></script>
<script src="https://cdn.tailwindcss.com?plugins=typography"></script>
<script>
tailwind.config = {
darkMode: ['class', '.theme--dark'],
theme: {
extend: {
fontFamily: {
sans: ['Helvetica', 'ui-sans-serif', 'system-ui']
},
colors: {
lavender: '#fdf0f5',
strongpink: '#e32a6d',
crimson: '#bc1150',
garnet: '#42091e'
},
typography: ({theme}) => ({
/* for markdown html content */
DEFAULT: {
css: {
'--tw-prose-headings': theme('colors.strongpink'),
'--tw-prose-invert-headings': theme('colors.strongpink'),
'--tw-prose-links': theme('colors.gray[700]'),
'--tw-prose-invert-links': theme('colors.neutral[50]')
}
}
})
}
}
}
</script>
<style type="text/tailwindcss">
@layer utilities {
.imgclip {
clip-path: url(#svg-shape);
}
.gradient {
mask-image: linear-gradient(
to bottom,
rgb(0, 0, 0) 50%,
rgba(0, 0, 0, 0) 100%
);
}
.safari {
margin: 1cm 3cm;
}
}
</style>
{{ if not (eq "" .TailwindDebugStuff) }} {{ .TailwindDebugStuff }} {{ else }}
<link
rel="stylesheet"
type="text/css"
href="/njump/static/tailwind-bundle.min.css"
/>
{{ end }}
<style>
@media print {
@page {

View File

@@ -5,22 +5,24 @@
<title>njump - the nostr static gateway</title>
<meta name="description" content="" />
{{template "head_common" .}}
{{template "head_common" .HeadCommonPartial}}
</head>
<body class="homepage">
<body
class="mb-16 print:text-black text-gray-600 dark:text-neutral-50 bg-white dark:bg-neutral-800 text-xl"
>
{{template "top" .}}
<div
class="block sm:flex sm:justify-center sm:items-center mx-auto px-4 sm:px-0"
>
<div
class="flex w-full sm:w-9/12 px-4 justify-between overflow-visible gap-10 lg:gap-20 print:w-full"
class="flex w-full sm:w-2/3 px-4 justify-between overflow-visible gap-10 lg:gap-20 print:w-full"
>
<div>
<h2 class="text-strongpink text-2xl">What is njump?</h2>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
<i>njump</i> is a HTTP
<a class="underline" href="https://github.com/nostr-protocol/nostr"
>Nostr</a
@@ -31,7 +33,7 @@
resource outside the Nostr world, where the
<code>nostr:</code> schema is not (yet) working.
</p>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
<i>njump</i> currently lives under {{ .Host }}, you can reach it
appending a Nostr
<a
@@ -45,7 +47,7 @@
>{{ .Host }}/&lt;nip-19-entity&gt;</span
>.
</p>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
For example, here's
<a
href="/npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6"
@@ -99,13 +101,13 @@
</div>
</div>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
There are several reasons to choose <i>njump</i> when sharing Nostr
content outside of Nostr:
</p>
<h2 class="text-strongpink text-2xl">Clean, fast and solid</h2>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
Pages by <i>njump</i> are extremely lightweight and fast to load
because there isn't any client side javascript involved; they are
minimalistic with the right attention to typography, focusing the
@@ -116,12 +118,12 @@
</p>
<h2 class="text-strongpink text-2xl">Good preview</h2>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
<i>njump</i> renders everything on the server-side, so it is able to
generate useful rich previews that work on Telegram, Discord,
Twitter and other places.
</p>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
When opening the URL directly in a browser, visitors will find
referenced content like images, video and links to referenced Nostr
events displayed in a simple but effective way. It shows the note
@@ -130,14 +132,14 @@
</p>
<h2 class="text-strongpink text-2xl">Cooperative (jump-out)</h2>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
<i>njump</i> is not interested capturing users at all, on the
contrary it invites them to "jump" to the Nostr resource by picking
from a list of web clients or with a <code>nostr:</code> for native
clients. It even remembers the most used one for each visitor and
puts it on the top for fast clicking or tap.
</p>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
<a
class="underline"
href="https://github.com/nostr-protocol/nips/blob/master/89.md"
@@ -147,7 +149,7 @@
</p>
<h2 class="text-strongpink text-2xl">Search friendly (jump-in)</h2>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
This is crucial: <i>njump</i> pages are static so search engines can
index them, this means that <i>njump</i> can help others to discover
great content on Nostr, jump in and join us! <i>njump</i> is the
@@ -157,7 +159,7 @@
</p>
<h2 class="text-strongpink text-2xl">Share NIP-05 profiles</h2>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
Now you can share your own profile with a pretty
<a
class="underline"
@@ -174,7 +176,7 @@
>https://{{ .Host }}/mike@mikedilger.com</a
>.
</p>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
A profile shows the basic metadata infos, the used "outbox" relays
and the last notes.
</p>
@@ -182,7 +184,7 @@
<h2 class="text-strongpink text-2xl">
Share on Twitter and Telegram
</h2>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
Now you can quickly and effortlessly share Nostr notes on Twitter
and Telegram, and maybe on many other "social platforms": just drop
a link, and njump will render the note text using the preview image
@@ -192,7 +194,7 @@
</p>
<h2 class="text-strongpink text-2xl">Relays view</h2>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
You can have a view of the last content posted to a relay using
<span class="rounded px-1 bg-lavender dark:bg-garnet"
>{{ .Host }}/r/&lt;relay-host&gt;</span
@@ -201,7 +203,7 @@
>https://{{ .Host }}/r/nostr.wine</a
>
</p>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
Some basic infos (<a
href="https://github.com/nostr-protocol/nips/blob/master/11.md"
>NIP-11</a
@@ -211,7 +213,7 @@
</p>
<h2 class="text-strongpink text-2xl">Inspector tool</h2>
<p class="leading-5 my-3">
<p class="leading-6 my-3">
You know, we are all programmers, including our moms, so for every
<i>njump</i> page you can toggle the "Show more details" switch and
inspect the full event JSON. Without installing other tools (like

View File

@@ -49,7 +49,7 @@
{{ end }}
<!---->
{{template "head_common" .}}
{{template "head_common" .HeadCommonPartial}}
</head>
<body

View File

@@ -9,7 +9,7 @@
{{ end }}
<!---->
{{template "head_common" .}}
{{template "head_common" .HeadCommonPartial}}
</head>
<body

View File

@@ -25,7 +25,7 @@
href="/{{.Npub}}.Xml"
/>
{{template "head_common" .}}
{{template "head_common" .HeadCommonPartial}}
</head>
<body
@@ -108,11 +108,11 @@
{{ if not (eq 0 (len .AuthorRelays)) }}
<div class="leading-5 mb-6">
<div class="text-sm text-strongpink">Posting on these relays</div>
<div class="text-sm text-strongpink">Publishing to</div>
{{range $index, $element := .AuthorRelays}}
<a
href="/r/{{$element}}"
class="inline-block max-w-full border mr-1 mt-2.5 px-2 py-0.5 rounded-lg border-slate-300 hover:text-white hover:bg-strongpink hover:border hover:border-solid hover:border-strongpink"
class="inline-block text-sm max-w-full border mr-1 mt-2 px-2 py-0.5 rounded-lg border-slate-300 hover:text-white hover:bg-strongpink hover:border hover:border-solid hover:border-strongpink"
>{{$element}}</a
>
{{end}}

View File

@@ -22,7 +22,7 @@
href="/r/{{.Hostname}}.xml"
/>
{{template "head_common" .}}
{{template "head_common" .HeadCommonPartial}}
</head>
<body