Skip to content

Commit

Permalink
feat(search): add search suggestions and selection of engines
Browse files Browse the repository at this point in the history
  • Loading branch information
scottmckendry committed Aug 25, 2024
1 parent a4d72d8 commit 07c2b26
Show file tree
Hide file tree
Showing 11 changed files with 340 additions and 27 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ module github.com/scottmckendry/mnemstart
go 1.23.0

require (
github.com/a-h/templ v0.2.747
github.com/a-h/templ v0.2.771
github.com/go-chi/chi/v5 v5.1.0
github.com/gorilla/sessions v1.1.1
github.com/joho/godotenv v1.5.1
Expand All @@ -29,7 +29,7 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 // indirect
golang.org/x/oauth2 v0.17.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/sys v0.23.0 // indirect
google.golang.org/appengine v1.6.8 // indirect
google.golang.org/protobuf v1.33.0 // indirect
modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGB
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
github.com/a-h/templ v0.2.747 h1:D0dQ2lxC3W7Dxl6fxQ/1zZHBQslSkTSvl5FxP/CfdKg=
github.com/a-h/templ v0.2.747/go.mod h1:69ObQIbrcuwPCU32ohNaWce3Cb7qM5GMiqN1K+2yop4=
github.com/a-h/templ v0.2.771 h1:4KH5ykNigYGGpCe0fRJ7/hzwz72k3qFqIiiLLJskbSo=
github.com/a-h/templ v0.2.771/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w=
github.com/antlr4-go/antlr/v4 v4.13.0 h1:lxCg3LAv+EUK6t1i0y1V6/SLeUi0eKEKdhQAlS8TVTI=
github.com/antlr4-go/antlr/v4 v4.13.0/go.mod h1:pfChB/xh/Unjila75QW7+VU4TSnWnnk9UTnmpPaOR2g=
github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo=
Expand Down Expand Up @@ -62,6 +64,7 @@ golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCR
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
Expand All @@ -77,6 +80,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
67 changes: 67 additions & 0 deletions handlers/search.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package handlers

import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"

"github.com/scottmckendry/mnemstart/views"
)

func (h *Handler) HandleSearchSuggest(w http.ResponseWriter, r *http.Request) {
engine := r.FormValue("search_engine")
query := r.FormValue("q")
query = url.QueryEscape(query)

body, err := getGoogleSuggestions(query)
if err != nil {
http.Error(
w,
fmt.Sprintf("Error getting suggestions: %v", err),
http.StatusInternalServerError,
)
return
}

var suggestions []any
err = json.Unmarshal(body, &suggestions)
if err != nil {
http.Error(
w,
fmt.Sprintf("Error unmarshalling suggestions: %v", err),
http.StatusInternalServerError,
)
return
}

parsedSuggestions := parseSuggestions(suggestions[1].([]any))
views.Suggestions(parsedSuggestions, engine).Render(r.Context(), w)
}

func getGoogleSuggestions(query string) ([]byte, error) {
resp, err := http.Get(
"https://suggestqueries.google.com/complete/search?client=firefox&q=" + query,
)
if err != nil {
return nil, err
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, err
}

return body, nil
}

func parseSuggestions(suggestions []any) []string {
var parsedSuggestions []string
for _, suggestion := range suggestions {
parsedSuggestions = append(parsedSuggestions, suggestion.(string))
}

return parsedSuggestions
}
2 changes: 2 additions & 0 deletions handlers/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ func (h *Handler) HandleSettingsUpdate(w http.ResponseWriter, r *http.Request) {
userSettings := h.store.GetUserSettings(user.Email)
userSettings.LeaderKey = r.FormValue("leaderKey")
userSettings.SearchEngine = r.FormValue("searchEngine")

log.Println(userSettings)
h.store.UpdateUserSettings(user.Email, userSettings)

mappings := h.store.GetMappings(user.Email)
Expand Down
1 change: 1 addition & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ func main() {
r.Get("/mappings/edit/{id}", handler.HandleMappingEdit)
r.Put("/mappings/update/{id}", handler.HandleMappingUpdate)
r.Delete("/mappings/delete/{id}", handler.HandleMappingDelete)
r.Post("/search/suggest", handler.HandleSearchSuggest)
})

// auth
Expand Down
4 changes: 1 addition & 3 deletions views/home.templ
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@ templ Home(user goth.User, settings *data.UserSettings, mappings []data.Mapping)
@Page(true, user) {
<div id="main-content">
@Clock()
<form action={ templ.SafeURL(settings.SearchEngine) } method="get">
<input type="text" id="search" name="q" placeholder="Search..."/>
</form>
@Search(settings)
</div>
<p id="status"></p>
<script src="/public/js/input.js"></script>
Expand Down
15 changes: 5 additions & 10 deletions views/home_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

57 changes: 57 additions & 0 deletions views/search.templ
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package views

import (
"github.com/scottmckendry/mnemstart/data"
)

type SearchEngine struct {
URL string
QueryParam string
}

var searchEngines = map[string]SearchEngine{
"Google": {
URL: "https://www.google.com/search",
QueryParam: "q",
},
"DuckDuckGo": {
URL: "https://duckduckgo.com/",
QueryParam: "q",
},
"Bing": {
URL: "https://www.bing.com/search",
QueryParam: "q",
},
"Brave Search": {
URL: "https://search.brave.com/search",
QueryParam: "q",
},
}

templ Search(settings *data.UserSettings) {
<form action={ templ.SafeURL(searchEngines[settings.SearchEngine].URL) } method="get">
<input
type="text"
id="search"
name={ searchEngines[settings.SearchEngine].QueryParam }
placeholder="Search..."
hx-post="/search/suggest"
hx-target="#suggestions"
hx-trigger="input changed delay:500ms"
autocomplete="off"
/>
// hidden form value that indicates the search engine
<input type="hidden" name="search_engine" value={ settings.SearchEngine }/>
</form>
<div id="suggestions"></div>
}

templ Suggestions(suggestions []string, engine string) {
for _, suggestion := range suggestions {
<a href={ templ.SafeURL(searchEngines[engine].URL + "?" + searchEngines[engine].QueryParam + "=" + suggestion) }>
<div class="suggestion">
{ suggestion }
</div>
</a>
}
}
150 changes: 150 additions & 0 deletions views/search_templ.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 7 additions & 2 deletions views/settings.templ
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,14 @@ templ Settings(user goth.User, settings *data.UserSettings) {
<label for="leaderKey">Leader Key</label>
<input type="text" name="leaderKey" value={ settings.LeaderKey } placeholder="Leader Key" data-include-edit=""/>
<label for="searchEngine">Search Engine</label>
<input type="text" name="searchEngine" value={ settings.SearchEngine } placeholder="Search Engine" data-include-edit=""/>
<select name="searchEngine" data-include-edit="">
// See search.templ for the full list of search engines
for name := range searchEngines {
<option value={ name } selected?={ settings.SearchEngine == name }>{ name }</option>
}
</select>
<div class="action-buttons">
<button class="button" _="on click trigger closeModal" hx-put="/update-settings" hx-include="input[data-include-edit]">Save</button>
<button class="button" _="on click trigger closeModal" hx-put="/update-settings" hx-include="input[data-include-edit],select[data-include-edit]">Save</button>
</div>
}
}
Loading

0 comments on commit 07c2b26

Please sign in to comment.