view: added start download button to subreddit details page
This commit is contained in:
parent
fe1ad50670
commit
08d81a2f94
|
@ -28,8 +28,10 @@ func (routes *Routes) Register(router chi.Router) {
|
|||
router.Get("/hot_reload", routes.CreateHotReloadRoute())
|
||||
}
|
||||
|
||||
router.Group(routes.registerWWWRoutes)
|
||||
router.Route("/htmx", routes.registerHTMXRoutes)
|
||||
router.Route("/api/v1", routes.registerV1APIRoutes)
|
||||
|
||||
router.Group(routes.registerWWWRoutes)
|
||||
}
|
||||
|
||||
func (routes *Routes) registerV1APIRoutes(router chi.Router) {
|
||||
|
@ -51,6 +53,14 @@ func (routes *Routes) registerV1APIRoutes(router chi.Router) {
|
|||
router.Get("/events", routes.EventsAPI)
|
||||
}
|
||||
|
||||
func (routes *Routes) registerHTMXRoutes(router chi.Router) {
|
||||
router.Use(otelchi.Middleware("redmage"))
|
||||
router.Use(chimiddleware.RequestLogger(middleware.ChiLogger{}))
|
||||
router.Use(chimiddleware.SetHeader("Content-Type", "text/html; charset=utf-8"))
|
||||
|
||||
router.Post("/subreddits/start", routes.SubredditStartDownloadHTMX)
|
||||
}
|
||||
|
||||
func (routes *Routes) registerWWWRoutes(router chi.Router) {
|
||||
router.Mount("/public", http.StripPrefix("/public", http.FileServer(http.FS(routes.PublicDir))))
|
||||
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
package routes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
|
||||
"github.com/tigorlazuardi/redmage/api"
|
||||
"github.com/tigorlazuardi/redmage/pkg/errs"
|
||||
"github.com/tigorlazuardi/redmage/pkg/log"
|
||||
)
|
||||
|
||||
func (r *Routes) SubredditStartDownloadAPI(rw http.ResponseWriter, req *http.Request) {
|
||||
enc := json.NewEncoder(rw)
|
||||
if r.Config.String("download.directory") == "" {
|
||||
rw.WriteHeader(http.StatusBadRequest)
|
||||
_ = enc.Encode(map[string]string{"error": "cannot download subreddits when download directory is not configured"})
|
||||
return
|
||||
}
|
||||
|
||||
ctx := req.Context()
|
||||
|
||||
var body api.PubsubStartDownloadSubredditParams
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&body)
|
||||
if err != nil {
|
||||
rw.WriteHeader(http.StatusBadRequest)
|
||||
_ = enc.Encode(map[string]string{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
err = r.API.PubsubStartDownloadSubreddit(ctx, body)
|
||||
if err != nil {
|
||||
log.New(ctx).Err(err).Error("failed to start subreddit download", "subreddit", body.Subreddit)
|
||||
code, message := errs.HTTPMessage(err)
|
||||
rw.WriteHeader(code)
|
||||
_ = enc.Encode(map[string]string{"error": message})
|
||||
return
|
||||
}
|
||||
|
||||
_ = enc.Encode(map[string]string{"message": "subreddit enqueued"})
|
||||
}
|
77
server/routes/subreddit_start.go
Normal file
77
server/routes/subreddit_start.go
Normal file
|
@ -0,0 +1,77 @@
|
|||
package routes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/tigorlazuardi/redmage/api"
|
||||
"github.com/tigorlazuardi/redmage/pkg/errs"
|
||||
"github.com/tigorlazuardi/redmage/pkg/log"
|
||||
"github.com/tigorlazuardi/redmage/views/components"
|
||||
)
|
||||
|
||||
func (r *Routes) SubredditStartDownloadAPI(rw http.ResponseWriter, req *http.Request) {
|
||||
ctx, span := tracer.Start(req.Context(), "Routes.SubredditStartDownloadAPI")
|
||||
defer span.End()
|
||||
|
||||
enc := json.NewEncoder(rw)
|
||||
if r.Config.String("download.directory") == "" {
|
||||
rw.WriteHeader(http.StatusBadRequest)
|
||||
_ = enc.Encode(map[string]string{"error": "cannot download subreddits when download directory is not configured"})
|
||||
return
|
||||
}
|
||||
|
||||
var body api.PubsubStartDownloadSubredditParams
|
||||
|
||||
err := json.NewDecoder(req.Body).Decode(&body)
|
||||
if err != nil {
|
||||
rw.WriteHeader(http.StatusBadRequest)
|
||||
_ = enc.Encode(map[string]string{"error": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
err = r.API.PubsubStartDownloadSubreddit(ctx, body)
|
||||
if err != nil {
|
||||
log.New(ctx).Err(err).Error("failed to start subreddit download", "subreddit", body.Subreddit)
|
||||
code, message := errs.HTTPMessage(err)
|
||||
rw.WriteHeader(code)
|
||||
_ = enc.Encode(map[string]string{"error": message})
|
||||
return
|
||||
}
|
||||
|
||||
_ = enc.Encode(map[string]string{"message": "subreddit enqueued"})
|
||||
}
|
||||
|
||||
func (routes *Routes) SubredditStartDownloadHTMX(rw http.ResponseWriter, r *http.Request) {
|
||||
ctx, span := tracer.Start(r.Context(), "Routes.SubredditStartDownloadHTMX")
|
||||
defer span.End()
|
||||
|
||||
if routes.Config.String("download.directory") == "" {
|
||||
rw.WriteHeader(http.StatusBadRequest)
|
||||
if err := components.ErrorNotication("Cannot download subreddits when download directory is not configured").Render(ctx, rw); err != nil {
|
||||
log.New(ctx).Err(err).Error("failed to render error notification")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var body api.PubsubStartDownloadSubredditParams
|
||||
body.Subreddit = r.FormValue("subreddit")
|
||||
|
||||
err := routes.API.PubsubStartDownloadSubreddit(ctx, body)
|
||||
if err != nil {
|
||||
log.New(ctx).Err(err).Error("failed to start subreddit download", "subreddit", body.Subreddit)
|
||||
code, message := errs.HTTPMessage(err)
|
||||
rw.WriteHeader(code)
|
||||
if err := components.ErrorNotication(message).Render(ctx, rw); err != nil {
|
||||
log.New(ctx).Err(err).Error("failed to render error notification")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
msg := fmt.Sprintf("Subreddit %s enqueued", body.Subreddit)
|
||||
|
||||
if err := components.SuccessNotification(msg).Render(ctx, rw); err != nil {
|
||||
log.New(ctx).Err(err).Error("failed to render success notification")
|
||||
}
|
||||
}
|
58
views/components/notification.templ
Normal file
58
views/components/notification.templ
Normal file
|
@ -0,0 +1,58 @@
|
|||
package components
|
||||
|
||||
const NotificationContainerID = "#notification-container"
|
||||
|
||||
templ NotificationContainer() {
|
||||
<div id="notification-container" class="fixed bottom-4 right-4 z-50"></div>
|
||||
}
|
||||
|
||||
templ InfoNotication(messages ...string) {
|
||||
<div
|
||||
hx-on::load="setTimeout(() => this.remove(), 5000)"
|
||||
class="toast"
|
||||
onclick="this.remove()"
|
||||
>
|
||||
<div class="alert alert-info hover:bg-info-content transition-all">
|
||||
for i, message := range messages {
|
||||
<span>{ message }</span>
|
||||
if i != len(messages) - 1 {
|
||||
<br/>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ ErrorNotication(messages ...string) {
|
||||
<div
|
||||
hx-on::load="setTimeout(() => this.remove(), 5000)"
|
||||
class="toast"
|
||||
onclick="this.remove()"
|
||||
>
|
||||
<div class="alert alert-error hover:bg-error-content transition-all">
|
||||
for i, message := range messages {
|
||||
<span>{ message }</span>
|
||||
if i != len(messages) - 1 {
|
||||
<br/>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
templ SuccessNotification(messages ...string) {
|
||||
<div
|
||||
hx-on::load="setTimeout(() => this.remove(), 5000)"
|
||||
class="toast"
|
||||
onclick="this.remove()"
|
||||
>
|
||||
<div class="alert alert-success hover:bg-success-content transition-all">
|
||||
for i, message := range messages {
|
||||
<span>{ message }</span>
|
||||
if i != len(messages) - 1 {
|
||||
<br/>
|
||||
}
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
|
@ -20,6 +20,7 @@ templ Detailsview(c *views.Context, data Data) {
|
|||
@components.Head(c, components.HeadTitle("Redmage - Subreddits"))
|
||||
@components.Body(c) {
|
||||
@DetailsContent(c, data)
|
||||
@components.NotificationContainer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,10 +32,23 @@ templ DetailsContent(c *views.Context, data Data) {
|
|||
<h1>Error: { data.Error }</h1>
|
||||
} else {
|
||||
<h1>Subreddit { data.Subreddit.Name }</h1>
|
||||
<h2>
|
||||
<div class="flex flex-wrap justify-between content-center">
|
||||
<h2 class="my-auto">
|
||||
Total Images:
|
||||
{ strconv.FormatInt(data.TotalImages, 10) }
|
||||
</h2>
|
||||
<button
|
||||
hx-post="/htmx/subreddits/start"
|
||||
hx-include="this"
|
||||
class="btn btn-info"
|
||||
hx-target={ components.NotificationContainerID }
|
||||
hx-target-error={ components.NotificationContainerID }
|
||||
hx-swap="afterbegin"
|
||||
>
|
||||
Start Download
|
||||
<input type="hidden" name="subreddit" value={ data.Subreddit.Name }/>
|
||||
</button>
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="flex gap-4 flex-wrap justify-between content-center">
|
||||
@FilterBar(c, data)
|
||||
|
|
Loading…
Reference in a new issue