search-release.go (3063B)
1 package server 2 3 import ( 4 "context" 5 "errors" 6 "lyrics/internal/db" 7 "lyrics/internal/domain" 8 "lyrics/internal/server/htmx" 9 releasesearchpicker "lyrics/internal/server/ui/partials/release-search-picker" 10 releasesearchsimilar "lyrics/internal/server/ui/partials/release-search-similar" 11 releasesearchtable "lyrics/internal/server/ui/partials/release-search-table" 12 "net/http" 13 "strconv" 14 ) 15 16 func (ss *ServerState) SearchRelease(w http.ResponseWriter, r *http.Request) { 17 logger := ss.logger.With("handler", "SearchRelease") 18 19 format := domain.SearchFormat(r.URL.Query().Get("format")) 20 21 var renderErr error 22 switch format { 23 case domain.SearchFormatSimilar: 24 release := r.URL.Query().Get("release-title") 25 26 _, results, err := db.SearchRelease(ss.db, release, 5, 1) 27 if err != nil { 28 logger.Error("failed to query db for releases", "err", err) 29 htmx.HxError(w, http.StatusInternalServerError, "Failed to search for release.") 30 return 31 } 32 33 renderErr = releasesearchsimilar.ReleaseSearchSimilar(releasesearchsimilar.ReleaseSearchSimilarParams{ 34 Releases: results, 35 }).Render(r.Context(), w) 36 case domain.SearchFormatSuggest: 37 release := r.URL.Query().Get("release-title") 38 39 _, results, err := db.SearchRelease(ss.db, release, 5, 1) 40 if err != nil { 41 logger.Error("failed to query db for releases", "err", err) 42 htmx.HxError(w, http.StatusInternalServerError, "Failed to search for release.") 43 return 44 } 45 46 renderErr = releasesearchpicker.ReleaseSearchPicker(releasesearchpicker.ReleaseSearchPickerParams{ 47 Releases: results, 48 }).Render(r.Context(), w) 49 case domain.SearchFormatTable: 50 query := r.URL.Query().Get("query") 51 pageStr := r.URL.Query().Get("page") 52 limitStr := r.URL.Query().Get("limit") 53 54 if pageStr == "" { 55 pageStr = "1" 56 } 57 58 page, err := strconv.ParseInt(pageStr, 10, 64) 59 if err != nil { 60 logger.Error("failed to parse page value", "err", err) 61 page = 1 62 } 63 if page <= 0 { 64 page = 1 65 } 66 67 if limitStr == "" { 68 limitStr = "25" 69 } 70 71 limit, err := strconv.ParseInt(limitStr, 10, 64) 72 if err != nil { 73 logger.Error("failed to parse limit value", "err", err) 74 limit = 25 75 } 76 if limit < 1 { 77 limit = 25 78 } 79 if limit > 100 { 80 limit = 100 81 } 82 83 offset := (page - 1) * limit 84 85 totalRows, results, err := db.SearchRelease(ss.db, query, limit, offset) 86 if err != nil { 87 logger.Error("failed to query db for releases", "err", err) 88 htmx.HxError(w, http.StatusInternalServerError, "Failed to search for release.") 89 return 90 } 91 totalPages := (int64(totalRows) + limit - 1) / limit 92 93 renderErr = releasesearchtable.ReleaseSearchTable(releasesearchtable.ReleaseSearchTableParams{ 94 Releases: results, 95 TotalPages: int64(totalPages), 96 CurrentPage: page, 97 Query: query, 98 Limit: limit, 99 }).Render(r.Context(), w) 100 } 101 if renderErr != nil { 102 if errors.Is(renderErr, context.Canceled) { 103 return 104 } 105 106 logger.Error("failed to render search release partial", "err", renderErr) 107 htmx.HxError(w, http.StatusInternalServerError, "Failed to render response.") 108 return 109 } 110 }