mirror of
https://github.com/status-im/status-mobile.git
synced 2025-01-13 18:25:45 +00:00
[desktop] Add search feature for chat list
Signed-off-by: yenda <eric@status.im>
This commit is contained in:
parent
14ef386f2e
commit
82c3997f07
@ -8,7 +8,8 @@
|
||||
[status-im.utils.platform :as platform]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.i18n :as i18n]
|
||||
[status-im.models.transactions :as transactions]))
|
||||
[status-im.models.transactions :as transactions]
|
||||
[clojure.set :as clojure.set]))
|
||||
|
||||
(reg-sub :get-chats :chats)
|
||||
|
||||
@ -75,11 +76,19 @@
|
||||
platform/ios? kb-height
|
||||
:default 0)))
|
||||
|
||||
(defn active-chats [chats]
|
||||
(into {} (filter (comp :is-active second) chats)))
|
||||
(defn active-chats [[contacts chats]]
|
||||
(reduce (fn [acc [chat-id {:keys [is-active] :as chat}]]
|
||||
(if is-active
|
||||
(assoc acc chat-id (if-let [contact (get contacts chat-id)]
|
||||
(update chat :tags clojure.set/union (:tags contact))
|
||||
chat))
|
||||
acc))
|
||||
{}
|
||||
chats))
|
||||
|
||||
(reg-sub
|
||||
:get-active-chats
|
||||
:<- [:get-contacts]
|
||||
:<- [:get-chats]
|
||||
active-chats)
|
||||
|
||||
|
@ -67,14 +67,16 @@
|
||||
(add-new-contact contact)
|
||||
(send-contact-request contact))))
|
||||
|
||||
(fx/defn add-contact-tag
|
||||
(fx/defn add-tag
|
||||
"add a tag to the contact"
|
||||
[{:keys [db] :as cofx} whisper-id tag]
|
||||
(let [tags (conj (get-in db [:contacts/contacts whisper-id :tags] #{}) tag)]
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [tag (get-in db [:ui/contact :contact/new-tag])
|
||||
whisper-id (get-in db [:current-chat-id])
|
||||
tags (conj (get-in db [:contacts/contacts whisper-id :tags] #{}) tag)]
|
||||
{:db (assoc-in db [:contacts/contacts whisper-id :tags] tags)
|
||||
:data-store/tx [(contacts-store/add-contact-tag-tx whisper-id tag)]}))
|
||||
|
||||
(fx/defn remove-contact-tag
|
||||
(fx/defn remove-tag
|
||||
"remove a tag from the contact"
|
||||
[{:keys [db] :as cofx} whisper-id tag]
|
||||
(let [tags (disj (get-in db [:contacts/contacts whisper-id :tags] #{}) tag)]
|
||||
|
@ -36,32 +36,30 @@
|
||||
(spec/def :contact/debug? boolean?)
|
||||
(spec/def :contact/tags (spec/coll-of string? :kind set?))
|
||||
|
||||
(spec/def :contact/contact
|
||||
(allowed-keys
|
||||
:req-un [:contact/name]
|
||||
:opt-un [:contact/whisper-identity
|
||||
:contact/address
|
||||
:contact/public-key
|
||||
:contact/photo-path
|
||||
:contact/status
|
||||
:contact/last-updated
|
||||
:contact/last-online
|
||||
:contact/pending?
|
||||
:contact/hide-contact?
|
||||
:contact/unremovable?
|
||||
:contact/dapp?
|
||||
:contact/dapp-url
|
||||
:contact/dapp-hash
|
||||
:contact/bot-url
|
||||
:contact/jail-loaded?
|
||||
:contact/jail-loaded-events
|
||||
:contact/command
|
||||
:contact/response
|
||||
:contact/debug?
|
||||
:contact/subscriptions
|
||||
:contact/fcm-token
|
||||
:contact/description
|
||||
:contact/tags]))
|
||||
(spec/def :contact/contact (spec/keys :req-un [:contact/name]
|
||||
:opt-un [:contact/whisper-identity
|
||||
:contact/address
|
||||
:contact/public-key
|
||||
:contact/photo-path
|
||||
:contact/status
|
||||
:contact/last-updated
|
||||
:contact/last-online
|
||||
:contact/pending?
|
||||
:contact/hide-contact?
|
||||
:contact/unremovable?
|
||||
:contact/dapp?
|
||||
:contact/dapp-url
|
||||
:contact/dapp-hash
|
||||
:contact/bot-url
|
||||
:contact/jail-loaded?
|
||||
:contact/jail-loaded-events
|
||||
:contact/command
|
||||
:contact/response
|
||||
:contact/debug?
|
||||
:contact/subscriptions
|
||||
:contact/fcm-token
|
||||
:contact/description
|
||||
:contact/tags]))
|
||||
|
||||
;;Contact list ui props
|
||||
(spec/def :contact-list-ui/edit? boolean?)
|
||||
@ -83,3 +81,6 @@
|
||||
(spec/def :contacts/click-action (spec/nilable #{:send :request}))
|
||||
;;used in modal list (for example for wallet)
|
||||
(spec/def :contacts/click-params (spec/nilable map?))
|
||||
|
||||
(spec/def :contact/new-tag string?)
|
||||
(spec/def :ui/contact (spec/keys :opt [:contact/new-tag]))
|
||||
|
@ -30,6 +30,7 @@
|
||||
[status-im.privacy-policy.core :as privacy-policy]
|
||||
[status-im.protocol.core :as protocol]
|
||||
[status-im.qr-scanner.core :as qr-scanner]
|
||||
[status-im.search.core :as search]
|
||||
[status-im.signals.core :as signals]
|
||||
[status-im.transport.inbox :as inbox]
|
||||
[status-im.transport.message.core :as transport.message]
|
||||
@ -1073,3 +1074,20 @@
|
||||
[(re-frame/inject-cofx :random-id-generator)]
|
||||
(fn [cofx _]
|
||||
(contact/add-new-identity-to-contacts cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:contact.ui/add-tag
|
||||
(fn [cofx _]
|
||||
(contact/add-tag cofx)))
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:contact.ui/set-tag-input-field
|
||||
(fn [cofx [_ text]]
|
||||
{:db (assoc-in (:db cofx) [:ui/contact :contact/new-tag] text)}))
|
||||
|
||||
;; search module
|
||||
|
||||
(handlers/register-handler-fx
|
||||
:search/filter-changed
|
||||
(fn [cofx [_ search-filter]]
|
||||
(search/filter-changed cofx search-filter)))
|
||||
|
5
src/status_im/search/core.cljs
Normal file
5
src/status_im/search/core.cljs
Normal file
@ -0,0 +1,5 @@
|
||||
(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)})
|
28
src/status_im/search/subs.cljs
Normal file
28
src/status_im/search/subs.cljs
Normal file
@ -0,0 +1,28 @@
|
||||
(ns status-im.search.subs
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as re-frame]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:search/filter
|
||||
(fn [db]
|
||||
(get-in db [:ui/search :filter] "")))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:search/filtered-active-chats
|
||||
:<- [:get-active-chats]
|
||||
:<- [:search/filter]
|
||||
(fn [[chats tag-filter]]
|
||||
(if (empty? tag-filter)
|
||||
chats
|
||||
(keep #(when (some (fn [tag]
|
||||
(string/includes? (string/lower-case tag)
|
||||
(string/lower-case tag-filter)))
|
||||
(into [(:name (val %))] (:tags (val %))))
|
||||
%)
|
||||
chats))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:search/filtered-home-items
|
||||
:<- [:search/filtered-active-chats]
|
||||
(fn [active-chats]
|
||||
active-chats))
|
@ -243,8 +243,10 @@
|
||||
:transport.inbox/request-to
|
||||
:desktop/desktop
|
||||
:dimensions/window
|
||||
:dapps/permissions]
|
||||
|
||||
:dapps/permissions
|
||||
:ui/contact
|
||||
:ui/search
|
||||
:ui/chat]
|
||||
:opt-un
|
||||
[::current-public-key
|
||||
::modal
|
||||
|
@ -3,7 +3,7 @@
|
||||
(:require [re-frame.core :as re-frame]
|
||||
[status-im.utils.gfycat.core :as gfycat]
|
||||
[status-im.i18n :as i18n]
|
||||
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.ui.screens.desktop.main.tabs.home.styles :as styles]
|
||||
[clojure.string :as string]
|
||||
[status-im.ui.screens.home.views.inner-item :as chat-item]
|
||||
@ -65,17 +65,51 @@
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:chat.ui/navigate-to-chat chat-id])}
|
||||
[chat-list-item-inner-view (assoc chat :chat-id chat-id)]])
|
||||
|
||||
(defn tag-view [tag {:keys [on-press]}]
|
||||
[react/touchable-highlight {:style {:border-radius 5
|
||||
:margin 2
|
||||
:padding 4
|
||||
:height 23
|
||||
:background-color (if (= tag "clear filter")
|
||||
colors/red
|
||||
colors/blue)
|
||||
:justify-content :center
|
||||
:align-items :center
|
||||
:align-content :center}
|
||||
:on-press on-press}
|
||||
[react/text {:style {:font-size 9
|
||||
:color colors/white}
|
||||
:font :medium} tag]])
|
||||
|
||||
(defn search-input [search-filter]
|
||||
[react/view {:style {:flex 1
|
||||
:flex-direction :row}}
|
||||
[react/text-input {:placeholder "Type here to search chats..."
|
||||
:auto-focus true
|
||||
:blur-on-submit true
|
||||
:style {:flex 1
|
||||
:color :black
|
||||
:height 30
|
||||
:margin-left 20
|
||||
:margin-right 22}
|
||||
:default-value search-filter
|
||||
:on-change (fn [e]
|
||||
(let [native-event (.-nativeEvent e)
|
||||
text (.-text native-event)]
|
||||
(re-frame/dispatch [:search/filter-changed text])))}]])
|
||||
|
||||
(views/defview chat-list-view []
|
||||
(views/letsubs [home-items [:home-items]]
|
||||
(views/letsubs [search-filter [:search/filter]
|
||||
filtered-home-items [:search/filtered-home-items]]
|
||||
[react/view {:style styles/chat-list-view}
|
||||
[react/view {:style styles/chat-list-header}
|
||||
[react/view {:style {:flex 1}}]
|
||||
[search-input search-filter]
|
||||
[react/touchable-highlight {:on-press #(re-frame/dispatch [:navigate-to :new-contact])}
|
||||
[react/view {:style styles/add-new}
|
||||
[icons/icon :icons/add {:style {:tint-color :white}}]]]]
|
||||
[react/view {:style styles/chat-list-separator}]
|
||||
[react/scroll-view {:enableArrayScrollingOptimization true}
|
||||
[react/view
|
||||
(for [[index chat] (map-indexed vector home-items)]
|
||||
(for [[index chat] (map-indexed vector filtered-home-items)]
|
||||
^{:key (first chat)}
|
||||
[chat-list-item chat])]]]))
|
||||
|
@ -3,6 +3,7 @@
|
||||
[status-im.utils.ethereum.core :as ethereum]
|
||||
status-im.chat.subs
|
||||
status-im.contact.subs
|
||||
status-im.search.subs
|
||||
status-im.ui.screens.accounts.subs
|
||||
status-im.ui.screens.extensions.subs
|
||||
status-im.ui.screens.home.subs
|
||||
|
@ -10,3 +10,7 @@
|
||||
(spec/def :global/not-empty-string (spec/and string? not-empty))
|
||||
(spec/def :global/public-key (spec/and :global/not-empty-string valid-public-key?))
|
||||
(spec/def :global/address ethereum/address?)
|
||||
|
||||
(spec/def :status/tag (spec/and :global/not-empty-string
|
||||
(partial re-matches #"[a-z0-9\-]+")))
|
||||
(spec/def :status/tags (spec/coll-of :status/tag :kind set?))
|
||||
|
@ -118,4 +118,4 @@
|
||||
(testing "it returns only chats with is-active"
|
||||
(is (= {1 active-chat-1
|
||||
2 active-chat-2}
|
||||
(s/active-chats chats))))))
|
||||
(s/active-chats [{} chats]))))))
|
||||
|
Loading…
x
Reference in New Issue
Block a user