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