[desktop] Add search feature for chat list

Signed-off-by: yenda <eric@status.im>
This commit is contained in:
yenda 2018-10-13 18:47:34 +02:00
parent 14ef386f2e
commit 82c3997f07
No known key found for this signature in database
GPG Key ID: 0095623C0069DCE6
11 changed files with 144 additions and 40 deletions

View File

@ -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)

View File

@ -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)]

View File

@ -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]))

View File

@ -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)))

View 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)})

View 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))

View File

@ -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

View File

@ -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])]]]))

View File

@ -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

View File

@ -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?))

View File

@ -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]))))))