diff options
| author | ewy <ewy0@protonmail.com> | 2026-04-09 21:01:59 +0200 |
|---|---|---|
| committer | ewy <ewy0@protonmail.com> | 2026-04-09 21:01:59 +0200 |
| commit | 6e896ae0e108eef385b46c26e770dc191ae936ba (patch) | |
| tree | 3f34ba405833fd08b2b9396ca50d0cb454126b53 | |
| parent | 4b082851542cf8b546e3fbacaf0b27a7db5b80eb (diff) | |
add more css
| -rw-r--r-- | go.mod | 2 | ||||
| -rw-r--r-- | go.sum | 10 | ||||
| -rw-r--r-- | main.go | 2 | ||||
| -rw-r--r-- | pages/create.go | 22 | ||||
| -rw-r--r-- | pages/create.gohtml | 31 | ||||
| -rw-r--r-- | pages/header.gohtml | 12 | ||||
| -rw-r--r-- | pages/landing.go | 7 | ||||
| -rw-r--r-- | pages/landing.gohtml | 46 | ||||
| -rw-r--r-- | pages/local.go | 58 | ||||
| -rw-r--r-- | pages/receive.go | 5 | ||||
| -rw-r--r-- | pages/style.gohtml | 84 | ||||
| -rw-r--r-- | storage/link.go | 1 |
12 files changed, 223 insertions, 57 deletions
@@ -6,4 +6,6 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/mattn/go-sqlite3 v1.14.38 // indirect github.com/spf13/pflag v1.0.10 // indirect + golang.org/x/sys v0.43.0 // indirect + gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect ) @@ -0,0 +1,10 @@ +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/mattn/go-sqlite3 v1.14.38 h1:tDUzL85kMvOrvpCt8P64SbGgVFtJB11GPi2AdmITgb4= +github.com/mattn/go-sqlite3 v1.14.38/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= +golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +gopkg.in/fsnotify/fsnotify.v1 v1.4.7 h1:XNNYLJHt73EyYiCZi6+xjupS9CpvmiDgjPTAjrBlQbo= +gopkg.in/fsnotify/fsnotify.v1 v1.4.7/go.mod h1:Fyux9zXlo4rWoMSIzpn9fDAYjalPqJ/K1qJ27s+7ltE= @@ -22,6 +22,8 @@ var ( func main() { pflag.Parse() + pages.SetupLocal() + http.HandleFunc("GET /{$}", pages.Land) http.HandleFunc("POST /{$}", pages.Create) http.HandleFunc("GET /l/{id}", pages.Get) diff --git a/pages/create.go b/pages/create.go index 03f4159..5469ee8 100644 --- a/pages/create.go +++ b/pages/create.go @@ -58,6 +58,7 @@ func CreateLink(w http.ResponseWriter, r *http.Request) *storage.Link { OpensFrom: time.Now().Add(time.Duration(minutesInFuture) * time.Minute), OpensLeft: numberOfOpens, } + l.OpensStr = l.OpensFrom.Format(time.UnixDate) id, err := l.Save(storage.Current) if err != nil { @@ -69,17 +70,30 @@ func CreateLink(w http.ResponseWriter, r *http.Request) *storage.Link { return &l } -//go:embed create.gohtml -var recContent string -var recTmpl = template.Must(template.New("delayed.link").Parse(recContent)) +var tmpl = template.New("delayed.link") func Create(w http.ResponseWriter, r *http.Request) { l := CreateLink(w, r) if l == nil { return } - err := recTmpl.Execute(w, l) + err := tmpl.ExecuteTemplate(w, "create", l) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } + +//go:embed create.gohtml +var recContent string + +//go:embed style.gohtml +var style string + +//go:embed header.gohtml +var header string + +func init() { + template.Must(tmpl.Parse(style)) + template.Must(tmpl.Parse(header)) + template.Must(tmpl.New("create").Parse(recContent)) +} diff --git a/pages/create.gohtml b/pages/create.gohtml index 5d402cb..d50582a 100644 --- a/pages/create.gohtml +++ b/pages/create.gohtml @@ -7,19 +7,26 @@ <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="icon" href="data:,"/> <title>delayed.link: created</title> + {{ template "style" . }} </head> <body> -<p> - <a href="/l/{{.Id}}">This link will unlock at {{.OpensFrom}}</a> -</p> -<p> - This will occur in approximately {{ .MinutesLeft }} minute{{ if gt .MinutesLeft 1 }}s{{end}}. -</p> -<p> - It will be able to be opened {{ .OpensLeft }} time{{ if gt .OpensLeft 1 }}s{{end}}. -</p> -<p> - This page is completely ephemeral. Once you close it, you cannot access the link again. -</p> +{{ template "header" . }} +<main> + <div> + <a href="/l/{{.Id}}">This link will unlock at {{.OpensStr}}</a> + </div> + <div> + It will occur in approximately {{ .MinutesLeft }} minute{{ if gt .MinutesLeft 1 }}s{{end}}. + </div> + <div> + It can be opened {{ .OpensLeft }} time{{ if gt .OpensLeft 1 }}s{{end}}. + </div> + <div> + Be mindful embedding services might take visits off the counter. + </div> + <div> + This page is completely ephemeral. Once you close it, you cannot access the link again. + </div> +</main> </body> </html>
\ No newline at end of file diff --git a/pages/header.gohtml b/pages/header.gohtml new file mode 100644 index 0000000..5af455e --- /dev/null +++ b/pages/header.gohtml @@ -0,0 +1,12 @@ +{{ define "header" }} + <header> + <a href="/"> + <h1> + delayed.link + </h1> + </a> + <span> + send something now, they unlock it later + </span> + </header> +{{end}}
\ No newline at end of file diff --git a/pages/landing.go b/pages/landing.go index d8c4f54..d2c2fc3 100644 --- a/pages/landing.go +++ b/pages/landing.go @@ -8,12 +8,15 @@ import ( //go:embed landing.gohtml var landContent string -var landTmpl = template.Must(template.New("delayed.link").Parse(landContent)) func Land(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) - err := landTmpl.Execute(w, nil) + err := tmpl.ExecuteTemplate(w, "land", nil) if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) } } + +func init() { + template.Must(tmpl.New("land").Parse(landContent)) +} diff --git a/pages/landing.gohtml b/pages/landing.gohtml index 40f5ae3..021cb95 100644 --- a/pages/landing.gohtml +++ b/pages/landing.gohtml @@ -4,55 +4,34 @@ <meta charset="UTF-8"> <link rel="icon" href="data:,"/> <title>delayed.link</title> - <style> - main { - min-height: 105vh; - } - - label { - display: flex; - justify-content: space-between; - max-width: 500px; - } - - input[type="number"] { - width: 64px; - } - - form { - display: flex; - flex-direction: column; - gap: 4px; - } - </style> + {{ template "style" . }} </head> <body> +{{ template "header" . }} <main> <form method="POST" action="/"> - <div> <label> - Lock time in minutes + <span> + Lock time in minutes + </span> <input type="number" name="minutes_in_future" value="10"/> </label> - </div> - <div> <label> - Maximum times the link can be opened + <span> + Maximum times the link can be opened + </span> <input type="number" name="number_of_opens" min="1" max="100" value="8"/> </label> - </div> - <div> <label> - URL to save for later + <span> + URL to save for later + </span> <input type="text" name="payload"/> </label> - </div> - <div> <label> <span></span> <input type="submit" value="Create"/> </label> - </div> </form> </main> <footer> @@ -60,8 +39,7 @@ WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH THE CUSTOMER. SHOULD - THE SOFTWARE PROVE DEFECTIVE, THE CUSTOMER ASSUMES THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION EXCEPT - TO THE EXTENT SET OUT UNDER THE HARDWARE WARRANTY IN THESE TERMS. + THE SOFTWARE PROVE DEFECTIVE, THE CUSTOMER ASSUMES THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. </footer> </body> </html>
\ No newline at end of file diff --git a/pages/local.go b/pages/local.go new file mode 100644 index 0000000..ccd0f41 --- /dev/null +++ b/pages/local.go @@ -0,0 +1,58 @@ +package pages + +import ( + "fmt" + "github.com/spf13/pflag" + "gopkg.in/fsnotify/fsnotify.v1" + "html/template" + "os" +) + +var Local = pflag.BoolP("local", "l", false, "use local files instead of embedded") + +var Templates = map[string]func(content string){ + "pages/create.gohtml": func(content string) { + template.Must(tmpl.New("create").Parse(content)) + }, + "pages/landing.gohtml": func(content string) { + template.Must(tmpl.New("landing").Parse(content)) + }, + "pages/style.gohtml": func(content string) { + template.Must(tmpl.Parse(content)) + }, +} + +func SetupLocal() { + if *Local { + + watcher, err := fsnotify.NewWatcher() + if err != nil { + panic(err) + } + for page := range Templates { + watcher.Add(page) + } + + go func() { + for { + select { + case ev := <-watcher.Events: + newContent, err := os.ReadFile(ev.Name) + if err != nil { + fmt.Printf("error: %vn", err) + continue + } + Templates[ev.Name](string(newContent)) + if err != nil { + fmt.Printf("error: %vn", err) + } else { + fmt.Printf("updated: %vn", ev.Name) + + } + + } + } + }() + + } +} diff --git a/pages/receive.go b/pages/receive.go deleted file mode 100644 index 023a20b..0000000 --- a/pages/receive.go +++ /dev/null @@ -1,5 +0,0 @@ -package pages - -import ( - _ "embed" -) diff --git a/pages/style.gohtml b/pages/style.gohtml new file mode 100644 index 0000000..bb15fb9 --- /dev/null +++ b/pages/style.gohtml @@ -0,0 +1,84 @@ +{{ define "style"}} +<style> + @media (prefers-color-scheme: dark) { + html { + background-color: #3e3b37; + color: rgb(222, 213, 200); + } + } + + body { + max-width: 44em; + margin: auto; + display: flex; + flex-direction: column; + gap: 32px; + + & p { + padding: 4px 0; + } + } + main { + min-height: 105vh; + display: flex; + gap: 16px; + flex-direction: column; + align-items: center; + } + + label { + display: flex; + justify-content: end; + width: 100%; + gap: 8px; + } + + form { + font-family: system-ui; + display: flex; + flex-direction: column; + gap: 4px; + + width: 100%; + + & input { + background-color: #fefcf8; + color: rgb(30, 27, 25); + border-color: #bad1f9; + border-style: double; + } + + & input[type="number"] { + width: 48px; + } + + & input[type="text"] { + width: 20em; + } + + & input[type="submit"] { + background-color: #bef8d7; + border-color: #395143; + } + } + + header { + display: flex; + align-items: baseline; + gap: 16px; + justify-content: space-between; + + & a { + text-decoration: none; + } + + & h1 { + font-family: monospace + } + } + + a { + color: #f2cae2; + } +</style> +{{end}}
\ No newline at end of file diff --git a/storage/link.go b/storage/link.go index 6f0a0c3..99542f8 100644 --- a/storage/link.go +++ b/storage/link.go @@ -12,6 +12,7 @@ type Link struct { Target string OpensFrom time.Time OpensLeft int + OpensStr string } var Null = uuid.UUID{} |
