new searchbar design
Signed-off-by: Volodymyr Kozieiev <vkjr.sp@gmail.com>
This commit is contained in:
parent
fb9ea6529f
commit
f3df8b2ec8
|
@ -441,6 +441,7 @@ var TopLevel = {
|
||||||
"scrollTo" : function () {},
|
"scrollTo" : function () {},
|
||||||
"scrollToEnd" : function () {},
|
"scrollToEnd" : function () {},
|
||||||
"scrollToIndex" : function () {},
|
"scrollToIndex" : function () {},
|
||||||
|
"scrollToLocation" : function () {},
|
||||||
"section" : function () {},
|
"section" : function () {},
|
||||||
"selection" : function () {},
|
"selection" : function () {},
|
||||||
"sendDirectMessage" : function () {},
|
"sendDirectMessage" : function () {},
|
||||||
|
|
|
@ -1784,15 +1784,21 @@
|
||||||
(let [{:keys [name random-name tags]} (val chat)]
|
(let [{:keys [name random-name tags]} (val chat)]
|
||||||
(into [name random-name] tags)))
|
(into [name random-name] tags)))
|
||||||
|
|
||||||
|
(defn sort-by-timestamp
|
||||||
|
[coll]
|
||||||
|
(when (not-empty coll)
|
||||||
|
(sort-by #(-> % second :timestamp) >
|
||||||
|
(into {} coll))))
|
||||||
|
|
||||||
(defn apply-filter
|
(defn apply-filter
|
||||||
"extract-attributes-fn is a function that take an element from the collection
|
"extract-attributes-fn is a function that take an element from the collection
|
||||||
and returns a vector of attributes which are strings
|
and returns a vector of attributes which are strings
|
||||||
apply-filter returns the elements for which at least one attribute includes
|
apply-filter returns the elements for which at least one attribute includes
|
||||||
the search-filter
|
the search-filter
|
||||||
apply-filter returns nil if the search-filter is empty or if there is no element
|
apply-filter returns nil if there is no element that match the filter
|
||||||
that match the filter"
|
apply-filter returns full collection if the search-filter is empty"
|
||||||
[search-filter coll extract-attributes-fn]
|
[search-filter coll extract-attributes-fn]
|
||||||
(when (not-empty search-filter)
|
(if (not-empty search-filter)
|
||||||
(let [search-filter (string/lower-case search-filter)
|
(let [search-filter (string/lower-case search-filter)
|
||||||
results (filter (fn [element]
|
results (filter (fn [element]
|
||||||
(some (fn [s]
|
(some (fn [s]
|
||||||
|
@ -1801,9 +1807,8 @@
|
||||||
search-filter)))
|
search-filter)))
|
||||||
(extract-attributes-fn element)))
|
(extract-attributes-fn element)))
|
||||||
coll)]
|
coll)]
|
||||||
(when (not-empty results)
|
(sort-by-timestamp results))
|
||||||
(sort-by #(-> % second :timestamp) >
|
(sort-by-timestamp coll)))
|
||||||
(into {} results))))))
|
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:search/filtered-chats
|
:search/filtered-chats
|
||||||
|
|
|
@ -190,12 +190,14 @@
|
||||||
(defn- base-list-props
|
(defn- base-list-props
|
||||||
[{:keys [key-fn render-fn empty-component header footer separator default-separator?]}]
|
[{:keys [key-fn render-fn empty-component header footer separator default-separator?]}]
|
||||||
(let [separator (or separator (when (and platform/ios? default-separator?) default-separator))]
|
(let [separator (or separator (when (and platform/ios? default-separator?) default-separator))]
|
||||||
(merge (when key-fn {:keyExtractor (wrap-key-fn key-fn)})
|
(merge (when key-fn {:keyExtractor (wrap-key-fn key-fn)})
|
||||||
(when render-fn {:renderItem (wrap-render-fn render-fn)})
|
(when render-fn {:renderItem (wrap-render-fn render-fn)})
|
||||||
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
|
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
|
||||||
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
|
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
|
||||||
(when header {:ListHeaderComponent (fn [] (reagent/as-element header))})
|
;; header and footer not wrapped in anonymous function to prevent re-creation on every re-render
|
||||||
(when footer {:ListFooterComponent (fn [] (reagent/as-element footer))}))))
|
;; More details can be found here - https://github.com/facebook/react-native/issues/13602#issuecomment-300608431
|
||||||
|
(when header {:ListHeaderComponent (reagent/as-element header)})
|
||||||
|
(when footer {:ListFooterComponent (reagent/as-element footer)}))))
|
||||||
|
|
||||||
;; Workaround an issue in reagent that does not consider JS array as JS value
|
;; Workaround an issue in reagent that does not consider JS array as JS value
|
||||||
;; This forces clj <-> js serialization and breaks clj semantic
|
;; This forces clj <-> js serialization and breaks clj semantic
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
(ns status-im.ui.screens.home.filter.views
|
|
||||||
(:require [status-im.ui.components.list.views :as list]
|
|
||||||
[status-im.ui.screens.home.styles :as styles]
|
|
||||||
[status-im.ui.components.react :as react]
|
|
||||||
[status-im.i18n :as i18n]
|
|
||||||
[status-im.ui.components.colors :as colors]
|
|
||||||
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
|
||||||
[status-im.utils.utils :as utils]
|
|
||||||
[status-im.ui.components.animation :as animation]
|
|
||||||
[reagent.core :as reagent]
|
|
||||||
[re-frame.core :as re-frame]
|
|
||||||
[status-im.ui.components.icons.vector-icons :as icons]))
|
|
||||||
|
|
||||||
(def animation-duration 150)
|
|
||||||
|
|
||||||
(defn search-input [_ {:keys [on-cancel on-focus on-change]}]
|
|
||||||
(let [input-is-focused? (reagent/atom false)
|
|
||||||
input-ref (reagent/atom nil)]
|
|
||||||
(fn [search-filter]
|
|
||||||
(let [show-cancel? (or @input-is-focused?
|
|
||||||
search-filter)]
|
|
||||||
[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! input-is-focused? true))
|
|
||||||
:on-change (fn [e]
|
|
||||||
(let [native-event (.-nativeEvent e)
|
|
||||||
text (.-text native-event)]
|
|
||||||
(when on-change
|
|
||||||
(on-change text))))}]]
|
|
||||||
(when show-cancel?
|
|
||||||
[react/touchable-highlight
|
|
||||||
{:on-press #(do
|
|
||||||
(when on-cancel
|
|
||||||
(on-cancel))
|
|
||||||
(.blur @input-ref)
|
|
||||||
(reset! input-is-focused? false))
|
|
||||||
:style {:margin-left 16}}
|
|
||||||
[react/text {:style {:color colors/blue}}
|
|
||||||
(i18n/label :t/cancel)]])]))))
|
|
||||||
|
|
||||||
(defonce search-input-state
|
|
||||||
(reagent/atom {:show? false
|
|
||||||
:height (animation/create-value
|
|
||||||
(- styles/search-input-height))
|
|
||||||
:to-hide? false}))
|
|
||||||
|
|
||||||
(defn show-search!
|
|
||||||
[]
|
|
||||||
(when-not (:to-hide? @search-input-state)
|
|
||||||
(swap! search-input-state assoc :show? true)
|
|
||||||
(animation/start
|
|
||||||
(animation/timing (:height @search-input-state)
|
|
||||||
{:toValue 0
|
|
||||||
:duration animation-duration
|
|
||||||
:easing (.out (animation/easing)
|
|
||||||
(.-quad (animation/easing)))
|
|
||||||
:useNativeDriver true})
|
|
||||||
#(swap! search-input-state assoc :to-hide? true))))
|
|
||||||
|
|
||||||
(defn update-search-state!
|
|
||||||
[]
|
|
||||||
(let [visible? (:to-hide? @search-input-state)]
|
|
||||||
(swap! search-input-state assoc :show? visible?)
|
|
||||||
(animation/set-value (:height @search-input-state)
|
|
||||||
(if visible? 0 (- styles/search-input-height)))))
|
|
||||||
|
|
||||||
(defn hide-search!
|
|
||||||
[]
|
|
||||||
(utils/set-timeout
|
|
||||||
#(swap! search-input-state assoc :show? false)
|
|
||||||
350)
|
|
||||||
(animation/start
|
|
||||||
(animation/timing (:height @search-input-state)
|
|
||||||
{:toValue (- styles/search-input-height)
|
|
||||||
:duration animation-duration
|
|
||||||
:easing (.in (animation/easing)
|
|
||||||
(.-quad (animation/easing)))
|
|
||||||
:useNativeDriver true})
|
|
||||||
#(swap! search-input-state assoc :to-hide? false)))
|
|
||||||
|
|
||||||
(defn search-input-wrapper
|
|
||||||
[search-filter]
|
|
||||||
(reagent/create-class
|
|
||||||
{:component-will-unmount
|
|
||||||
#(update-search-state!)
|
|
||||||
:component-did-mount
|
|
||||||
#(update-search-state!)
|
|
||||||
:reagent-render
|
|
||||||
(fn [search-filter]
|
|
||||||
[search-input search-filter
|
|
||||||
{:on-cancel #(do
|
|
||||||
(re-frame/dispatch [:search/filter-changed nil])
|
|
||||||
(hide-search!))
|
|
||||||
:on-focus (fn [search-filter]
|
|
||||||
(when-not search-filter
|
|
||||||
(re-frame/dispatch [:search/filter-changed ""])))
|
|
||||||
:on-change (fn [text]
|
|
||||||
(re-frame/dispatch [:search/filter-changed text]))}])}))
|
|
||||||
|
|
||||||
(defn home-filtered-items-list
|
|
||||||
[chats]
|
|
||||||
[list/section-list
|
|
||||||
{:style {:margin-bottom -35}
|
|
||||||
:sections [{:title :t/chats
|
|
||||||
:data chats}]
|
|
||||||
:key-fn first
|
|
||||||
;; true by default on iOS
|
|
||||||
:stickySectionHeadersEnabled false
|
|
||||||
:render-section-header-fn
|
|
||||||
(fn [{:keys [title data]}]
|
|
||||||
[react/view {:style {:height 40}}
|
|
||||||
[react/text {:style styles/filter-section-title}
|
|
||||||
(i18n/label title)]])
|
|
||||||
:render-section-footer-fn
|
|
||||||
(fn [{:keys [title data]}]
|
|
||||||
(when (empty? data)
|
|
||||||
[list/big-list-item
|
|
||||||
{:text (i18n/label :t/no-result)
|
|
||||||
:text-color colors/gray
|
|
||||||
:hide-chevron? true
|
|
||||||
:action-fn #()
|
|
||||||
:icon (case title
|
|
||||||
"messages" :main-icons/one-on-one-chat
|
|
||||||
"browser" :main-icons/browser
|
|
||||||
"chats" :main-icons/message)
|
|
||||||
:icon-color colors/gray}]))
|
|
||||||
:render-fn (fn [home-item]
|
|
||||||
[inner-item/home-list-item home-item])}])
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.ui.screens.home.styles
|
(ns status-im.ui.screens.home.styles
|
||||||
(:require [status-im.ui.components.colors :as colors]
|
(:require [status-im.ui.components.colors :as colors]
|
||||||
[status-im.utils.styles :as styles]))
|
[status-im.utils.styles :as styles]
|
||||||
|
[status-im.utils.platform :as platform]))
|
||||||
|
|
||||||
(defn toolbar []
|
(defn toolbar []
|
||||||
{:background-color colors/white})
|
{:background-color colors/white})
|
||||||
|
@ -24,12 +25,17 @@
|
||||||
(def search-input-height 56)
|
(def search-input-height 56)
|
||||||
|
|
||||||
(def search-container
|
(def search-container
|
||||||
{:height search-input-height
|
(merge
|
||||||
:flex-direction :row
|
{:height search-input-height
|
||||||
:padding-horizontal 16
|
:flex-direction :row
|
||||||
:background-color colors/white
|
:padding-horizontal 16
|
||||||
:align-items :center
|
:background-color colors/white
|
||||||
:justify-content :center})
|
:align-items :center
|
||||||
|
:justify-content :center}
|
||||||
|
(when platform/ios?
|
||||||
|
{:position :absolute
|
||||||
|
:top (- search-input-height)
|
||||||
|
:width "100%"})))
|
||||||
|
|
||||||
(def search-input-container
|
(def search-input-container
|
||||||
{:background-color colors/gray-lighter
|
{:background-color colors/gray-lighter
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
[status-im.ui.components.react :as react]
|
[status-im.ui.components.react :as react]
|
||||||
[status-im.ui.components.toolbar.view :as toolbar]
|
[status-im.ui.components.toolbar.view :as toolbar]
|
||||||
[status-im.ui.screens.home.styles :as styles]
|
[status-im.ui.screens.home.styles :as styles]
|
||||||
[status-im.ui.screens.home.filter.views :as filter.views]
|
|
||||||
[status-im.utils.platform :as platform]
|
[status-im.utils.platform :as platform]
|
||||||
[status-im.ui.components.tabbar.styles :as tabs.styles]
|
[status-im.ui.components.tabbar.styles :as tabs.styles]
|
||||||
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
[status-im.ui.screens.home.views.inner-item :as inner-item]
|
||||||
|
@ -23,6 +22,8 @@
|
||||||
[status-im.ui.components.button :as button])
|
[status-im.ui.components.button :as button])
|
||||||
(:require-macros [status-im.utils.views :as views]))
|
(:require-macros [status-im.utils.views :as views]))
|
||||||
|
|
||||||
|
(defonce search-active? (reagent/atom false))
|
||||||
|
|
||||||
(defn welcome-video-wrapper []
|
(defn welcome-video-wrapper []
|
||||||
[react/view {:style {:align-items :center
|
[react/view {:style {:align-items :center
|
||||||
:justify-content :center
|
:justify-content :center
|
||||||
|
@ -85,45 +86,101 @@
|
||||||
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}}
|
[react/view {:style {:flex 1 :flex-direction :row :align-items :center :justify-content :center}}
|
||||||
[react/i18n-text {:style styles/welcome-blank-text :key :welcome-blank-message}]])
|
[react/i18n-text {:style styles/welcome-blank-text :key :welcome-blank-message}]])
|
||||||
|
|
||||||
(defn home-items-view [_ _ _ _ search-input-state]
|
(defn chat-list-footer [hide-home-tooltip?]
|
||||||
(let [analyze-pos? (reagent/atom true)
|
(let [show-tooltip? (and (not hide-home-tooltip?) (not @search-active?))]
|
||||||
start-pos (reagent/atom 0)]
|
[react/view
|
||||||
(fn [search-filter chats all-home-items hide-home-tooltip?]
|
(when show-tooltip?
|
||||||
(if search-filter
|
[home-tooltip-view])
|
||||||
[filter.views/home-filtered-items-list chats]
|
[react/view {:height 68 :flex 1}]]))
|
||||||
[react/animated-view
|
|
||||||
{:style {:flex 1
|
(views/defview search-input [{:keys [on-cancel on-focus on-change]}]
|
||||||
:background-color :white
|
(views/letsubs
|
||||||
:margin-bottom (- styles/search-input-height)
|
[{:keys [search-filter]} [:home-items]
|
||||||
:transform [{:translateY (:height @search-input-state)}]}}
|
input-ref (reagent/atom nil)]
|
||||||
(if (or (seq all-home-items) (not hide-home-tooltip?))
|
[react/view {:style styles/search-container}
|
||||||
[list/flat-list (merge {:data all-home-items
|
[react/view {:style styles/search-input-container}
|
||||||
:key-fn first
|
[icons/icon :main-icons/search {:color colors/gray
|
||||||
:header [react/view {:height 4 :flex 1}]
|
:container-style {:margin-left 6
|
||||||
:footer [react/view
|
:margin-right 2}}]
|
||||||
(when-not hide-home-tooltip?
|
[react/text-input {:placeholder (i18n/label :t/search)
|
||||||
[home-tooltip-view])
|
:blur-on-submit true
|
||||||
[react/view {:height 68 :flex 1}]]
|
:multiline false
|
||||||
:on-scroll-begin-drag
|
:ref #(reset! input-ref %)
|
||||||
(fn [e]
|
:style styles/search-input
|
||||||
(reset! analyze-pos? true)
|
:default-value search-filter
|
||||||
(reset! start-pos (.-y (.-contentOffset (.-nativeEvent e)))))
|
:on-focus #(do
|
||||||
:on-scroll-end-drag
|
(when on-focus
|
||||||
(fn [e]
|
(on-focus search-filter))
|
||||||
(reset! analyze-pos? false))
|
(reset! search-active? true))
|
||||||
:on-scroll
|
:on-change (fn [e]
|
||||||
(fn [e]
|
(let [native-event (.-nativeEvent e)
|
||||||
(let [y-pos (.-y (.-contentOffset (.-nativeEvent e)))
|
text (.-text native-event)]
|
||||||
scroling-down? (> y-pos @start-pos)
|
(when on-change
|
||||||
scrolling-up-from-top? (< y-pos -20)]
|
(on-change text))))}]]
|
||||||
(if (and @analyze-pos? scrolling-up-from-top?)
|
(when @search-active?
|
||||||
(filter.views/show-search!))
|
[react/touchable-highlight
|
||||||
(if (and @analyze-pos? scroling-down?)
|
{:on-press (fn []
|
||||||
(filter.views/hide-search!))))
|
(.clear @input-ref)
|
||||||
:render-fn
|
(.blur @input-ref)
|
||||||
(fn [home-item _]
|
(when on-cancel
|
||||||
[inner-item/home-list-item home-item])})]
|
(on-cancel))
|
||||||
[welcome-blank-page])]))))
|
(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])
|
||||||
|
:on-focus (fn [search-filter]
|
||||||
|
(when-not search-filter
|
||||||
|
(re-frame/dispatch [:search/filter-changed ""])))
|
||||||
|
:on-change (fn [text]
|
||||||
|
(re-frame/dispatch [:search/filter-changed text]))}])
|
||||||
|
|
||||||
|
(defn section-footer [{:keys [title data]}]
|
||||||
|
(when (and @search-active? (empty? data))
|
||||||
|
[list/big-list-item
|
||||||
|
{:text (i18n/label :t/no-result)
|
||||||
|
:text-color colors/gray
|
||||||
|
:hide-chevron? true
|
||||||
|
:action-fn #()
|
||||||
|
:icon (case title
|
||||||
|
"messages" :main-icons/one-on-one-chat
|
||||||
|
"browser" :main-icons/browser
|
||||||
|
"chats" :main-icons/message)
|
||||||
|
:icon-color colors/gray}]))
|
||||||
|
|
||||||
|
(views/defview home-filtered-items-list []
|
||||||
|
(views/letsubs
|
||||||
|
[{:keys [chats all-home-items]} [:home-items]
|
||||||
|
{:keys [hide-home-tooltip?]} [:multiaccount]]
|
||||||
|
(let [list-ref (reagent/atom nil)]
|
||||||
|
[list/section-list
|
||||||
|
(merge
|
||||||
|
{:sections [{:title :t/chats
|
||||||
|
:data (if @search-active? chats all-home-items)}]
|
||||||
|
:key-fn first
|
||||||
|
;; true by default on iOS
|
||||||
|
:stickySectionHeadersEnabled false
|
||||||
|
:keyboard-should-persist-taps :always
|
||||||
|
:ref #(reset! list-ref %)
|
||||||
|
:footer [chat-list-footer hide-home-tooltip?]
|
||||||
|
:contentInset {:top 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])
|
||||||
|
: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))))]
|
||||||
|
(if hide-searchbar?
|
||||||
|
(.scrollToLocation @list-ref #js {:sectionIndex 0 :itemIndex 0}))))})])))
|
||||||
|
|
||||||
(views/defview home-action-button [home-width]
|
(views/defview home-action-button [home-width]
|
||||||
(views/letsubs [logging-in? [:multiaccounts/login]]
|
(views/letsubs [logging-in? [:multiaccounts/login]]
|
||||||
|
@ -139,7 +196,7 @@
|
||||||
(views/defview home [loading?]
|
(views/defview home [loading?]
|
||||||
(views/letsubs
|
(views/letsubs
|
||||||
[anim-translate-y (animation/create-value connectivity/neg-connectivity-bar-height)
|
[anim-translate-y (animation/create-value connectivity/neg-connectivity-bar-height)
|
||||||
{:keys [search-filter chats all-home-items]} [:home-items]
|
{:keys [all-home-items]} [:home-items]
|
||||||
{:keys [hide-home-tooltip?]} [:multiaccount]
|
{:keys [hide-home-tooltip?]} [:multiaccount]
|
||||||
window-width [:dimensions/window-width]
|
window-width [:dimensions/window-width]
|
||||||
two-pane-ui-enabled? [:two-pane-ui-enabled?]]
|
two-pane-ui-enabled? [:two-pane-ui-enabled?]]
|
||||||
|
@ -172,13 +229,9 @@
|
||||||
[react/activity-indicator {:flex 1
|
[react/activity-indicator {:flex 1
|
||||||
:animating true}]
|
:animating true}]
|
||||||
[react/view {:flex 1}
|
[react/view {:flex 1}
|
||||||
[filter.views/search-input-wrapper search-filter]
|
(if (and (empty? all-home-items) hide-home-tooltip? (not @search-active?))
|
||||||
[home-items-view
|
[welcome-blank-page]
|
||||||
search-filter
|
[home-filtered-items-list])])]
|
||||||
chats
|
|
||||||
all-home-items
|
|
||||||
hide-home-tooltip?
|
|
||||||
filter.views/search-input-state]])]
|
|
||||||
[home-action-button home-width]]])))
|
[home-action-button home-width]]])))
|
||||||
|
|
||||||
(views/defview home-wrapper []
|
(views/defview home-wrapper []
|
||||||
|
|
|
@ -83,6 +83,7 @@
|
||||||
tribute-label))
|
tribute-label))
|
||||||
:subtitle-row-accessory [unviewed-indicator chat-id]
|
:subtitle-row-accessory [unviewed-indicator chat-id]
|
||||||
:on-press #(do
|
:on-press #(do
|
||||||
|
(re-frame/dispatch [:dismiss-keyboard])
|
||||||
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])
|
(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])
|
||||||
(re-frame/dispatch [:chat.ui/mark-messages-seen :chat]))
|
(re-frame/dispatch [:chat.ui/mark-messages-seen :chat]))
|
||||||
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet chat-actions {:chat-id chat-id}])}]))
|
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet chat-actions {:chat-id chat-id}])}]))
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
:random-name "random-name4"
|
:random-name "random-name4"
|
||||||
:tags #{"tag4"}}}]
|
:tags #{"tag4"}}}]
|
||||||
(testing "no search filter"
|
(testing "no search filter"
|
||||||
(is (= 0
|
(is (= (count chats)
|
||||||
(count (search.subs/apply-filter ""
|
(count (search.subs/apply-filter ""
|
||||||
chats
|
chats
|
||||||
search.subs/extract-chat-attributes)))))
|
search.subs/extract-chat-attributes)))))
|
||||||
|
|
Loading…
Reference in New Issue