componentizied input-search and added in curency and token

Signed-off-by: Churikova Tetiana <churikova.tm@gmail.com>
This commit is contained in:
tbenr 2020-02-19 19:18:01 +01:00 committed by Churikova Tetiana
parent 40c12241e0
commit 81c4d16f9f
No known key found for this signature in database
GPG Key ID: 0D4EA7B33B47E6D8
9 changed files with 210 additions and 106 deletions

View File

@ -1241,13 +1241,6 @@
#(when ens-name
(contact/name-verified % public-key ens-name))))))
;; search module
(handlers/register-handler-fx
:search/filter-changed
(fn [cofx [_ search-filter]]
(search/filter-changed cofx search-filter)))
;; pairing module
(handlers/register-handler-fx

View File

@ -1,5 +1,17 @@
(ns status-im.search.core
(:require [status-im.utils.fx :as fx]))
(fx/defn filter-changed [cofx search-filter]
{:db (assoc-in (:db cofx) [:ui/search :filter] search-filter)})
(fx/defn home-filter-changed
{:events [:search/home-filter-changed]}
[cofx search-filter]
{:db (assoc-in (:db cofx) [:ui/search :home-filter] search-filter)})
(fx/defn currency-filter-changed
{:events [:search/currency-filter-changed]}
[cofx search-filter]
{:db (assoc-in (:db cofx) [:ui/search :currency-filter] search-filter)})
(fx/defn token-filter-changed
{:events [:search/token-filter-changed]}
[cofx search-filter]
{:db (assoc-in (:db cofx) [:ui/search :token-filter] search-filter)})

View File

@ -375,10 +375,22 @@
(get-in animations [type item-id :delete-swiped])))
(re-frame/reg-sub
:search/filter
:search/home-filter
:<- [:ui/search]
(fn [search]
(get search :filter)))
(get search :home-filter)))
(re-frame/reg-sub
:search/currency-filter
:<- [:ui/search]
(fn [search]
(get search :currency-filter)))
(re-frame/reg-sub
:search/token-filter
:<- [:ui/search]
(fn [search]
(get search :token-filter)))
(defn- node-version [web3-node-version]
(or web3-node-version "N/A"))
@ -1011,7 +1023,7 @@
(re-frame/reg-sub
:home-items
:<- [:chats/active-chats]
:<- [:search/filter]
:<- [:search/home-filter]
:<- [:search/filtered-chats]
(fn [[chats search-filter filtered-chats]]
(if (or (nil? search-filter)
@ -1828,25 +1840,53 @@
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]
(if (not-empty search-filter)
(let [search-filter (string/lower-case search-filter)
results (filter (fn [element]
(some (fn [s]
(when (string? s)
(string/includes? (string/lower-case s)
search-filter)))
(extract-attributes-fn element)))
coll)]
(sort-by-timestamp results))
(sort-by-timestamp coll)))
[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)))
(re-frame/reg-sub
:search/filtered-chats
:<- [:chats/active-chats]
:<- [:search/filter]
:<- [:search/home-filter]
(fn [[chats search-filter]]
(apply-filter search-filter chats extract-chat-attributes)))
(apply-filter search-filter chats extract-chat-attributes true)))
(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 constants/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)}}))
;; TRIBUTE TO TALK
(re-frame/reg-sub

View File

@ -0,0 +1,27 @@
(ns status-im.ui.components.search-input.styles
(:require [status-im.ui.components.colors :as colors]
[status-im.utils.styles :as styles]))
(styles/def search-input
{:flex 1
:android {:margin 0
:padding 0}})
(def search-input-height 56)
(def search-container
{:height search-input-height
:flex-direction :row
:padding-horizontal 16
:background-color colors/white
:align-items :center
:justify-content :center})
(def search-input-container
{:background-color colors/gray-lighter
:flex 1
:flex-direction :row
:height 36
:align-items :center
:justify-content :center
:border-radius 8})

View File

@ -0,0 +1,52 @@
(ns status-im.ui.components.search-input.view
(:require-macros [status-im.utils.views :as views])
(:require [reagent.core :as reagent]
[status-im.i18n :as i18n]
[status-im.ui.components.react :as react]
[status-im.ui.components.colors :as colors]
[status-im.ui.components.search-input.styles :as styles]
[status-im.ui.components.icons.vector-icons :as icons]))
(views/defview search-input [{:keys [on-cancel
on-focus
on-change
search-active?
search-container-style
search-filter
auto-focus]}]
(views/letsubs
[input-ref (reagent/atom nil)]
[react/view {:style (or search-container-style styles/search-container)}
[react/view {:style styles/search-input-container}
[icons/icon :main-icons/search {:color colors/gray
:container-style {:margin-left 6
:margin-right 2}}]
[react/text-input {:placeholder (i18n/label :t/search)
:blur-on-submit true
:multiline false
:ref #(reset! input-ref %)
:style styles/search-input
:default-value search-filter
:auto-focus auto-focus
:auto-correct false
:auto-capitalize false
:on-focus #(do
(when on-focus
(on-focus search-filter))
(reset! search-active? true))
:on-change (fn [e]
(let [native-event (.-nativeEvent e)
text (.-text native-event)]
(when on-change
(on-change text))))}]]
(when @search-active?
[react/touchable-highlight
{:on-press (fn []
(.clear @input-ref)
(.blur @input-ref)
(when on-cancel
(on-cancel))
(reset! search-active? false))
:style {:margin-left 16}}
[react/text {:style {:color colors/blue}}
(i18n/label :t/cancel)]])]))

