From 08d81a2f94589fad2693ef2488a0e07c1dfb97fd Mon Sep 17 00:00:00 2001 From: Tigor Hutasuhut Date: Thu, 2 May 2024 20:59:32 +0700 Subject: [PATCH] view: added start download button to subreddit details page --- server/routes/routes.go | 12 ++- server/routes/subreddit_download.go | 41 ---------- server/routes/subreddit_start.go | 77 +++++++++++++++++++ views/components/notification.templ | 58 ++++++++++++++ .../detailsview/detailsview.templ | 22 +++++- 5 files changed, 164 insertions(+), 46 deletions(-) delete mode 100644 server/routes/subreddit_download.go create mode 100644 server/routes/subreddit_start.go create mode 100644 views/components/notification.templ diff --git a/server/routes/routes.go b/server/routes/routes.go index ac487a4..c89b9e9 100644 --- a/server/routes/routes.go +++ b/server/routes/routes.go @@ -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)))) diff --git a/server/routes/subreddit_download.go b/server/routes/subreddit_download.go deleted file mode 100644 index 4bf0b5f..0000000 --- a/server/routes/subreddit_download.go +++ /dev/null @@ -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"}) -} diff --git a/server/routes/subreddit_start.go b/server/routes/subreddit_start.go new file mode 100644 index 0000000..cf06c20 --- /dev/null +++ b/server/routes/subreddit_start.go @@ -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") + } +} diff --git a/views/components/notification.templ b/views/components/notification.templ new file mode 100644 index 0000000..7b6b230 --- /dev/null +++ b/views/components/notification.templ @@ -0,0 +1,58 @@ +package components + +const NotificationContainerID = "#notification-container" + +templ NotificationContainer() { +
+} + +templ InfoNotication(messages ...string) { +
+
+ for i, message := range messages { + { message } + if i != len(messages) - 1 { +
+ } + } +
+
+} + +templ ErrorNotication(messages ...string) { +
+
+ for i, message := range messages { + { message } + if i != len(messages) - 1 { +
+ } + } +
+
+} + +templ SuccessNotification(messages ...string) { +
+
+ for i, message := range messages { + { message } + if i != len(messages) - 1 { +
+ } + } +
+
+} diff --git a/views/subredditsview/detailsview/detailsview.templ b/views/subredditsview/detailsview/detailsview.templ index 8e0b6e9..121a7ba 100644 --- a/views/subredditsview/detailsview/detailsview.templ +++ b/views/subredditsview/detailsview/detailsview.templ @@ -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) {

Error: { data.Error }

} else {

Subreddit { data.Subreddit.Name }

-

- Total Images: - { strconv.FormatInt(data.TotalImages, 10) } -

+
+

+ Total Images: + { strconv.FormatInt(data.TotalImages, 10) } +

+ +
@FilterBar(c, data)