Add Videos page [deploy-site]

This commit is contained in:
Ben Croker 2025-04-03 21:43:21 -06:00
parent a723a63a0a
commit a3f00b9033
No known key found for this signature in database
GPG Key ID: 09D799816F1CF332
5 changed files with 100 additions and 1 deletions

View File

@ -133,6 +133,7 @@ func setupRoutes(ctx context.Context, router chi.Router) (err error) {
setupHowTos(ctx, router),
setupExamples(ctx, router, sessionSignals),
setupTests(ctx, router),
setupVideos(router),
setupEssays(ctx, router),
setupErrors(router),
setupMemes(router),

View File

@ -15,7 +15,7 @@ templ PageBundler(r *http.Request, manifest PluginManifest, store *BundlerStore)
@header(r)
<div data-signals={ templ.JSONString(store) } class="p-8 flex flex-col gap-8">
<div>
<div class="text-6xl font-brand font-bold text-center">Bundler</div>
<h1 class="text-6xl font-brand font-bold text-center">Bundler</h1>
<div class="text-center">While Datastar is still one of the smallest frameworks available, you can bundle only the plugins you need to reduce the size even further.</div>
</div>
<div id="results"></div>

66
site/routes_videos.go Normal file
View File

@ -0,0 +1,66 @@
package site
import (
"net/http"
"strconv"
"github.com/go-chi/chi/v5"
datastar "github.com/starfederation/datastar/sdk/go"
)
type Video struct {
Code string
Title string
}
func setupVideos(router chi.Router) error {
videos := []Video{
{Code: "4vb9C_K7zCU", Title: " Delaney exposes Alien Signals—not so extraterrestrial after all"},
{Code: "0K71AyAF6E4", Title: "Real-time Hypermedia - Delaney Gillilan"},
{Code: "OV6xS865pF0", Title: "Immutability & Event Sourcing "},
{Code: "YRzPqPELZdY", Title: "DataStar, Engineering, and Web Apps with Delaney Gillilan"},
{Code: "IrtBBqyDrJU", Title: "Codeiomorph with Micah "},
{Code: "HbTFlUqELVc", Title: "Hypermedia at 144fps!?"},
{Code: "DTURjpV2ZHQ", Title: "Getting to grips with Datastar "},
{Code: "QPRigsY_4E8", Title: "054: Datastar with Delaney Gillilan"},
{Code: "zu92P9wyUfI", Title: "Tuning the engine; Codeiomorph; Pub/Sub; NATS "},
{Code: "a6ByFsFCN0c", Title: "Beta 3; Full-stack framework; CQRS"},
{Code: "hUqFY9TQvdM", Title: "Datastar The progressive performance framework"},
{Code: "p4X02rEPkJY", Title: "What Datastar is Not, with JLarky"},
{Code: "99wTA9sFEWE", Title: "Datastar v1"},
{Code: "J-DzgNA6F-4", Title: "[D*#4] Build a dopamine hell with Datastar!"},
{Code: "1cbqmVkzcJQ", Title: "[D*#3] Build a chess game with Datastar"},
{Code: "t2NC7jGtD60", Title: "[D*#2] Build a Twitch room with Datastar "},
{Code: "vLekrUywdRI", Title: "[D*#1] - Build a game with Python and Datastar!"},
{Code: "UXPD3LblwVA", Title: "I recreated Google's worst product feature using datastar"},
{Code: "aVjU1st-52g", Title: "Intro to Datastar (and Craft CMS)"},
{Code: "FMKdE4QFyNk", Title: "Puffy does Realtime Hypermedia - Patrick Marchand - EuroBSDCon 2024"},
}
router.Route("/videos", func(videosRouter chi.Router) {
videosRouter.Get("/", func(w http.ResponseWriter, r *http.Request) {
PageVideos(r, videos...).Render(r.Context(), w)
})
videosRouter.Get("/data/{index}", func(w http.ResponseWriter, r *http.Request) {
sse := datastar.NewSSE(w, r)
indexStr := chi.URLParam(r, "index")
if indexStr == "" {
http.Error(w, "Missing index", http.StatusBadRequest)
return
}
index, err := strconv.Atoi(indexStr)
if err != nil || index < 0 || index >= len(videos) {
http.Error(w, "Invalid index", http.StatusBadRequest)
return
}
code := videos[index].Code
sse.MergeFragments(`<div id="video-` + indexStr + `" class="w-full max-w-xl aspect-video bg-black"><iframe class="w-full h-full" src="https://www.youtube.com/embed/` + code + `?autoplay=1" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>`)
})
})
return nil
}

29
site/routes_videos.templ Normal file
View File

@ -0,0 +1,29 @@
package site
import "net/http"
import "strconv"
templ PageVideos(r *http.Request, videos ...Video) {
@Page("Videos", "A day without a good video is like a joke without a punchline—pointless.", "/videos") {
@header(r)
<div class="flex flex-col gap-8 p-8">
<div>
<h1 class="text-6xl font-brand font-bold text-center">Videos</h1>
<div class="text-center">Subscribe to our <a href="https://www.youtube.com/@data-star" target="_blank" class="text-primary">YouTube channel</a> and never miss a video update.</div>
</div>
<div class="flex flex-wrap justify-center gap-8">
for key, video := range videos {
{{
id := "video-" + strconv.Itoa(key)
action := "@get('/videos/data/" + strconv.Itoa(key) + "')"
thumbnail := "https://img.youtube.com/vi/" + video.Code + "/maxresdefault.jpg"
title := video.Title
}}
<div id={ id } data-on-click={ action } class="w-full max-w-xl aspect-video cursor-pointer">
<img src={ thumbnail } alt={ title } class="w-full h-full"/>
</div>
}
</div>
</div>
}
}

View File

@ -103,6 +103,9 @@ templ headerTopLevelLinks(r *http.Request) {
@headerTopLevelLink(r, "How Tos")
@headerTopLevelLink(r, "Examples")
@headerDropdownMenu("More") {
<li>
@headerTopLevelLink(r, "Videos")
</li>
<li>
@headerTopLevelLink(r, "Essays")
</li>