Skip to content

Commit

Permalink
search, add 'clear' button (#398)
Browse files Browse the repository at this point in the history
* jfx, search pane, adds 'clear' button that resets search state.
* jfx, 'clear' button disabled when search not customised.
* cli, tweaks some log messages to remove redundant information
* jfx, search buttons are now a uniform height.
* jfx, removed border radius on search input button.
  • Loading branch information
torkus authored Apr 27, 2023
1 parent 1c5077b commit 99b1647
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 29 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

* a "clear" button to the search addons tab that removes all search filters, including search terms.
* new column for installed addons "starred" that will add an installed addon to the 'user-catalogue'.
- star button disabled when addon is being ignored or isn't matched against the catalogue.
* new column for installed addons "size" with the total size of the addon on disk, including any grouped addons.
Expand Down Expand Up @@ -43,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

* minor cosmetic fix. the buttons on the search tab are now a consistent height.
* possible cache stampede fetching strongbox release info. A lock is now acquired to ensure checks happen sequentially.
- it was possible for the GUI to fire off many requests to Github simultaneously, bypassing cache and overwriting each other.

Expand Down
14 changes: 11 additions & 3 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,19 @@ see CHANGELOG.md for a more formal list of changes by release
- import it with find-addon?
- done

* search, a 'clear' button
- resets favourited, search input, tags, etc
- done

* search, buttons are slightly different sizes
- input star and dropdown are a few pixels shorter than the buttons on either side
- done

## todo

* user-catalogue
- switch to log window to see progress when refresh-catalogue triggered

* user catalogue, schedule refreshes
- ensure the user catalogue doesn't get too stale and perform an update in the background if it looks like it's very old
- update README
Expand All @@ -76,9 +87,6 @@ see CHANGELOG.md for a more formal list of changes by release
* user catalogue, refreshing may guarantee exceeding github limit.
- if we know this, add a warning? refuse?

* search, a 'clear' button
- resets favourited, search input, tags, etc

* 'core/state :db-stats', seems like a nice idea to put more information here
- known-hosts
- num addons per-host
Expand Down
26 changes: 12 additions & 14 deletions src/strongbox/cli.clj
Original file line number Diff line number Diff line change
Expand Up @@ -197,16 +197,10 @@
(doseq [path path-list]
(core/state-bind path listener))))

(defn-spec reset-search-navigation nil?
"returns the search results to page 1"
[]
(swap! core/state assoc-in [:search :page] 0)
nil)

(defn-spec search-add-filter nil?
"adds a new filter to the search `filter-by` state."
[filter-by :search/filter-by, val any?]
(reset-search-navigation)
(core/reset-search-navigation)
(case filter-by
:source (swap! core/state assoc-in [:search :filter-by filter-by] (utils/nilable val))
:tag (swap! core/state update-in [:search :filter-by filter-by] conj val)
Expand All @@ -216,17 +210,23 @@
(defn-spec search-rm-filter nil?
"removes a filter from the search `filter-by` state."
[filter-by :search/filter-by, val any?]
(reset-search-navigation)
(core/reset-search-navigation)
(swap! core/state update-in [:search :filter-by filter-by] clojure.set/difference #{val})
nil)

(defn-spec search-toggle-filter nil?
"toggles boolean filters on and off"
[filter-by :search/filter-by]
(reset-search-navigation)
(core/reset-search-navigation)
(swap! core/state update-in [:search :filter-by filter-by] not)
nil)

(defn-spec clear-search! nil?
"resets the search state to defaults and jogs the search results"
[]
(core/reset-search-state!)
(bump-search))

;;

(defn-spec change-catalogue nil?
Expand Down Expand Up @@ -708,21 +708,19 @@
"refresh the details of an individual `addon` in the user catalogue, optionally writing the updated catalogue to file."
[addon :addon/summary, db :addon/summary-list]
(logging/with-addon addon
(info "refreshing user-catalogue addon:" (:name addon))
(info "refreshing user-catalogue entry")
(try
(let [{:keys [source source-id url]} addon
refreshed-addon (core/db-addon-by-source-and-source-id db source source-id)
attempt-dry-run? false
refreshed-addon (or refreshed-addon
(find-addon url attempt-dry-run?))]
(if-not refreshed-addon
(warn (format "failed to refresh details of addon in user-catalogue: couldn't find addon '%s' in catalogue or online"
(:name addon)))
(warn "failed to refresh user-catalogue entry as the addon was not found in the catalogue or online")
(core/add-user-addon! refreshed-addon)))

(catch Exception e
(error (format "an unexpected error happened while updating the details for '%s' in the user-catalogue: %s"
(:name addon) (.getMessage e)))))))
(error (format "an unexpected error happened while refreshing the user-catalogue entry: %s" (.getMessage e)))))))