View File

@ -1,18 +1,19 @@
(ns status-im.ui.screens.currency-settings.views
(:require-macros [status-im.utils.views :as views])
(:require [re-frame.core :as re-frame]
[status-im.i18n :as i18n]
[reagent.core :as reagent]
[status-im.ui.components.react :as react]
[status-im.ui.components.icons.vector-icons :as vector-icons]
[status-im.ui.components.list.views :as list]
[status-im.ui.components.toolbar.view :as toolbar]
[status-im.ui.screens.profile.components.views :as profile.components]
[status-im.ui.screens.currency-settings.styles :as styles]
[status-im.constants :as constants]
[status-im.ui.components.topbar :as topbar]))
[status-im.ui.components.topbar :as topbar]
[status-im.ui.components.search-input.view :as search-input]))
(defonce search-active? (reagent/atom false))
(defn render-currency [current-currency-id]
(fn [{:keys [id code display-name] :as currency}]
(fn [{:keys [id code display-name]}]
(let [selected? (= id current-currency-id)]
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:wallet.settings.ui/currency-selected id])
@ -24,13 +25,27 @@
[vector-icons/icon :main-icons/check {:color :active}])]])))
(views/defview currency-settings []
(views/letsubs [currency-id [:wallet.settings/currency]]
(views/letsubs [currency-id [:wallet.settings/currency]
{:keys [currencies search-filter]} [:search/filtered-currencies]]
{:component-will-unmount #(do
(re-frame/dispatch [:search/currency-filter-changed nil])
(reset! search-active? false))}
[react/view {:flex 1}
[topbar/topbar {:title :t/main-currency}]
[react/view styles/wrapper
[list/flat-list {:data (->> constants/currencies
[search-input/search-input
{:search-active? search-active?
:search-filter search-filter
:on-cancel #(re-frame/dispatch [:search/currency-filter-changed nil])
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/currency-filter-changed ""])))
:on-change (fn [text]
(re-frame/dispatch [:search/currency-filter-changed text]))}]
[list/flat-list {:data (->> currencies
vals
(sort #(compare (:code %1) (:code %2))))
:key-fn :code
:separator (profile.components/settings-item-separator)
:render-fn (render-currency currency-id)}]]]))
:render-fn (render-currency currency-id)
:keyboardShouldPersistTaps :always}]]]))

View File

