diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..951eef94b --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,4 @@ +{ + "makefile.extensionOutputFolder": "./.vscode", + "go.testFlags": ["-v"] +} \ No newline at end of file diff --git a/main.go b/main.go index 5459e79f7..c66167463 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,12 @@ import ( "log" "net/http" "os" + "strconv" + "strings" +) + +const ( + Limit = 20 ) func main() { @@ -48,7 +54,9 @@ func handleSearch(searcher Searcher) func(w http.ResponseWriter, r *http.Request w.Write([]byte("missing search query in URL params")) return } - results := searcher.Search(query[0]) + page := page(r.URL.Query().Get("p")) + + results := searcher.Search(query[0], page) buf := &bytes.Buffer{} enc := json.NewEncoder(buf) err := enc.Encode(results) @@ -68,15 +76,33 @@ func (s *Searcher) Load(filename string) error { return fmt.Errorf("Load: %w", err) } s.CompleteWorks = string(dat) - s.SuffixArray = suffixarray.New(dat) + lowerWorks := strings.ToLower(s.CompleteWorks) + s.SuffixArray = suffixarray.New([]byte(lowerWorks)) return nil } -func (s *Searcher) Search(query string) []string { +func (s *Searcher) Search(query string, page int) []string { + query = strings.ToLower(query) idxs := s.SuffixArray.Lookup([]byte(query), -1) + offset := page * Limit + if len(idxs) >= (offset + Limit) { + idxs = idxs[offset : offset+Limit] + } else if offset < len(idxs) { + idxs = idxs[offset:] + } else { // out of range, send empty + idxs = []int{} + } results := []string{} for _, idx := range idxs { results = append(results, s.CompleteWorks[idx-250:idx+250]) } return results } + +func page(s string) int { + if i, err := strconv.Atoi(s); err == nil { + return i + } + log.Printf("*> unexpected error occured when converting string %s to int on `page` sending zero\n", s) + return 0 +} diff --git a/static/app.js b/static/app.js index 3ba77f817..e4f9a6c08 100644 --- a/static/app.js +++ b/static/app.js @@ -1,11 +1,25 @@ const Controller = { search: (ev) => { ev.preventDefault(); + page = 0; const form = document.getElementById("form"); const data = Object.fromEntries(new FormData(form)); - const response = fetch(`/search?q=${data.query}`).then((response) => { + const response = fetch(`/search?q=${data.query}&p=${page}`).then((response) => { response.json().then((results) => { Controller.updateTable(results); + page = page + 1 + }); + }); + }, + + loadmore: (ev) => { + ev.preventDefault(); + const form = document.getElementById("form"); + const data = Object.fromEntries(new FormData(form)); + const response = fetch(`/search?q=${data.query}&p=${page}`).then((response) => { + response.json().then((results) => { + Controller.updateTable(results); + page = page + 1 }); }); }, @@ -16,9 +30,16 @@ const Controller = { for (let result of results) { rows.push(`${result}`); } - table.innerHTML = rows; + if (page == 0){ + table.innerHTML = rows; + } else { + table.innerHTML = table.innerHTML + rows; + } }, }; +var page = 0; const form = document.getElementById("form"); +const button = document.getElementById("load-more"); form.addEventListener("submit", Controller.search); +button.addEventListener("click", Controller.loadmore); diff --git a/static/index.html b/static/index.html index cccacbd1b..a5ec37ca3 100644 --- a/static/index.html +++ b/static/index.html @@ -21,7 +21,7 @@

- +