From 7073a2d3f228ec3590f9a150860a280a64713bc2 Mon Sep 17 00:00:00 2001
From: Leon Mika
Date: Fri, 26 Sep 2025 08:13:29 +1000
Subject: [PATCH] Added clocks tool
---
.idea/.gitignore | 8 +
.idea/modules.xml | 8 +
.idea/vcs.xml | 6 +
.idea/webtools.iml | 9 +
Makefile | 23 +
cmds/clocks/elems.go | 13 +
cmds/clocks/main.go | 87 +++
cmds/clocks/models.go | 18 +
go.mod | 3 +
site/clocks/index.html | 54 ++
site/clocks/main.js | 8 +
site/clocks/style.css | 13 +
.../freelens-logo}/index.html | 3 +-
.../freelens-logo}/script.js | 0
index.html => site/index.html | 3 +-
target/clocks/index.html | 54 ++
target/clocks/main.js | 8 +
target/clocks/style.css | 13 +
target/freelens-logo/index.html | 53 ++
target/freelens-logo/script.js | 78 +++
target/index.html | 27 +
target/wasm/clocks.wasm | Bin 0 -> 3045523 bytes
target/wasm/wasm_exec.js | 575 ++++++++++++++++++
23 files changed, 1061 insertions(+), 3 deletions(-)
create mode 100644 .idea/.gitignore
create mode 100644 .idea/modules.xml
create mode 100644 .idea/vcs.xml
create mode 100644 .idea/webtools.iml
create mode 100644 Makefile
create mode 100644 cmds/clocks/elems.go
create mode 100644 cmds/clocks/main.go
create mode 100644 cmds/clocks/models.go
create mode 100644 go.mod
create mode 100644 site/clocks/index.html
create mode 100644 site/clocks/main.js
create mode 100644 site/clocks/style.css
rename {freelens-logo => site/freelens-logo}/index.html (96%)
rename {freelens-logo => site/freelens-logo}/script.js (100%)
rename index.html => site/index.html (81%)
create mode 100644 target/clocks/index.html
create mode 100644 target/clocks/main.js
create mode 100644 target/clocks/style.css
create mode 100644 target/freelens-logo/index.html
create mode 100644 target/freelens-logo/script.js
create mode 100644 target/index.html
create mode 100755 target/wasm/clocks.wasm
create mode 100644 target/wasm/wasm_exec.js
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..c92d2ee
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/webtools.iml b/.idea/webtools.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/webtools.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..3b92b15
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,23 @@
+GOROOT := $(shell go env | grep GOROOT | sed -e "s/GOROOT=//g" | sed -e "s/[']//g")
+
+.Phony: build
+build: clean build.wasm build.site
+
+.Phony: clean
+clean:
+ -rm -r target
+ mkdir target
+
+.Phony: build.wasm
+build.wasm:
+ mkdir target/wasm
+ GOOS=js GOARCH=wasm go build -o target/wasm/clocks.wasm ./cmds/clocks
+ cp $(GOROOT)/lib/wasm/wasm_exec.js target/wasm/.
+
+.Phony: build.site
+build.site:
+ cp -r site/* target/.
+
+.Phony: dev
+dev: build
+ ( cd target ; python3 -m http.server )
\ No newline at end of file
diff --git a/cmds/clocks/elems.go b/cmds/clocks/elems.go
new file mode 100644
index 0000000..6bbfa1b
--- /dev/null
+++ b/cmds/clocks/elems.go
@@ -0,0 +1,13 @@
+package main
+
+import "syscall/js"
+
+func findClockElements(id string) htmlElements {
+ doc := js.Global().Get("document")
+ rootClockElem := doc.Call("querySelector", "#"+id)
+ return htmlElements{
+ locationDiv: rootClockElem.Call("querySelector", ".location"),
+ timeDiv: rootClockElem.Call("querySelector", ".time"),
+ dateDiv: rootClockElem.Call("querySelector", ".date"),
+ }
+}
diff --git a/cmds/clocks/main.go b/cmds/clocks/main.go
new file mode 100644
index 0000000..cb48fd4
--- /dev/null
+++ b/cmds/clocks/main.go
@@ -0,0 +1,87 @@
+//go:build js
+
+package main
+
+import (
+ "log"
+ "time"
+
+ _ "time/tzdata"
+)
+
+func main() {
+ melTime, err := time.LoadLocation("Australia/Melbourne")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ sg, err := time.LoadLocation("Asia/Singapore")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ nyc, err := time.LoadLocation("America/New_York")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ la, err := time.LoadLocation("America/Los_Angeles")
+ if err != nil {
+ log.Fatal(err)
+ }
+
+ utc := time.UTC
+
+ clocks := []clock{
+ {
+ name: "UTC",
+ loc: utc,
+ elements: findClockElements("utc"),
+ },
+ {
+ name: "Australia/Melbourne",
+ loc: melTime,
+ elements: findClockElements("mel"),
+ },
+ {
+ name: "Asia/Singapore",
+ loc: sg,
+ elements: findClockElements("sg"),
+ },
+ {
+ name: "America/New_York",
+ loc: nyc,
+ elements: findClockElements("nyc"),
+ },
+ {
+ name: "America/Los_Angeles",
+ loc: la,
+ elements: findClockElements("la"),
+ },
+ }
+
+ updateClocks(clocks)
+ go startClockUpdater(clocks)
+
+ <-make(chan struct{})
+}
+
+func startClockUpdater(clocks []clock) {
+ for range time.Tick(1 * time.Second) {
+ updateClocks(clocks)
+ }
+}
+
+func updateClocks(clocks []clock) {
+ n := time.Now()
+ for _, c := range clocks {
+ updateClock(n, c)
+ }
+}
+
+func updateClock(t time.Time, clk clock) {
+ lt := t.In(clk.loc)
+ clk.elements.locationDiv.Set("innerText", clk.name)
+ clk.elements.dateDiv.Set("innerText", lt.Format("02 Jan 2006"))
+ clk.elements.timeDiv.Set("innerText", lt.Format("15:04:05"))
+}
diff --git a/cmds/clocks/models.go b/cmds/clocks/models.go
new file mode 100644
index 0000000..91eab7b
--- /dev/null
+++ b/cmds/clocks/models.go
@@ -0,0 +1,18 @@
+package main
+
+import (
+ "syscall/js"
+ "time"
+)
+
+type clock struct {
+ name string
+ loc *time.Location
+ elements htmlElements
+}
+
+type htmlElements struct {
+ locationDiv js.Value
+ timeDiv js.Value
+ dateDiv js.Value
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..71cbe1b
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,3 @@
+module github.com/lmika/webtools
+
+go 1.24.3
diff --git a/site/clocks/index.html b/site/clocks/index.html
new file mode 100644
index 0000000..9654fd2
--- /dev/null
+++ b/site/clocks/index.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+ Clocks - Tools
+
+
+
+
+
+
+ Clocks
+ Various time zones
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/site/clocks/main.js b/site/clocks/main.js
new file mode 100644
index 0000000..ba74c81
--- /dev/null
+++ b/site/clocks/main.js
@@ -0,0 +1,8 @@
+import "/wasm/wasm_exec.js";
+
+const go = new Go();
+
+WebAssembly.instantiateStreaming(fetch("/wasm/clocks.wasm"), go.importObject)
+ .then((result) => {
+ go.run(result.instance);
+ });
\ No newline at end of file
diff --git a/site/clocks/style.css b/site/clocks/style.css
new file mode 100644
index 0000000..023a284
--- /dev/null
+++ b/site/clocks/style.css
@@ -0,0 +1,13 @@
+div.clock {
+ text-align: center;
+ margin-block-end: 1.8rem;
+}
+
+div.clock div.location {
+ color: rgb(175, 41, 29);
+}
+
+div.clock div.time {
+ font-size: 200%;
+ font-family: var(--pico-font-family-monospace);
+}
\ No newline at end of file
diff --git a/freelens-logo/index.html b/site/freelens-logo/index.html
similarity index 96%
rename from freelens-logo/index.html
rename to site/freelens-logo/index.html
index 30dc187..9c9f52b 100644
--- a/freelens-logo/index.html
+++ b/site/freelens-logo/index.html
@@ -4,8 +4,7 @@
- Freelens Logo
- Tools
+ Freelens Logo Creator - Tools
+
+
+ Clocks
+ Various time zones
+
+
+
+
+
+
+
+
diff --git a/target/clocks/index.html b/target/clocks/index.html
new file mode 100644
index 0000000..9654fd2
--- /dev/null
+++ b/target/clocks/index.html
@@ -0,0 +1,54 @@
+
+
+