@ -1,6 +1,7 @@
(ns status-im.ui.screens.home.styles
(:require [status-im.ui.components.colors :as colors]
[status-im.utils.styles :as styles]
[status-im.ui.components.search-input.styles :as search-input.styles]
[status-im.utils.platform :as platform]))
(defn toolbar []
@ -22,35 +23,14 @@
:color colors/gray
:desktop {:max-height 20}})
(def search-input-height 56)
(def search-container
(merge
{:height search-input-height
:flex-direction :row
:padding-horizontal 16
:background-color colors/white
:align-items :center
:justify-content :center}
search-input.styles/search-container
(when platform/ios?
{:position :absolute
:top (- search-input-height)
:top (- search-input.styles/search-input-height)
:width "100%"})))
(def search-input-container
{:background-color colors/gray-lighter
:flex 1
:flex-direction :row
:height 36
:align-items :center
:justify-content :center
:border-radius 8})
(styles/def search-input
{:flex 1
:android {:margin 0
:padding 0}})
(def filter-section-title
{:margin-left 16
:margin-top 14

View File

@ -18,7 +18,9 @@
[status-im.constants :as constants]
[status-im.ui.components.colors :as colors]
[status-im.ui.screens.add-new.new-public-chat.view :as new-public-chat]
[status-im.ui.components.button :as button])
[status-im.ui.components.button :as button]
[status-im.ui.components.search-input.view :as search-input]
[status-im.ui.components.search-input.styles :as search-input.styles])
(:require-macros [status-im.utils.views :as views]))
(defonce search-active? (reagent/atom false))
@ -91,50 +93,17 @@
[home-tooltip-view])
[react/view {:height 68 :flex 1}]]))
(views/defview search-input [{:keys [on-cancel on-focus on-change]}]
(views/letsubs
[{:keys [search-filter]} [:home-items]
input-ref (reagent/atom nil)]
[react/view {:style styles/search-container}
[react/view {:style styles/search-input-container}
[icons/icon :main-icons/search {:color colors/gray
:container-style {:margin-left 6
:margin-right 2}}]
[react/text-input {:placeholder (i18n/label :t/search)
:blur-on-submit true
:multiline false
:ref #(reset! input-ref %)
:style styles/search-input
:default-value search-filter
:on-focus #(do
(when on-focus
(on-focus search-filter))
(reset! search-active? true))
:on-change (fn [e]
(let [native-event (.-nativeEvent e)
text (.-text native-event)]
(when on-change
(on-change text))))}]]
(when @search-active?
[react/touchable-highlight
{:on-press (fn []
(.clear @input-ref)
(.blur @input-ref)
(when on-cancel
(on-cancel))
(reset! search-active? false))
:style {:margin-left 16}}
[react/text {:style {:color colors/blue}}
(i18n/label :t/cancel)]])]))
(defn search-input-wrapper []
[search-input
{:on-cancel #(re-frame/dispatch [:search/filter-changed nil])
(defn search-input-wrapper [search-filter]
[search-input/search-input
{:search-active? search-active?
:search-container-style styles/search-container
:search-filter search-filter
:on-cancel #(re-frame/dispatch [:search/home-filter-changed nil])
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/filter-changed ""])))
(re-frame/dispatch [:search/home-filter-changed ""])))
:on-change (fn [text]
(re-frame/dispatch [:search/filter-changed text]))}])
(re-frame/dispatch [:search/home-filter-changed text]))}])
(defn section-footer [{:keys [title data]}]
(when (and @search-active? (empty? data))
@ -151,7 +120,7 @@
(views/defview home-filtered-items-list []
(views/letsubs
[{:keys [chats all-home-items]} [:home-items]
[{:keys [chats all-home-items search-filter]} [:home-items]
{:keys [hide-home-tooltip?]} [:multiaccount]]
(let [list-ref (reagent/atom nil)]
[list/section-list
@ -164,19 +133,19 @@
:keyboard-should-persist-taps :always
:ref #(reset! list-ref %)
:footer [chat-list-footer hide-home-tooltip?]
:contentInset {:top styles/search-input-height}
:contentInset {:top search-input.styles/search-input-height}
:render-section-header-fn (fn [data] [react/view])
:render-section-footer-fn section-footer
:render-fn (fn [home-item]
[inner-item/home-list-item home-item])
:header (when (or @search-active? (not-empty all-home-items))
[search-input-wrapper])
[search-input-wrapper search-filter])
:on-scroll-end-drag
(fn [e]
(let [y (-> e .-nativeEvent .-contentOffset .-y)
hide-searchbar? (cond
platform/ios? (and (neg? y) (> y (- (/ styles/search-input-height 2))))
platform/android? (and (< y styles/search-input-height) (> y (/ styles/search-input-height 2))))]
platform/ios? (and (neg? y) (> y (- (/ search-input.styles/search-input-height 2))))
platform/android? (and (< y search-input.styles/search-input-height) (> y (/ search-input.styles/search-input-height 2))))]
(if hide-searchbar?
(.scrollToLocation @list-ref #js {:sectionIndex 0 :itemIndex 0}))))})])))

View File

@ -7,9 +7,12 @@
[status-im.ui.components.styles :as components.styles]
[status-im.ui.components.list-item.views :as list-item]
[reagent.core :as reagent]
[status-im.ui.components.topbar :as topbar])
[status-im.ui.components.topbar :as topbar]
[status-im.ui.components.search-input.view :as search-input])
(:require-macros [status-im.utils.views :refer [defview letsubs]]))
(defonce search-active? (reagent/atom false))
(defn toolbar []
[topbar/topbar
{:title :t/wallet-assets
@ -70,10 +73,23 @@
[render-token token])
(defview manage-assets []
(letsubs [{custom-tokens true default-tokens nil} [:wallet/grouped-chain-tokens]]
(letsubs [{search-filter :search-filter
{custom-tokens true default-tokens nil} :tokens} [:wallet/filtered-grouped-chain-tokens]]
{:component-will-unmount #(do
(re-frame/dispatch [:search/token-filter-changed nil])
(reset! search-active? false))}
[react/view (merge components.styles/flex {:background-color :white})
[toolbar]
[react/view {:style components.styles/flex}
[search-input/search-input
{:search-active? search-active?
:search-filter search-filter
:on-cancel #(re-frame/dispatch [:search/token-filter-changed nil])
:on-focus (fn [search-filter]
(when-not search-filter
(re-frame/dispatch [:search/token-filter-changed ""])))
:on-change (fn [text]
(re-frame/dispatch [:search/token-filter-changed text]))}]
[list/section-list
{:header
[react/view {:margin-top 16}