(defn-spec refresh-user-catalogue nil?
"refresh the details of all addons in the user catalogue, writing the updated catalogue to file once."
Expand Down
16 changes: 14 additions & 2 deletions src/strongbox/core.clj
Original file line number Diff line number Diff line change
Expand Up @@ -923,12 +923,24 @@
(partition-all cap (seque 100 (filter match-fn db))))))))

(defn-spec empty-search-results nil?
"empties app state of search results.
this is to clear out anything between catalogue reloads."
"empties app state of search *results* but not filters.
this handles catalogue reloads but preserves user filtering."
[]
(swap! state update-in [:search] merge (select-keys -search-state-template [:page :results :selected-results-list]))
nil)

(defn-spec reset-search-navigation nil?
"resets the search results to page 1"
[]
(swap! state assoc-in [:search :page] 0)
nil)

(defn-spec reset-search-state! nil?
"replaces search state with default settings."
[]
(swap! state update-in [:search] merge -search-state-template)
nil)

(defn-spec db-load-user-catalogue nil?
"loads the user catalogue into state, but only if it hasn't already been loaded."
[]
Expand Down
35 changes: 29 additions & 6 deletions src/strongbox/jfx.clj
Original file line number Diff line number Diff line change
Expand Up @@ -510,15 +510,22 @@

"#search-addons "
{"#search-install-button"
{:-fx-min-width "90px"}
{:-fx-min-width "90px"
:-fx-padding ".4em 1em"}

"#search-text-field "
{:-fx-min-width "100px"
:-fx-padding ".4em .5em"
:-fx-background-radius "0"
:-fx-text-fill (colour :table-font-colour)}

"#search-random-button"
{:-fx-min-width "80px"}

"#search-user-catalogue-button"
{:-fx-font-weight "bold"
:-fx-font-size "1.2em"
:-fx-padding "2 7 "
:-fx-padding "3 7 "

".starred" {:-fx-text-fill (colour :star-starred)
;; the yellow of the star doesn't stand out from the gray gradient behind it.
Expand All @@ -527,16 +534,15 @@
:-fx-stroke-width ".2"
:-fx-effect (str "dropshadow( gaussian , " (colour :star-starred) " , 10, 0.0 , 0 , 0 )")}}}

"#search-addon-hosts-list"
{:-fx-pref-height "2em"}

"#search-prev-button"
{:-fx-min-width "80px"}

"#search-next-button"
{:-fx-min-width "70px"}

"#search-text-field "
{:-fx-min-width "100px"
:-fx-text-fill (colour :table-font-colour)}

"#search-selected-tag-bar"
{:-fx-padding "0 0 10 10"
:-fx-spacing "10"
Expand Down Expand Up @@ -2088,6 +2094,7 @@
:title "addon host"
:items known-host-list
:show-checked-count false
:id "search-addon-hosts-list"
:on-checked-items-changed (fn [val]
(cli/search-add-filter :source val))
:disable disable-host-selector?}
Expand All @@ -2097,6 +2104,22 @@
;; :text "random"
;; :on-action (handler cli/random-search)}

