Commit Diff


commit - 5dfdd66b09fe47403bcc7678f431f06feba5cbb1
commit + 964b49d98af7652f37f0eb6fe170fdca5d444b35
blob - fe60e21b6bd1a72734687ab0197b479fd2332ae8
blob + 60238e8a438264893569d426e11a67367d81bc03
--- internal/service/handlers.go
+++ internal/service/handlers.go
@@ -2,11 +2,10 @@ package service
 
 import (
 	"html/template"
+	"log"
 	"net/http"
 	"net/url"
 	"strings"
-
-	"github.com/streatCodes/rss/rss"
 )
 
 var templateFuncs = template.FuncMap{
@@ -14,14 +13,17 @@ var templateFuncs = template.FuncMap{
 	"pathEscape": url.PathEscape,
 }
 
-func render(w http.ResponseWriter, name string, data any) {
+func render(w http.ResponseWriter, name string, data any) error {
 	tmpl := template.New("").Funcs(templateFuncs)
 	tmpl = template.Must(tmpl.ParseGlob("internal/templates/*.tmpl"))
-	tmpl.ExecuteTemplate(w, name, data)
+	return tmpl.ExecuteTemplate(w, name, data)
 }
 
 func (service *Service) homeHandler(w http.ResponseWriter, r *http.Request) {
-	render(w, "home", nil)
+	err := render(w, "homePage", nil)
+	if err != nil {
+		log.Printf("Error executing template - %s", err)
+	}
 }
 
 func (service *Service) searchHandler(w http.ResponseWriter, r *http.Request) {
@@ -37,22 +39,23 @@ func (service *Service) searchHandler(w http.ResponseW
 		render(w, "results", results)
 		return
 	}
-	render(w, "home", results)
+	err = render(w, "homePage", results)
+	if err != nil {
+		log.Printf("Error executing template - %s", err)
+	}
 }
 
-type ChannelPage struct {
-	ShowSubscribeButton bool
-	Channel             *rss.Channel
-}
-
 func (service *Service) channelHandler(w http.ResponseWriter, r *http.Request) {
-	channelPage := ChannelPage{ShowSubscribeButton: true}
+	channelPage := ChannelResult{ShowSubscribeButton: true}
 	channelUrl := strings.TrimPrefix(r.URL.Path, "/channel/")
 
 	//Check to see if we have the feed in the database
 	if channel, err := service.db.GetChannel(channelUrl); channel != nil && err == nil {
-		channelPage.Channel = channel
+		channelPage.Channel = *channel
 	}
 
-	render(w, "channelPage", channelPage)
+	err := render(w, "channelPage", channelPage)
+	if err != nil {
+		log.Printf("Error executing template - %s", err)
+	}
 }
blob - 7ed9210fb5ae6c58e79f7f2e061779b2107ecb8d
blob + 0290a91232879dfc969ed229043dc4ca3c74c021
--- internal/service/search.go
+++ internal/service/search.go
@@ -9,8 +9,9 @@ import (
 )
 
 type ChannelResult struct {
-	ChannelUrl string
-	Channel    rss.Channel
+	ShowSubscribeButton bool
+	ChannelUrl          string
+	Channel             rss.Channel
 }
 
 func (service *Service) findChannel(query string) ([]ChannelResult, error) {
blob - ef0a5d66297f2c3b8c46267193799a428e007726
blob + a5ccabe58f529a1cd5b8be587e00bbb6cfc1fbdc
--- internal/templates/channelPage.tmpl
+++ internal/templates/channelPage.tmpl
@@ -1,7 +1,11 @@
 {{ define "channelPage" }}
 {{ template "header" }}
 <main class="search-area">
-    Channels todo {{.Channel.Title}}
+    {{ template "channel" . }}
+    TODO Episodes:
+    {{range .Channel.Items}}
+        <p>{{.Title}}</p>
+    {{end}}
 </main>
 {{ template "footer" }}
 {{ end }}
blob - /dev/null
blob + 877c7246e89f9cba24249441307f109be81eb6b2 (mode 644)
--- /dev/null
+++ internal/templates/channel.tmpl
@@ -0,0 +1,36 @@
+{{ define "channel" }}
+    <div class="result">
+        <img src="{{ .Channel.Image.Href }}" width="170" height="170" />
+        <div>
+            <hgroup>
+                <div class="flex">
+                    <h2>{{ .Channel.Title }}</h2>
+                    {{if .ChannelUrl}}<a class="button" href="/channel/{{ .ChannelUrl | pathEscape}}">Episodes</a>{{end}}
+                    {{if .ShowSubscribeButton}}<a class="button">Subscribe</a>{{end}}
+                </div>
+                <time datetime="{{ .Channel.PubDate.Format "2006-01-02T15:04:05Z07:00" }}">
+                    Last updated {{ .Channel.PubDate | timeAgo }}
+                </time>
+            </hgroup>
+            <p>{{ .Channel.Description }}</p>
+            <div class="tag-line">
+                {{ if gt (len .Channel.Link) 0 }}
+                    <a href="{{index .Channel.Link 0}}" class="button">
+                        <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-globe2" viewBox="0 0 16 16">
+                            <path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m7.5-6.923c-.67.204-1.335.82-1.887 1.855q-.215.403-.395.872c.705.157 1.472.257 2.282.287zM4.249 3.539q.214-.577.481-1.078a7 7 0 0 1 .597-.933A7 7 0 0 0 3.051 3.05q.544.277 1.198.49zM3.509 7.5c.036-1.07.188-2.087.436-3.008a9 9 0 0 1-1.565-.667A6.96 6.96 0 0 0 1.018 7.5zm1.4-2.741a12.3 12.3 0 0 0-.4 2.741H7.5V5.091c-.91-.03-1.783-.145-2.591-.332M8.5 5.09V7.5h2.99a12.3 12.3 0 0 0-.399-2.741c-.808.187-1.681.301-2.591.332zM4.51 8.5c.035.987.176 1.914.399 2.741A13.6 13.6 0 0 1 7.5 10.91V8.5zm3.99 0v2.409c.91.03 1.783.145 2.591.332.223-.827.364-1.754.4-2.741zm-3.282 3.696q.18.469.395.872c.552 1.035 1.218 1.65 1.887 1.855V11.91c-.81.03-1.577.13-2.282.287zm.11 2.276a7 7 0 0 1-.598-.933 9 9 0 0 1-.481-1.079 8.4 8.4 0 0 0-1.198.49 7 7 0 0 0 2.276 1.522zm-1.383-2.964A13.4 13.4 0 0 1 3.508 8.5h-2.49a6.96 6.96 0 0 0 1.362 3.675c.47-.258.995-.482 1.565-.667m6.728 2.964a7 7 0 0 0 2.275-1.521 8.4 8.4 0 0 0-1.197-.49 9 9 0 0 1-.481 1.078 7 7 0 0 1-.597.933M8.5 11.909v3.014c.67-.204 1.335-.82 1.887-1.855q.216-.403.395-.872A12.6 12.6 0 0 0 8.5 11.91zm3.555-.401c.57.185 1.095.409 1.565.667A6.96 6.96 0 0 0 14.982 8.5h-2.49a13.4 13.4 0 0 1-.437 3.008M14.982 7.5a6.96 6.96 0 0 0-1.362-3.675c-.47.258-.995.482-1.565.667.248.92.4 1.938.437 3.008zM11.27 2.461q.266.502.482 1.078a8.4 8.4 0 0 0 1.196-.49 7 7 0 0 0-2.275-1.52c.218.283.418.597.597.932m-.488 1.343a8 8 0 0 0-.395-.872C9.835 1.897 9.17 1.282 8.5 1.077V4.09c.81-.03 1.577-.13 2.282-.287z"/>
+                        </svg>
+                    </a>
+                {{ end }}
+                <a href="mailto:{{.Channel.Owner.Email}}" class="button" style="margin-right: 1rem">
+                    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-envelope" viewBox="0 0 16 16">
+                        <path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1zm13 2.383-4.708 2.825L15 11.105zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741M1 11.105l4.708-2.897L1 5.383z"/>
+                    </svg>
+                </a>
+
+                {{ range .Channel.Categories }}
+                    <a class="category">#{{ .Text }}</a>
+                {{ end }}
+            </div>
+        </div>
+    </div>
+{{ end }}
\ No newline at end of file
blob - 23302b9aa8be8f918eb35fbd152ef550a6366a1c (mode 644)
blob + /dev/null
--- internal/templates/home.tmpl
+++ /dev/null
@@ -1,43 +0,0 @@
-{{ define "home" }}
-{{ template "header" }}
-<main class="search-area">
-    <hgroup class="search-animation">
-        <h1>Subscribe to your favourite feed!</h1>
-        <div style="display: flex">
-            <h3>Your&nbsp;</h3>
-            <div class="text-stack">
-                <h3>exciting calendar event</h3>
-                <h3>top blog</h3>
-                <h3>beloved podcast</h3>
-                <h3>number one forum thread</h3>
-                <h3>go-to YouTube channel</h3>
-            </div>
-        </div>
-    </hgroup>
-
-    <form action="/search" hx-get="/search" hx-target="#search-results" hx-push-url="true">
-        <div class="search-box">
-            <button type="button" aria-label="Filter">
-                <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="currentColor" class="bi bi-filter"
-                    viewBox="0 0 16 16">
-                    <path
-                        d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5" />
-                </svg>
-            </button>
-            <input type="search" autofocus name="search" placeholder="Search for a feed!" />
-            <button type="submit" aria-label="Send">
-                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search"
-                    viewBox="0 0 16 16">
-                    <path
-                        d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0" />
-                </svg>
-            </button>
-        </div>
-    </form>
-
-    <div id="search-results">
-        {{ template "results" . }}
-    </div>
-</main>
-{{ template "footer" }}
-{{ end }}
blob - 659b7e94cc258811911c19033cd2fa7efe7b88b6
blob + 2aab6a3d7f25203a20886b691538fd51768cd146
--- internal/templates/results.tmpl
+++ internal/templates/results.tmpl
@@ -1,39 +1,7 @@
 {{ define "results" }}
     <div class="results">
     {{ range . }}
-        <div class="result">
-            <img src="{{ .Channel.Image.Href }}" width="170" height="170" />
-            <div>
-                <hgroup>
-                    <div class="flex">
-                        <h2>{{ .Channel.Title }}</h2>
-                        <a class="button" href="/channel/{{ .ChannelUrl | pathEscape}}">Episodes</a>
-                    </div>
-                    <time datetime="{{ .Channel.PubDate.Format "2006-01-02T15:04:05Z07:00" }}">
-                        Last updated {{ .Channel.PubDate | timeAgo }}
-                    </time>
-                </hgroup>
-                <p>{{ .Channel.Description }}</p>
-                <div class="tag-line">
-                    {{ if gt (len .Channel.Link) 0 }}
-                        <a href="{{index .Channel.Link 0}}" class="button">
-                            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-globe2" viewBox="0 0 16 16">
-                                <path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8m7.5-6.923c-.67.204-1.335.82-1.887 1.855q-.215.403-.395.872c.705.157 1.472.257 2.282.287zM4.249 3.539q.214-.577.481-1.078a7 7 0 0 1 .597-.933A7 7 0 0 0 3.051 3.05q.544.277 1.198.49zM3.509 7.5c.036-1.07.188-2.087.436-3.008a9 9 0 0 1-1.565-.667A6.96 6.96 0 0 0 1.018 7.5zm1.4-2.741a12.3 12.3 0 0 0-.4 2.741H7.5V5.091c-.91-.03-1.783-.145-2.591-.332M8.5 5.09V7.5h2.99a12.3 12.3 0 0 0-.399-2.741c-.808.187-1.681.301-2.591.332zM4.51 8.5c.035.987.176 1.914.399 2.741A13.6 13.6 0 0 1 7.5 10.91V8.5zm3.99 0v2.409c.91.03 1.783.145 2.591.332.223-.827.364-1.754.4-2.741zm-3.282 3.696q.18.469.395.872c.552 1.035 1.218 1.65 1.887 1.855V11.91c-.81.03-1.577.13-2.282.287zm.11 2.276a7 7 0 0 1-.598-.933 9 9 0 0 1-.481-1.079 8.4 8.4 0 0 0-1.198.49 7 7 0 0 0 2.276 1.522zm-1.383-2.964A13.4 13.4 0 0 1 3.508 8.5h-2.49a6.96 6.96 0 0 0 1.362 3.675c.47-.258.995-.482 1.565-.667m6.728 2.964a7 7 0 0 0 2.275-1.521 8.4 8.4 0 0 0-1.197-.49 9 9 0 0 1-.481 1.078 7 7 0 0 1-.597.933M8.5 11.909v3.014c.67-.204 1.335-.82 1.887-1.855q.216-.403.395-.872A12.6 12.6 0 0 0 8.5 11.91zm3.555-.401c.57.185 1.095.409 1.565.667A6.96 6.96 0 0 0 14.982 8.5h-2.49a13.4 13.4 0 0 1-.437 3.008M14.982 7.5a6.96 6.96 0 0 0-1.362-3.675c-.47.258-.995.482-1.565.667.248.92.4 1.938.437 3.008zM11.27 2.461q.266.502.482 1.078a8.4 8.4 0 0 0 1.196-.49 7 7 0 0 0-2.275-1.52c.218.283.418.597.597.932m-.488 1.343a8 8 0 0 0-.395-.872C9.835 1.897 9.17 1.282 8.5 1.077V4.09c.81-.03 1.577-.13 2.282-.287z"/>
-                            </svg>
-                        </a>
-                    {{ end }}
-                    <a href="mailto:{{.Channel.Owner.Email}}" class="button" style="margin-right: 1rem">
-                        <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-envelope" viewBox="0 0 16 16">
-                            <path d="M0 4a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v.217l7 4.2 7-4.2V4a1 1 0 0 0-1-1zm13 2.383-4.708 2.825L15 11.105zm-.034 6.876-5.64-3.471L8 9.583l-1.326-.795-5.64 3.47A1 1 0 0 0 2 13h12a1 1 0 0 0 .966-.741M1 11.105l4.708-2.897L1 5.383z"/>
-                        </svg>
-                    </a>
-
-                    {{ range .Channel.Categories }}
-                        <a class="category">#{{ .Text }}</a>
-                    {{ end }}
-                </div>
-            </div>
-        </div>
+        {{ template "channel" . }}
     {{ end }}
     </div>
 {{ end }}
\ No newline at end of file
blob - /dev/null
blob + d1df16020a04bda47bd95761a71fffe655c38a5c (mode 644)
--- /dev/null
+++ internal/templates/homePage.tmpl
@@ -0,0 +1,43 @@
+{{ define "homePage" }}
+{{ template "header" }}
+<main class="search-area">
+    <hgroup class="search-animation">
+        <h1>Subscribe to your favourite feed!</h1>
+        <div style="display: flex">
+            <h3>Your&nbsp;</h3>
+            <div class="text-stack">
+                <h3>exciting calendar event</h3>
+                <h3>top blog</h3>
+                <h3>beloved podcast</h3>
+                <h3>number one forum thread</h3>
+                <h3>go-to YouTube channel</h3>
+            </div>
+        </div>
+    </hgroup>
+
+    <form action="/search" hx-get="/search" hx-target="#search-results" hx-push-url="true">
+        <div class="search-box">
+            <button type="button" aria-label="Filter">
+                <svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" fill="currentColor" class="bi bi-filter"
+                    viewBox="0 0 16 16">
+                    <path
+                        d="M6 10.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 0 1h-3a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h7a.5.5 0 0 1 0 1h-7a.5.5 0 0 1-.5-.5m-2-3a.5.5 0 0 1 .5-.5h11a.5.5 0 0 1 0 1h-11a.5.5 0 0 1-.5-.5" />
+                </svg>
+            </button>
+            <input type="search" autofocus name="search" placeholder="Search for a feed!" />
+            <button type="submit" aria-label="Send">
+                <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search"
+                    viewBox="0 0 16 16">
+                    <path
+                        d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0" />
+                </svg>
+            </button>
+        </div>
+    </form>
+
+    <div id="search-results">
+        {{ template "results" . }}
+    </div>
+</main>
+{{ template "footer" }}
+{{ end }}
blob - 273cadda4dc38e2b12ef22db0e9ce52b16cc787d
blob + 3e5a16ca63d50b96853d608997b5c9095754578a
--- web/style.css
+++ web/style.css
@@ -223,13 +223,17 @@ main:has(.result)>hgroup.search-animation {
     }
 }
 
-.results .result {
+.result {
     background-color: var(--black);
     display: flex;
     border-radius: 2rem;
     padding: 1rem;
     box-shadow: var(--shadow);
     margin-bottom: 1rem;
+
+    &>div {
+        width: 100%;
+    }
 
     img {
         border-radius: 2rem;