status-react/src/status_im2/subs/search.cljs

95 lines
3.8 KiB
Clojure

(ns status-im2.subs.search
(:require [clojure.string :as string])
(:require [clojure.string :as string]
[status-im.utils.gfycat.core :as gfycat]
[re-frame.core :as re-frame]
[status-im.utils.currency :as currency]))
(defn sort-by-timestamp
[coll]
(when (not-empty coll)
(sort-by #(-> % second :timestamp) >
(into {} coll))))
(defn apply-filter
"extract-attributes-fn is a function that take an element from the collection
and returns a vector of attributes which are strings
apply-filter returns the elements for which at least one attribute includes
the search-filter
apply-filter returns nil if there is no element that match the filter
apply-filter returns full collection if the search-filter is empty"
[search-filter coll extract-attributes-fn sort?]
(let [results (if (not-empty search-filter)
(let [search-filter (string/lower-case search-filter)]
(filter (fn [element]
(some (fn [v]
(let [s (cond (string? v) v
(keyword? v) (name v))]
(when (string? s)
(string/includes? (string/lower-case s)
search-filter))))
(extract-attributes-fn element)))
coll))
coll)]
(if sort?
(sort-by-timestamp results)
results)))
(defn filter-chat
[contacts search-filter {:keys [group-chat alias name chat-id]}]
(let [alias (if-not group-chat
(string/lower-case (or alias
(get-in contacts [chat-id :alias])
(gfycat/generate-gfy chat-id)))
"")
nickname (get-in contacts [chat-id :nickname])]
(or
(string/includes? (string/lower-case (str name)) search-filter)
(string/includes? (string/lower-case alias) search-filter)
(when nickname
(string/includes? (string/lower-case nickname) search-filter))
(and
(get-in contacts [chat-id :ens-verified])
(string/includes? (string/lower-case
(str (get-in contacts [chat-id :name])))
search-filter)))))
(re-frame/reg-sub
:search/filtered-chats
:<- [:chats/home-list-chats]
:<- [:contacts/contacts]
:<- [:search/home-filter]
(fn [[chats contacts search-filter]]
;; Short-circuit if search-filter is empty
(let [filtered-chats (if (seq search-filter)
(filter
(partial filter-chat
contacts
(string/lower-case search-filter))
chats)
chats)]
(sort-by :timestamp > filtered-chats))))
(defn extract-currency-attributes [currency]
(let [{:keys [code display-name]} (val currency)]
[code display-name]))
(re-frame/reg-sub
:search/filtered-currencies
:<- [:search/currency-filter]
(fn [search-currency-filter]
{:search-filter search-currency-filter
:currencies (apply-filter search-currency-filter currency/currencies extract-currency-attributes false)}))
(defn extract-token-attributes [token]
(let [{:keys [symbol name]} token]
[symbol name]))
(re-frame/reg-sub
:wallet/filtered-grouped-chain-tokens
:<- [:wallet/grouped-chain-tokens]
:<- [:search/token-filter]
(fn [[{custom-tokens true default-tokens nil} search-token-filter]]
{:search-filter search-token-filter
:tokens {true (apply-filter search-token-filter custom-tokens extract-token-attributes false)
nil (apply-filter search-token-filter default-tokens extract-token-attributes false)}}))