From 8be575875d85b4bf469fdda24b11ec1891338158 Mon Sep 17 00:00:00 2001 From: Ben Visness Date: Tue, 6 Jun 2023 13:23:54 -0500 Subject: [PATCH] Add time machine submissions page --- src/hmnurl/hmnurl_test.go | 25 ++ src/hmnurl/urls.go | 7 + .../src/include/timemachine_submission.html | 30 ++ .../src/layouts/timemachine_base.html | 332 +++++++++--------- src/templates/src/timemachine.html | 69 +--- .../src/timemachine_submissions.html | 36 ++ src/website/routes.go | 1 + src/website/time_machine.go | 104 +++++- 8 files changed, 382 insertions(+), 222 deletions(-) create mode 100644 src/templates/src/include/timemachine_submission.html create mode 100644 src/templates/src/timemachine_submissions.html diff --git a/src/hmnurl/hmnurl_test.go b/src/hmnurl/hmnurl_test.go index 3a43c81..e71f657 100644 --- a/src/hmnurl/hmnurl_test.go +++ b/src/hmnurl/hmnurl_test.go @@ -415,6 +415,31 @@ func TestJamRecap2023_Visibility(t *testing.T) { AssertSubdomain(t, BuildJamRecap2023_Visibility(), "") } +func TestTimeMachine(t *testing.T) { + AssertRegexMatch(t, BuildTimeMachine(), RegexTimeMachine, nil) + AssertSubdomain(t, BuildTimeMachine(), "") +} + +func TestTimeMachineSubmissions(t *testing.T) { + AssertRegexMatch(t, BuildTimeMachineSubmissions(), RegexTimeMachineSubmissions, nil) + AssertSubdomain(t, BuildTimeMachineSubmissions(), "") +} + +func TestTimeMachineForm(t *testing.T) { + AssertRegexMatch(t, BuildTimeMachineForm(), RegexTimeMachineForm, nil) + AssertSubdomain(t, BuildTimeMachineForm(), "") +} + +func TestTimeMachineFormDone(t *testing.T) { + AssertRegexMatch(t, BuildTimeMachineFormDone(), RegexTimeMachineFormDone, nil) + AssertSubdomain(t, BuildTimeMachineFormDone(), "") +} + +func TestNewsletterSignup(t *testing.T) { + AssertRegexMatch(t, BuildNewsletterSignup(), RegexNewsletterSignup, nil) + AssertSubdomain(t, BuildNewsletterSignup(), "") +} + func TestProjectNewJam(t *testing.T) { AssertRegexMatch(t, BuildProjectNewJam(), RegexProjectNew, nil) AssertSubdomain(t, BuildProjectNewJam(), "") diff --git a/src/hmnurl/urls.go b/src/hmnurl/urls.go index 17071c6..6d0eab0 100644 --- a/src/hmnurl/urls.go +++ b/src/hmnurl/urls.go @@ -119,6 +119,13 @@ func BuildTimeMachine() string { return Url("/timemachine", nil) } +var RegexTimeMachineSubmissions = regexp.MustCompile("^/timemachine/submissions$") + +func BuildTimeMachineSubmissions() string { + defer CatchPanic() + return Url("/timemachine/submissions", nil) +} + var RegexTimeMachineForm = regexp.MustCompile("^/timemachine/submit$") func BuildTimeMachineForm() string { diff --git a/src/templates/src/include/timemachine_submission.html b/src/templates/src/include/timemachine_submission.html new file mode 100644 index 0000000..9d81c50 --- /dev/null +++ b/src/templates/src/include/timemachine_submission.html @@ -0,0 +1,30 @@ +
+ {{ template "frame title" .Title }} +
+
+
+
+ Video Thumbnail + +
+ Play Video +
+
+
+
+ {{ range .Details }} +
{{ .Name }}: {{ .Content }}
+ {{ end }} + +
+
+
+ {{ .Description }} +
+
+
+
diff --git a/src/templates/src/layouts/timemachine_base.html b/src/templates/src/layouts/timemachine_base.html index 54daaf6..97e2f2e 100644 --- a/src/templates/src/layouts/timemachine_base.html +++ b/src/templates/src/layouts/timemachine_base.html @@ -5,195 +5,213 @@ - - + + - - + + - {{ if .CanonicalLink }}{{ end }} - {{ range .OpenGraphItems }} - {{ if .Property }} - - {{ else }} - - {{ end }} - {{ end }} - {{ if .Title }} - {{ .Title }} | Handmade Network + {{ if .CanonicalLink }}{{ end }} + {{ range .OpenGraphItems }} + {{ if .Property }} + {{ else }} - Handmade Network + {{ end }} - + {{ end }} + {{ if .Title }} + {{ .Title }} | Handmade Network + {{ else }} + Handmade Network + {{ end }} + - + - - - - + + + + - + .win95-input { + border-width: 2px; + border-style: solid; + border-image: url('{{ dataimg "timemachine/win95-border-input.gif" }}') 4; + outline: none; + background-color: white !important; + resize: vertical; /* only applies to textareas so whatever */ + } + .less-spacing p { + margin: 0.2rem 0; + } + -
-
- {{ template "header.html" . }} -
- -
- {{ block "content" . }}{{ end }} -
- -
- {{ template "footer.html" . }} -
+
+
+ {{ template "header.html" . }}
+ +
+
+ {{ with .Breadcrumbs }} +
+ {{ range $i, $e := . -}} + {{- if gt $i 0 -}} + » + {{- end -}} + {{ .Name }} + {{- end }} +
+ {{ end }} +
+ {{ block "content" . }}{{ end }} + +
+ {{ template "footer.html" . }} +
+
+
+ +{{ define "frame title" }} +
+ {{ . }} + +
+{{ end }} diff --git a/src/templates/src/timemachine.html b/src/templates/src/timemachine.html index 34b8962..d128a1c 100644 --- a/src/templates/src/timemachine.html +++ b/src/templates/src/timemachine.html @@ -1,12 +1,5 @@ {{ template "timemachine_base.html" . }} -{{ define "frame title" }} -
- {{ . }} - -
-{{ end }} - {{ define "content" }}
@@ -77,7 +70,7 @@
- Submit your own + Submit Your Own
@@ -92,66 +85,22 @@
- 1 video has been submitted! Would you like to see it? + {{ if eq .NumSubmissions 1 }} + {{ .NumSubmissions }} video has been submitted! Would you like to see it? + {{ else }} + {{ .NumSubmissions }} videos have been submitted! Would you like to see them? + {{ end }}
-
Yes
+
Yes
-
- {{ template "frame title" "2009 iPod Touch" }} -
-
-
-
- Video Thumbnail - -
- Play Video -
-
-
-
-
Device: iPod Touch 3rd gen, model MC008LL
-
Submitted by: Ben Visness
-
Release year: 2009
-
Processor: 600MHz Samsung S5L8922, single-core
-
Memory: 256MB LPDDR2 @ 200 MHz
-
Operating system: iOS 5
-
-
-
-

- This is the iPod Touch I got when I was 13. It was my first major - tech purchase and an early device in the iOS lineup. When I - purchased this I think it was running iOS 3; at this point it has - iOS 5. I was pleased to see that the battery still holds a charge - quite well, and it consistently runs at about 30 to 60 frames per - second. -

-

- In the video you can see several built-in apps. Media playback - still works great, and scrubbing around in songs is instantaneous. - App switching works well. The calculator launches instantly (as - you would hope). I was shocked to see that the old Google Maps app - still works - apparently they have kept their old tile-based map - servers online. It even gave me public transit directions. -

-

- Overall, I would say this device feels only a hair slower than my - current iPhone. -

-
-
-
+
+ {{ template "timemachine_submission.html" .FeaturedSubmission }}
diff --git a/src/templates/src/timemachine_submissions.html b/src/templates/src/timemachine_submissions.html new file mode 100644 index 0000000..041ab62 --- /dev/null +++ b/src/templates/src/timemachine_submissions.html @@ -0,0 +1,36 @@ +{{ template "timemachine_base.html" . }} + +{{ define "content" }} +
+
+
+
+ {{ template "frame title" "About This Page" }} +
+
+ +
+
+
+ The community has submitted the following + {{ with len .Submissions }} + {{ if eq . 1 }}video{{ else }}{{ . }} videos{{ end }} + {{ end }} + to the Time Machine project. If you have access to any older devices, you can participate too! +
+ +
+
+
+
+ +
+ {{ range .Submissions }} + {{ template "timemachine_submission.html" . }} + {{ end }} +
+
+
+{{ end }} diff --git a/src/website/routes.go b/src/website/routes.go index ee00a4f..966d4f2 100644 --- a/src/website/routes.go +++ b/src/website/routes.go @@ -71,6 +71,7 @@ func NewWebsiteRoutes(conn *pgxpool.Pool) http.Handler { hmnOnly.GET(hmnurl.RegexJamRecap2023_Visibility, JamRecap2023_Visibility) hmnOnly.GET(hmnurl.RegexTimeMachine, TimeMachine) + hmnOnly.GET(hmnurl.RegexTimeMachineSubmissions, TimeMachineSubmissions) hmnOnly.GET(hmnurl.RegexTimeMachineForm, needsAuth(TimeMachineForm)) hmnOnly.GET(hmnurl.RegexTimeMachineFormDone, needsAuth(TimeMachineFormDone)) hmnOnly.POST(hmnurl.RegexTimeMachineForm, needsAuth(csrfMiddleware(TimeMachineFormSubmit))) diff --git a/src/website/time_machine.go b/src/website/time_machine.go index f8031f0..74fa354 100644 --- a/src/website/time_machine.go +++ b/src/website/time_machine.go @@ -1,6 +1,7 @@ package website import ( + "html/template" "net/http" "strings" @@ -11,7 +12,46 @@ import ( ) func TimeMachine(c *RequestContext) ResponseData { - baseData := getBaseDataAutocrumb(c, "Time Machine") + baseData := getBaseData(c, "Time Machine", nil) + baseData.OpenGraphItems = []templates.OpenGraphItem{ + {Property: "og:title", Value: "Time Machine"}, + {Property: "og:site_name", Value: "Handmade Network"}, + {Property: "og:type", Value: "website"}, + {Property: "og:image", Value: hmnurl.BuildPublic("timemachine/opengraph.png", true)}, + {Property: "og:description", Value: "This summer, dig out your old devices and see what they were actually like to use."}, + {Property: "og:url", Value: hmnurl.BuildTimeMachine()}, + {Name: "twitter:card", Value: "summary_large_image"}, + {Name: "twitter:image", Value: hmnurl.BuildPublic("timemachine/twittercard.png", true)}, + } + + featured := tmSubmissions[0] + featured.Title = "Latest Submission" + + type TemplateData struct { + templates.BaseData + SubmitUrl string + SubmissionsUrl string + NumSubmissions int + FeaturedSubmission TimeMachineSubmission + } + tmpl := TemplateData{ + BaseData: baseData, + SubmitUrl: hmnurl.BuildTimeMachineForm(), + SubmissionsUrl: hmnurl.BuildTimeMachineSubmissions(), + NumSubmissions: len(tmSubmissions), + FeaturedSubmission: featured, + } + + var res ResponseData + res.MustWriteTemplate("timemachine.html", tmpl, c.Perf) + return res +} + +func TimeMachineSubmissions(c *RequestContext) ResponseData { + baseData := getBaseData(c, "Time Machine - Submissions", []templates.Breadcrumb{ + {"Time Machine", hmnurl.BuildTimeMachine()}, + {"Submissions", hmnurl.BuildTimeMachineSubmissions()}, + }) baseData.OpenGraphItems = []templates.OpenGraphItem{ {Property: "og:title", Value: "Time Machine"}, {Property: "og:site_name", Value: "Handmade Network"}, @@ -25,15 +65,19 @@ func TimeMachine(c *RequestContext) ResponseData { type TemplateData struct { templates.BaseData - SubmitUrl string + MainUrl string + SubmitUrl string + Submissions []TimeMachineSubmission } tmpl := TemplateData{ - BaseData: baseData, - SubmitUrl: hmnurl.BuildTimeMachineForm(), + BaseData: baseData, + MainUrl: hmnurl.BuildTimeMachine(), + SubmitUrl: hmnurl.BuildTimeMachineForm(), + Submissions: tmSubmissions, } var res ResponseData - res.MustWriteTemplate("timemachine.html", tmpl, c.Perf) + res.MustWriteTemplate("timemachine_submissions.html", tmpl, c.Perf) return res } @@ -94,3 +138,53 @@ func TimeMachineFormDone(c *RequestContext) ResponseData { ) return res } + +type TimeMachineSubmission struct { + Title string + Url string + Thumbnail string + Details []TimeMachineSubmissionDetail + Description template.HTML +} + +type TimeMachineSubmissionDetail struct { + Name string + Content template.HTML +} + +var tmSubmissions = []TimeMachineSubmission{ + { + Title: "2009 iPod Touch", + Url: "https://youtu.be/2eBFk1yV6mE", + Thumbnail: "timemachine/ipodtouch-dither.gif", + Details: []TimeMachineSubmissionDetail{ + {"Device", "iPod Touch 3rd gen, model MC008LL"}, + {"Submitted by", "Ben Visness"}, + {"Release year", "2009"}, + {"Processor", "600MHz Samsung S5L8922, single-core"}, + {"Memory", "256MB LPDDR2 @ 200 MHz"}, + {"Operating system", "iOS 5"}, + }, + Description: ` +

+ This is the iPod Touch I got when I was 13. It was my first major + tech purchase and an early device in the iOS lineup. When I + purchased this I think it was running iOS 3; at this point it has + iOS 5. I was pleased to see that the battery still holds a charge + quite well, and it consistently runs at about 30 to 60 frames per + second. +

+

+ In the video you can see several built-in apps. Media playback + still works great, and scrubbing around in songs is instantaneous. + App switching works well. The calculator launches instantly (as + you would hope). I was shocked to see that the old Google Maps app + still works - apparently they have kept their old tile-based map + servers online. It even gave me public transit directions. +

+

+ Overall, I would say this device feels only a hair slower than my + current iPhone. +

`, + }, +}