{:fx/type :button
:id "search-clear-button"
:text "clear"
:on-action (fn [_]
(when-let [ccb (first (select "#search-addon-hosts-list"))]
(.clearChecks (.getCheckModel ccb)))
(cli/clear-search!))
:disable (let [ss (dissoc search-state :results)
as (dissoc core/-search-state-template :results)]
(if (clojure.string/blank? (:term ss))
;; we use alternating `" "` and `nil` to 'bump' search results.
;; if we have one of those, don't consider the search term.
(= (dissoc ss :term)
(dissoc as :term))
(= ss as)))}

{:fx/type :h-box
:id "spacer"
:h-box/hgrow :ALWAYS}
Expand Down
68 changes: 64 additions & 4 deletions test/strongbox/core_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -1465,18 +1465,78 @@
expected-empty-search-state (assoc core/-search-state-template :term search-term)]
(with-global-fake-routes-in-isolation fake-routes
(with-running-app

;; we have 4 search results to start with
(cli/bump-search)
(Thread/sleep 50) ;; searching happens in the background
(is (= 4 (-> (core/get-state :search) :results first count)))

;; search for 'a'
;; we should have three results:
;; 1. "*A* New Simple Percent"
;; 2. "Skins for *A*ddOns"
;; 3. "Chinchill*a*"
(cli/search search-term)
;; searching happens in the background
(Thread/sleep 50)
;; we have one search result from a catalogue of 4 addons
(is (= 1 (-> (core/get-state :search) :results count)))
(is (= 3 (-> (core/get-state :search) :results first count)))

;; empty the stale search state
(core/empty-search-results)
(Thread/sleep 50)
(is (= expected-empty-search-state (core/get-state :search)))

;; do the search again without specifying a search term
;; we should have three search results again
(cli/bump-search)
(Thread/sleep 50)
(is (= 1 (-> (core/get-state :search) :results count))))))))
(is (= 3 (-> (core/get-state :search) :results first count))))))))

(deftest reset-search-state
(testing "search state can be cleared entirely"
(let [dummy-catalogue (slurp (fixture-path "catalogue--v2.json"))
fake-routes {"https://raw.githubusercontent.com/ogri-la/strongbox-catalogue/master/short-catalogue.json"
{:get (fn [req] {:status 200 :body dummy-catalogue})}}
search-term "a"]
(with-global-fake-routes-in-isolation fake-routes
(with-running-app
(cli/bump-search)

;; we have four results initially
(Thread/sleep 50)
(is (= 4 (-> (core/get-state :search) :results first count)))

;; search for 'a'
;; we should have three results:
;; 1. "*A* New Simple Percent"
;; 2. "Skins for *A*ddOns"
;; 3. "Chinchill*a*"
(cli/search search-term)
(Thread/sleep 50)
(is (= 3 (-> (core/get-state :search) :results first count)))

;; filter by host and we still have one search result
(cli/search-add-filter :source ["curseforge"])
(Thread/sleep 50)
;;(is (= {} (core/get-state :search)))
(is (= 1 (-> (core/get-state :search) :results first count)))
(is (= ["curseforge"] (core/get-state :search :filter-by :source)))

;; filter by tag and we still have one search result
(cli/search-add-filter :tag :unit-frames)
(Thread/sleep 50)
(is (= 1 (-> (core/get-state :search) :results count)))
(is (= #{:unit-frames} (core/get-state :search :filter-by :tag)))

(core/reset-search-state!)
(Thread/sleep 50)

;; we have 4 search results from a catalogue of 4 addons
(is (= 4 (-> (core/get-state :search) :results first count)))

;; and all the filters have been removed
(is (nil? (core/get-state :search :term)))
(is (empty? (core/get-state :search :filter-by :tag)))
(is (nil? (core/get-state :search :filter-by :source))))))))

(deftest -download-strongbox-release
(testing "standard github response for strongbox release data can be parsed and the release version extracted"
Expand Down

0 comments on commit 99b1647

Please sign in to comment.