From e8da8717eaccd2c80d1c4ac0bfafd38029fe0c02 Mon Sep 17 00:00:00 2001 From: Tigor Hutasuhut Date: Tue, 7 May 2024 22:50:23 +0700 Subject: [PATCH] devices: properly implemented and integrated windows wallpaper mode --- api/reddit/post.go | 10 +++ api/subreddits_get_by_name.go | 4 ++ server/routes/device_create.go | 66 +++++++++++++++++++ server/routes/page_subreddits_details.go | 2 +- server/routes/routes.go | 1 + views/components/image_card.templ | 6 ++ views/devicesview/adddevice/name_input.templ | 4 +- .../devicesview/adddevice/nsfw_checkbox.templ | 24 +++++++ views/devicesview/adddevice/view.templ | 6 ++ .../windows_wallpaper_checkbox.templ | 27 ++++++++ views/homeview/homeview.templ | 2 +- .../detailsview/detailsview.templ | 4 +- 12 files changed, 150 insertions(+), 6 deletions(-) create mode 100644 views/devicesview/adddevice/nsfw_checkbox.templ create mode 100644 views/devicesview/adddevice/windows_wallpaper_checkbox.templ diff --git a/api/reddit/post.go b/api/reddit/post.go index e9ed7a0..ff817ef 100644 --- a/api/reddit/post.go +++ b/api/reddit/post.go @@ -262,6 +262,9 @@ func (post *Post) GetName() string { } func (post *Post) GetImageTargetPath(cfg *config.Config, device *models.Device) string { + if device.WindowsWallpaperMode == 1 { + return post.GetWindowsWallpaperImageTargetPath(cfg, device) + } baseDownloadDir := cfg.String("download.directory") p := path.Join(baseDownloadDir, device.Slug, post.GetSubreddit(), post.GetImageFilename()) abs, _ := filepath.Abs(p) @@ -269,6 +272,9 @@ func (post *Post) GetImageTargetPath(cfg *config.Config, device *models.Device) } func (post *Post) GetImageTargetDir(cfg *config.Config, device *models.Device) string { + if device.WindowsWallpaperMode == 1 { + return post.GetWindowsWallpaperImageTargetDir(cfg, device) + } baseDownloadDir := cfg.String("download.directory") p := path.Join(baseDownloadDir, device.Slug, post.GetSubreddit()) abs, _ := filepath.Abs(p) @@ -316,6 +322,10 @@ func (post *Post) GetThumbnailRelativePath() string { } func (post *Post) GetImageRelativePath(device *models.Device) string { + if device.WindowsWallpaperMode == 1 { + return post.GetWindowsWallpaperImageRelativePath(device) + } + return path.Join(device.Slug, post.GetSubreddit(), post.GetImageFilename()) } diff --git a/api/subreddits_get_by_name.go b/api/subreddits_get_by_name.go index d2d28c6..7b46fab 100644 --- a/api/subreddits_get_by_name.go +++ b/api/subreddits_get_by_name.go @@ -186,6 +186,10 @@ func (api *API) SubredditGetByNameWithImages(ctx context.Context, name string, i return result, errs.Wrapw(err, "failed to get images by subreddit", "subreddit", result.Subreddit.Name, "params", imageParams) } + if err := result.Images.LoadImageDevice(ctx, api.db); err != nil { + return result, errs.Wrapw(err, "failed to get device by images") + } + result.Total, err = models.Images. Query(ctx, api.db, append(imageParams.CountQuery(), models.SelectWhere.Images.Subreddit.EQ(result.Subreddit.Name))...). Count() diff --git a/server/routes/device_create.go b/server/routes/device_create.go index 03c2bf7..b4c435a 100644 --- a/server/routes/device_create.go +++ b/server/routes/device_create.go @@ -6,11 +6,13 @@ import ( "fmt" "net/http" "regexp" + "strconv" "github.com/tigorlazuardi/redmage/models" "github.com/tigorlazuardi/redmage/pkg/errs" "github.com/tigorlazuardi/redmage/pkg/log" "github.com/tigorlazuardi/redmage/pkg/telemetry" + "github.com/tigorlazuardi/redmage/views/components" ) func (routes *Routes) APIDeviceCreate(rw http.ResponseWriter, r *http.Request) { @@ -95,3 +97,67 @@ func validateCreateDevice(params *models.Device) error { } return nil } + +func (routes *Routes) DevicesCreateHTMX(rw http.ResponseWriter, req *http.Request) { + var err error + ctx, span := tracer.Start(req.Context(), "*Routes.DevicesCreateHTMX") + defer func() { telemetry.EndWithStatus(span, err) }() + + device, err := createDeviceFromParams(req) + if err != nil { + rw.WriteHeader(400) + if err := components.ErrorToast(err.Error()).Render(ctx, rw); err != nil { + log.New(ctx).Err(err).Error("failed to render error notification") + } + return + } + + _, err = routes.API.DevicesCreate(ctx, device) + if err != nil { + log.New(ctx).Err(err).Error("failed to create device", "device", device) + code, message := errs.HTTPMessage(err) + rw.WriteHeader(code) + if err := components.ErrorToast(message).Render(ctx, rw); err != nil { + log.New(ctx).Err(err).Error("failed to render error notification") + } + return + } + + rw.Header().Set("HX-Redirect", "/devices") + rw.WriteHeader(http.StatusCreated) + + if err := components.SuccessToast("device created").Render(ctx, rw); err != nil { + log.New(ctx).Err(err).Error("failed to render success notification") + } +} + +func createDeviceFromParams(req *http.Request) (*models.Device, error) { + device := new(models.Device) + + device.Enable = 1 + device.Name = req.FormValue("name") + device.Slug = req.FormValue("slug") + device.ResolutionX, _ = strconv.ParseFloat(req.FormValue("resolution_x"), 32) + device.ResolutionY, _ = strconv.ParseFloat(req.FormValue("resolution_y"), 32) + device.AspectRatioTolerance, _ = strconv.ParseFloat(req.FormValue("aspect_ratio_tolerance"), 32) + + maxX, _ := strconv.ParseInt(req.FormValue("max_x"), 10, 32) + device.MaxX = int32(maxX) + + maxY, _ := strconv.ParseInt(req.FormValue("max_y"), 10, 32) + device.MaxY = int32(maxY) + + minX, _ := strconv.ParseInt(req.FormValue("min_x"), 10, 32) + device.MinX = int32(minX) + + minY, _ := strconv.ParseInt(req.FormValue("min_y"), 10, 32) + device.MinY = int32(minY) + + nsfw, _ := strconv.ParseInt(req.FormValue("nsfw"), 10, 32) + device.NSFW = int32(nsfw) + + windowsWallpaperMode, _ := strconv.ParseInt(req.FormValue("windows_wallpaper_mode"), 10, 32) + device.WindowsWallpaperMode = int32(windowsWallpaperMode) + + return device, validateCreateDevice(device) +} diff --git a/server/routes/page_subreddits_details.go b/server/routes/page_subreddits_details.go index 96ab840..0d71ce9 100644 --- a/server/routes/page_subreddits_details.go +++ b/server/routes/page_subreddits_details.go @@ -40,7 +40,7 @@ func (routes *Routes) PageSubredditsDetails(rw http.ResponseWriter, r *http.Requ data.Subreddit = result.Subreddit data.Images = result.Images data.TotalImages = result.Total - data.Devices, err = routes.API.GetDevices(ctx, api.DevicesListParams{}) + data.Devices, err = routes.API.GetDevices(ctx, api.DevicesListParams{Status: -1}) if err != nil { log.New(ctx).Err(err).Error("failed to get devices") code, message := errs.HTTPMessage(err) diff --git a/server/routes/routes.go b/server/routes/routes.go index 2681a54..2bfc1f9 100644 --- a/server/routes/routes.go +++ b/server/routes/routes.go @@ -63,6 +63,7 @@ func (routes *Routes) registerHTMXRoutes(router chi.Router) { router.Post("/subreddits/check", routes.SubredditCheckHTMX) router.Get("/subreddits/validate/schedule", routes.SubredditValidateScheduleHTMX) + router.Post("/devices/add", routes.DevicesCreateHTMX) router.Post("/devices/add/validate/slug", routes.DevicesValidateSlugHTMX) router.Post("/devices/add/validate/name", routes.DevicesValidateNameHTMX) } diff --git a/views/components/image_card.templ b/views/components/image_card.templ index 8e7521f..edc12b2 100644 --- a/views/components/image_card.templ +++ b/views/components/image_card.templ @@ -14,6 +14,7 @@ const ( HideTitle ImageCardOption = 1 << iota HideSubreddit HidePoster + HideDevice ) templ ImageCard(data *models.Image, opts ImageCardOption) { @@ -48,6 +49,11 @@ templ ImageCard(data *models.Image, opts ImageCardOption) {

{ fmt.Sprintf("%d \u00d7 %d", data.ImageWidth, data.ImageHeight) } px

{ formatByteSize(data.ImageSize) }

+ if data.R.Device != nil && !opts.Has(HideDevice) { + +
{ data.R.Device.Name }
+
+ } } diff --git a/views/devicesview/adddevice/name_input.templ b/views/devicesview/adddevice/name_input.templ index 593f76b..6e2f64a 100644 --- a/views/devicesview/adddevice/name_input.templ +++ b/views/devicesview/adddevice/name_input.templ @@ -9,7 +9,7 @@ type NameInputData struct { } templ NameInput(data NameInputData) { -