Merge pull request #541 from status-im/feature/toolbar-fixes-and-search
Toolbar refactoring, unification; search for contacts (#448); processed-messages cache (#552); fix for #554
This commit is contained in:
commit
63e352020d
|
@ -1,5 +1,6 @@
|
||||||
(ns status-im.accounts.handlers
|
(ns status-im.accounts.handlers
|
||||||
(:require [status-im.data-store.accounts :as accounts-store]
|
(:require [status-im.data-store.accounts :as accounts-store]
|
||||||
|
[status-im.data-store.processed-messages :as processed-messages]
|
||||||
[re-frame.core :refer [register-handler after dispatch dispatch-sync debug]]
|
[re-frame.core :refer [register-handler after dispatch dispatch-sync debug]]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[status-im.protocol.core :as protocol]
|
[status-im.protocol.core :as protocol]
|
||||||
|
@ -18,6 +19,7 @@
|
||||||
[status-im.utils.gfycat.core :refer [generate-gfy]]
|
[status-im.utils.gfycat.core :refer [generate-gfy]]
|
||||||
[status-im.constants :refer [console-chat-id]]
|
[status-im.constants :refer [console-chat-id]]
|
||||||
[status-im.utils.scheduler :as s]
|
[status-im.utils.scheduler :as s]
|
||||||
|
[status-im.protocol.message-cache :as cache]
|
||||||
[status-im.navigation.handlers :as nav]))
|
[status-im.navigation.handlers :as nav]))
|
||||||
|
|
||||||
|
|
||||||
|
@ -149,6 +151,15 @@
|
||||||
|
|
||||||
(register-handler :console-create-account console-create-account)
|
(register-handler :console-create-account console-create-account)
|
||||||
|
|
||||||
|
(register-handler
|
||||||
|
:load-processed-messages
|
||||||
|
(u/side-effect!
|
||||||
|
(fn [_]
|
||||||
|
(let [now (time/now-ms)
|
||||||
|
messages (processed-messages/get-filtered (str "ttl > " now))]
|
||||||
|
(cache/init! messages)
|
||||||
|
(processed-messages/delete (str "ttl <=" now))))))
|
||||||
|
|
||||||
(defmethod nav/preload-data! :qr-code-view
|
(defmethod nav/preload-data! :qr-code-view
|
||||||
[{:keys [current-account-id] :as db} [_ _ {:keys [contact qr-source amount?]}]]
|
[{:keys [current-account-id] :as db} [_ _ {:keys [contact qr-source amount?]}]]
|
||||||
(assoc db :qr-modal {:contact (or contact
|
(assoc db :qr-modal {:contact (or contact
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
get-dimensions]]
|
get-dimensions]]
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.components.toolbar.styles :refer [toolbar-title-container
|
[status-im.components.toolbar.styles :refer [toolbar-title-container
|
||||||
toolbar-title-text]]
|
toolbar-title-text]]
|
||||||
[status-im.components.text-field.view :refer [text-field]]
|
[status-im.components.text-field.view :refer [text-field]]
|
||||||
|
@ -66,9 +67,7 @@
|
||||||
:style st/gradient-background}]
|
:style st/gradient-background}]
|
||||||
[status-bar {:type :transparent}]
|
[status-bar {:type :transparent}]
|
||||||
[toolbar {:background-color :transparent
|
[toolbar {:background-color :transparent
|
||||||
:nav-action {:image {:source {:uri :icon_back_white}
|
:nav-action (act/back-white #(dispatch [:navigate-back]))
|
||||||
:style icon-back}
|
|
||||||
:handler #(dispatch [:navigate-back])}
|
|
||||||
:custom-content [toolbar-title]
|
:custom-content [toolbar-title]
|
||||||
:actions [{:image {:style icon-search}
|
:actions [{:image {:style icon-search}
|
||||||
:handler #()}]}]
|
:handler #()}]}]
|
||||||
|
|
|
@ -9,13 +9,12 @@
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.text-field.view :refer [text-field]]
|
[status-im.components.text-field.view :refer [text-field]]
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.components.toolbar.styles :refer [toolbar-gradient
|
[status-im.components.toolbar.styles :refer [toolbar-gradient
|
||||||
toolbar-title-container
|
toolbar-title-container
|
||||||
toolbar-title-text]]
|
toolbar-title-text]]
|
||||||
[status-im.components.styles :refer [color-purple
|
[status-im.components.styles :refer [color-purple
|
||||||
color-white
|
color-white
|
||||||
icon-back
|
|
||||||
icon-search
|
|
||||||
button-input]]
|
button-input]]
|
||||||
[status-im.components.react :refer [linear-gradient]]
|
[status-im.components.react :refer [linear-gradient]]
|
||||||
[status-im.i18n :refer [label]]
|
[status-im.i18n :refer [label]]
|
||||||
|
@ -78,12 +77,8 @@
|
||||||
[view st/screen-container
|
[view st/screen-container
|
||||||
[status-bar {:type :transparent}]
|
[status-bar {:type :transparent}]
|
||||||
[toolbar {:background-color :transparent
|
[toolbar {:background-color :transparent
|
||||||
:nav-action {:image {:source {:uri :icon_back}
|
:nav-action (act/back #(dispatch [:navigate-back]))
|
||||||
:style icon-back}
|
:custom-content [toolbar-title]}]
|
||||||
:handler #(dispatch [:navigate-back])}
|
|
||||||
:custom-content [toolbar-title]
|
|
||||||
:actions [{:image {:style icon-search}
|
|
||||||
:handler #()}]}]
|
|
||||||
[linear-gradient {:locations [0 0.6 1]
|
[linear-gradient {:locations [0 0.6 1]
|
||||||
:colors gradient-colors
|
:colors gradient-colors
|
||||||
:style toolbar-gradient}]
|
:style toolbar-gradient}]
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
touchable-highlight]]
|
touchable-highlight]]
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.components.styles :refer [color-purple
|
[status-im.components.styles :refer [color-purple
|
||||||
color-white
|
color-white
|
||||||
icon-search
|
icon-search
|
||||||
|
@ -61,9 +62,9 @@
|
||||||
:style st/gradient-background}
|
:style st/gradient-background}
|
||||||
[status-bar {:type :transparent}]
|
[status-bar {:type :transparent}]
|
||||||
[toolbar {:background-color :transparent
|
[toolbar {:background-color :transparent
|
||||||
:nav-action {:image {:source (if show-back? {:uri :icon_back_white} nil)
|
:nav-action (if show-back?
|
||||||
:style icon-back}
|
(act/back-white #(dispatch [:navigate-back]))
|
||||||
:handler (if show-back? #(dispatch [:navigate-back]) nil)}
|
act/nothing)
|
||||||
:custom-content [toolbar-title]
|
:custom-content [toolbar-title]
|
||||||
:actions [{:image {:style icon-search}
|
:actions [{:image {:style icon-search}
|
||||||
:handler #()}]}]]
|
:handler #()}]}]]
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
modal
|
modal
|
||||||
splash-screen]]
|
splash-screen]]
|
||||||
[status-im.components.main-tabs :refer [main-tabs]]
|
[status-im.components.main-tabs :refer [main-tabs]]
|
||||||
|
[status-im.contacts.search-results :refer [contacts-search-results]]
|
||||||
[status-im.contacts.views.contact-list :refer [contact-list]]
|
[status-im.contacts.views.contact-list :refer [contact-list]]
|
||||||
[status-im.contacts.views.new-contact :refer [new-contact]]
|
[status-im.contacts.views.new-contact :refer [new-contact]]
|
||||||
[status-im.qr-scanner.screen :refer [qr-scanner]]
|
[status-im.qr-scanner.screen :refer [qr-scanner]]
|
||||||
|
@ -95,6 +96,7 @@
|
||||||
:new-group new-group
|
:new-group new-group
|
||||||
:group-settings group-settings
|
:group-settings group-settings
|
||||||
:contact-list main-tabs
|
:contact-list main-tabs
|
||||||
|
:contact-list-search-results contacts-search-results
|
||||||
:group-contacts contact-list
|
:group-contacts contact-list
|
||||||
:new-contact new-contact
|
:new-contact new-contact
|
||||||
:qr-scanner qr-scanner
|
:qr-scanner qr-scanner
|
||||||
|
|
|
@ -8,43 +8,36 @@
|
||||||
text
|
text
|
||||||
image
|
image
|
||||||
touchable-highlight]]
|
touchable-highlight]]
|
||||||
[status-im.utils.listview :refer [to-datasource]]
|
|
||||||
[status-im.chats-list.views.chat-list-item :refer [chat-list-item]]
|
|
||||||
[status-im.components.action-button :refer [action-button
|
[status-im.components.action-button :refer [action-button
|
||||||
action-button-item]]
|
action-button-item]]
|
||||||
[status-im.components.drawer.view :refer [open-drawer]]
|
[status-im.components.drawer.view :refer [open-drawer]]
|
||||||
[status-im.components.styles :refer [color-blue]]
|
[status-im.components.styles :refer [color-blue]]
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar-with-search]]
|
||||||
[status-im.components.toolbar.styles :refer [toolbar-background1
|
[status-im.components.toolbar.actions :as act]
|
||||||
toolbar-background2]]
|
|
||||||
[status-im.components.icons.custom-icons :refer [ion-icon]]
|
[status-im.components.icons.custom-icons :refer [ion-icon]]
|
||||||
[status-im.components.react :refer [linear-gradient]]
|
[status-im.components.react :refer [linear-gradient]]
|
||||||
[status-im.i18n :refer [label]]
|
|
||||||
[status-im.chats-list.styles :as st]
|
|
||||||
[status-im.utils.platform :refer [platform-specific]]
|
|
||||||
[status-im.components.sync-state.offline :refer [offline-view]]
|
[status-im.components.sync-state.offline :refer [offline-view]]
|
||||||
|
[status-im.utils.listview :refer [to-datasource]]
|
||||||
|
[status-im.chats-list.views.chat-list-item :refer [chat-list-item]]
|
||||||
|
[status-im.i18n :refer [label]]
|
||||||
|
[status-im.utils.platform :refer [platform-specific]]
|
||||||
|
[status-im.chats-list.styles :as st]
|
||||||
[status-im.components.tabs.styles :refer [tabs-height]]))
|
[status-im.components.tabs.styles :refer [tabs-height]]))
|
||||||
|
|
||||||
(defview chats-list-toolbar []
|
(defview toolbar-view []
|
||||||
[chats-scrolled? [:get :chats-scrolled?]]
|
[chats-scrolled? [:get :chats-scrolled?]]
|
||||||
(let [new-chat? (get-in platform-specific [:chats :new-chat-in-toolbar?])
|
(let [new-chat? (get-in platform-specific [:chats :new-chat-in-toolbar?])
|
||||||
actions (cond->> [{:image {:source {:uri :icon_search}
|
actions (if new-chat?
|
||||||
:style st/toolbar-icon}
|
[(act/add #(dispatch [:navigate-to :group-contacts :people]))])]
|
||||||
:handler (fn [])}]
|
[toolbar-with-search
|
||||||
new-chat?
|
{:show-search? false
|
||||||
(into [{:image {:source {:uri :icon_add}
|
:search-key :chat-list
|
||||||
:style st/toolbar-icon}
|
|
||||||
:handler #(dispatch [:navigate-to :group-contacts :people])}]))]
|
|
||||||
[toolbar {:nav-action {:image {:source {:uri :icon_hamburger}
|
|
||||||
:style st/hamburger-icon}
|
|
||||||
:handler open-drawer}
|
|
||||||
:title (label :t/chats)
|
:title (label :t/chats)
|
||||||
:style (get-in platform-specific [:component-styles :toolbar])
|
:search-placeholder (label :t/search-for)
|
||||||
:background-color (if chats-scrolled?
|
:nav-action (act/hamburger open-drawer)
|
||||||
toolbar-background1
|
:actions actions
|
||||||
toolbar-background2)
|
:style (st/toolbar chats-scrolled?)}]))
|
||||||
:actions actions}]))
|
|
||||||
|
|
||||||
(defn chats-action-button []
|
(defn chats-action-button []
|
||||||
[view {:style (st/action-buttons-container false 0)
|
[view {:style (st/action-buttons-container false 0)
|
||||||
|
@ -75,7 +68,7 @@
|
||||||
(defview chats-list []
|
(defview chats-list []
|
||||||
[chats [:get :chats]]
|
[chats [:get :chats]]
|
||||||
[view st/chats-container
|
[view st/chats-container
|
||||||
[chats-list-toolbar]
|
[toolbar-view]
|
||||||
[list-view {:dataSource (to-datasource chats)
|
[list-view {:dataSource (to-datasource chats)
|
||||||
:renderRow (fn [[id :as row] _ _]
|
:renderRow (fn [[id :as row] _ _]
|
||||||
(list-item ^{:key id} [chat-list-item row]))
|
(list-item ^{:key id} [chat-list-item row]))
|
||||||
|
|
|
@ -7,8 +7,16 @@
|
||||||
text2-color
|
text2-color
|
||||||
new-messages-count-color]]
|
new-messages-count-color]]
|
||||||
[status-im.components.tabs.styles :refer [tabs-height]]
|
[status-im.components.tabs.styles :refer [tabs-height]]
|
||||||
|
[status-im.components.toolbar.styles :refer [toolbar-background1
|
||||||
|
toolbar-background2]]
|
||||||
[status-im.utils.platform :as p]))
|
[status-im.utils.platform :as p]))
|
||||||
|
|
||||||
|
(defn toolbar [chats-scrolled?]
|
||||||
|
(merge {:background-color (if chats-scrolled?
|
||||||
|
toolbar-background1
|
||||||
|
toolbar-background2)}
|
||||||
|
(get-in p/platform-specific [:component-styles :toolbar])))
|
||||||
|
|
||||||
(def gradient-top-bottom-shadow
|
(def gradient-top-bottom-shadow
|
||||||
["rgba(24, 52, 76, 0.165)"
|
["rgba(24, 52, 76, 0.165)"
|
||||||
"rgba(24, 52, 76, 0.03)"
|
"rgba(24, 52, 76, 0.03)"
|
||||||
|
@ -103,14 +111,6 @@
|
||||||
:color color-blue
|
:color color-blue
|
||||||
:textAlign :center})
|
:textAlign :center})
|
||||||
|
|
||||||
(def hamburger-icon
|
|
||||||
{:width 16
|
|
||||||
:height 12})
|
|
||||||
|
|
||||||
(def toolbar-icon
|
|
||||||
{:width 17
|
|
||||||
:height 17})
|
|
||||||
|
|
||||||
(def chats-container
|
(def chats-container
|
||||||
{:flex 1})
|
{:flex 1})
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@
|
||||||
:on-momentum-scroll-end (on-scroll-end swiped? dragging?)})
|
:on-momentum-scroll-end (on-scroll-end swiped? dragging?)})
|
||||||
[chats-list]
|
[chats-list]
|
||||||
[discover (= @view-id :discover)]
|
[discover (= @view-id :discover)]
|
||||||
[contact-list]]
|
[contact-list (= @view-id :contact-list)]]
|
||||||
[tabs {:selected-view-id @view-id
|
[tabs {:selected-view-id @view-id
|
||||||
:prev-view-id @prev-view-id
|
:prev-view-id @prev-view-id
|
||||||
:tab-list tab-list}]
|
:tab-list tab-list}]
|
||||||
|
|
|
@ -31,10 +31,6 @@
|
||||||
(def flex
|
(def flex
|
||||||
{:flex 1})
|
{:flex 1})
|
||||||
|
|
||||||
(def hamburger-icon
|
|
||||||
{:width 16
|
|
||||||
:height 12})
|
|
||||||
|
|
||||||
(def icon-search
|
(def icon-search
|
||||||
{:width 17
|
{:width 17
|
||||||
:height 17})
|
:height 17})
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
(ns status-im.components.toolbar.actions
|
||||||
|
(:require [status-im.components.toolbar.styles :as st]))
|
||||||
|
|
||||||
|
(def nothing
|
||||||
|
{:image {:source nil
|
||||||
|
:style st/action-search}})
|
||||||
|
|
||||||
|
(defn hamburger [handler]
|
||||||
|
{:image {:source {:uri :icon_hamburger}
|
||||||
|
:style st/action-hamburger}
|
||||||
|
:handler handler})
|
||||||
|
|
||||||
|
(defn add [handler]
|
||||||
|
{:image {:source {:uri :icon_add}
|
||||||
|
:style st/action-add}
|
||||||
|
:handler handler})
|
||||||
|
|
||||||
|
(defn search [handler]
|
||||||
|
{:image {:source {:uri :icon_search}
|
||||||
|
:style st/action-search}
|
||||||
|
:handler handler})
|
||||||
|
|
||||||
|
(defn back [handler]
|
||||||
|
{:image {:source {:uri :icon_back}
|
||||||
|
:style st/action-back}
|
||||||
|
:handler handler})
|
||||||
|
|
||||||
|
(defn back-white [handler]
|
||||||
|
{:image {:source {:uri :icon_back_white}
|
||||||
|
:style st/action-back}
|
||||||
|
:handler handler})
|
|
@ -41,7 +41,7 @@
|
||||||
:justifyContent :center})
|
:justifyContent :center})
|
||||||
|
|
||||||
(def toolbar-title-text
|
(def toolbar-title-text
|
||||||
{:margin-top -2.5
|
{:margin-top 0
|
||||||
:color text1-color
|
:color text1-color
|
||||||
:font-size 16})
|
:font-size 16})
|
||||||
|
|
||||||
|
@ -58,3 +58,45 @@
|
||||||
:margin-right toolbar-icon-spacing
|
:margin-right toolbar-icon-spacing
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:justify-content :center})
|
:justify-content :center})
|
||||||
|
|
||||||
|
(def toolbar-with-search
|
||||||
|
{:background-color toolbar-background2
|
||||||
|
:elevation 0})
|
||||||
|
|
||||||
|
(def toolbar-with-search-content
|
||||||
|
{:flex 1
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center})
|
||||||
|
|
||||||
|
(def toolbar-search-input
|
||||||
|
{:flex 1
|
||||||
|
:align-self :stretch
|
||||||
|
:margin-left 18
|
||||||
|
:margin-top 2
|
||||||
|
:font-size 14
|
||||||
|
:color "#7099e6"})
|
||||||
|
|
||||||
|
(def toolbar-with-search-title
|
||||||
|
{:color "#000000de"
|
||||||
|
:align-self :center
|
||||||
|
:text-align :center
|
||||||
|
:font-size 16})
|
||||||
|
|
||||||
|
|
||||||
|
;; Specific actions
|
||||||
|
|
||||||
|
(def action-hamburger
|
||||||
|
{:width 16
|
||||||
|
:height 12})
|
||||||
|
|
||||||
|
(def action-add
|
||||||
|
{:width 17
|
||||||
|
:height 17})
|
||||||
|
|
||||||
|
(def action-search
|
||||||
|
{:width 17
|
||||||
|
:height 17})
|
||||||
|
|
||||||
|
(def action-back
|
||||||
|
{:width 8
|
||||||
|
:height 14})
|
||||||
|
|
|
@ -3,10 +3,13 @@
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
icon
|
icon
|
||||||
text
|
text
|
||||||
|
text-input
|
||||||
image
|
image
|
||||||
touchable-highlight]]
|
touchable-highlight]]
|
||||||
[status-im.components.sync-state.gradient :refer [sync-state-gradient-view]]
|
[status-im.components.sync-state.gradient :refer [sync-state-gradient-view]]
|
||||||
[status-im.components.styles :refer [icon-back]]
|
[status-im.components.styles :refer [icon-back
|
||||||
|
icon-search]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.components.toolbar.styles :as st]
|
[status-im.components.toolbar.styles :as st]
|
||||||
[status-im.utils.platform :refer [platform-specific]]))
|
[status-im.utils.platform :refer [platform-specific]]))
|
||||||
|
|
||||||
|
@ -48,3 +51,43 @@
|
||||||
custom-action)]]
|
custom-action)]]
|
||||||
[sync-state-gradient-view]]))
|
[sync-state-gradient-view]]))
|
||||||
|
|
||||||
|
(defn- toolbar-search-submit [on-search-submit]
|
||||||
|
(let [text @(subscribe [:get-in [:toolbar-search :text]])]
|
||||||
|
(on-search-submit text)
|
||||||
|
(dispatch [:set-in [:toolbar-search :text] nil])))
|
||||||
|
|
||||||
|
(defn- toolbar-with-search-content [{:keys [show-search?
|
||||||
|
search-key
|
||||||
|
search-placeholder
|
||||||
|
title
|
||||||
|
on-search-submit]}]
|
||||||
|
[view st/toolbar-with-search-content
|
||||||
|
(if show-search?
|
||||||
|
[text-input
|
||||||
|
{:style st/toolbar-search-input
|
||||||
|
:auto-focus true
|
||||||
|
:placeholder search-placeholder
|
||||||
|
:on-change-text #(dispatch [:set-in [:toolbar-search :text] %])
|
||||||
|
:on-submit-editing #(toolbar-search-submit on-search-submit)}]
|
||||||
|
[view
|
||||||
|
[text {:style st/toolbar-with-search-title
|
||||||
|
:font :toolbar-title}
|
||||||
|
title]])])
|
||||||
|
|
||||||
|
(defn toolbar-with-search [{:keys [show-search?
|
||||||
|
search-key
|
||||||
|
nav-action
|
||||||
|
actions
|
||||||
|
style
|
||||||
|
on-search-submit]
|
||||||
|
:as opts}]
|
||||||
|
(let [toggle-search-fn #(dispatch [:set-in [:toolbar-search :show] %])
|
||||||
|
actions (if show-search?
|
||||||
|
[(act/search #(toolbar-search-submit on-search-submit))]
|
||||||
|
(into actions [(act/search #(toggle-search-fn search-key))]))]
|
||||||
|
[toolbar {:style (merge st/toolbar-with-search style)
|
||||||
|
:nav-action (if show-search?
|
||||||
|
(act/back #(toggle-search-fn nil))
|
||||||
|
nav-action)
|
||||||
|
:custom-content [toolbar-with-search-content opts]
|
||||||
|
:actions actions}]))
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
[status-im.utils.utils :refer [require]]
|
[status-im.utils.utils :refer [require]]
|
||||||
[status-im.navigation.handlers :as nav]
|
[status-im.navigation.handlers :as nav]
|
||||||
[status-im.utils.random :as random]
|
[status-im.utils.random :as random]
|
||||||
|
[status-im.i18n :refer [label]]
|
||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[cljs.reader :refer [read-string]]))
|
[cljs.reader :refer [read-string]]))
|
||||||
|
|
||||||
|
@ -31,9 +32,10 @@
|
||||||
|
|
||||||
(defmethod nav/preload-data! :contact-list
|
(defmethod nav/preload-data! :contact-list
|
||||||
[db [_ _ click-handler]]
|
[db [_ _ click-handler]]
|
||||||
(assoc db :contacts-click-handler click-handler
|
(-> db
|
||||||
:contacts-filter nil))
|
(assoc-in [:toolbar-search :show] nil)
|
||||||
|
(assoc :contacts-click-handler click-handler
|
||||||
|
:contacts-filter nil)))
|
||||||
|
|
||||||
(register-handler :remove-contacts-click-handler
|
(register-handler :remove-contacts-click-handler
|
||||||
(fn [db]
|
(fn [db]
|
||||||
|
@ -56,6 +58,13 @@
|
||||||
|
|
||||||
(register-handler :watch-contact (u/side-effect! watch-contact))
|
(register-handler :watch-contact (u/side-effect! watch-contact))
|
||||||
|
|
||||||
|
(defn stop-watching-contact
|
||||||
|
[{:keys [web3]} [_ {:keys [whisper-identity]}]]
|
||||||
|
(protocol/stop-watching-user! {:web3 web3
|
||||||
|
:identity whisper-identity}))
|
||||||
|
|
||||||
|
(register-handler :stop-watching-contact (u/side-effect! stop-watching-contact))
|
||||||
|
|
||||||
(defn send-contact-request
|
(defn send-contact-request
|
||||||
[{:keys [current-public-key web3 current-account-id accounts]} [_ contact]]
|
[{:keys [current-public-key web3 current-account-id accounts]} [_ contact]]
|
||||||
(let [{:keys [whisper-identity]} contact
|
(let [{:keys [whisper-identity]} contact
|
||||||
|
@ -199,11 +208,13 @@
|
||||||
|
|
||||||
(register-handler :add-pending-contact
|
(register-handler :add-pending-contact
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
(fn [{:keys [chats]} [_ chat-id]]
|
(fn [{:keys [chats contacts]} [_ chat-id]]
|
||||||
(let [contact (read-string (get-in chats [chat-id :contact-info]))]
|
(let [contact (if-let [contact-info (get-in chats [chat-id :contact-info])]
|
||||||
|
(read-string contact-info)
|
||||||
|
(-> (get contacts chat-id)
|
||||||
|
(assoc :pending false)))]
|
||||||
(dispatch [::prepare-contact contact])
|
(dispatch [::prepare-contact contact])
|
||||||
(dispatch [:update-chat! {:chat-id chat-id
|
(dispatch [:update-chat! {:chat-id chat-id
|
||||||
:contact-info nil
|
|
||||||
:pending-contact? false}])
|
:pending-contact? false}])
|
||||||
(dispatch [:watch-contact contact])
|
(dispatch [:watch-contact contact])
|
||||||
(dispatch [:discoveries-send-portions chat-id])))))
|
(dispatch [:discoveries-send-portions chat-id])))))
|
||||||
|
@ -242,3 +253,22 @@
|
||||||
(dispatch [:update-contact! {:whisper-identity from
|
(dispatch [:update-contact! {:whisper-identity from
|
||||||
:last-online timestamp}]))))))
|
:last-online timestamp}]))))))
|
||||||
|
|
||||||
|
(register-handler :remove-contact
|
||||||
|
(-> (u/side-effect!
|
||||||
|
(fn [_ [_ {:keys [whisper-identity] :as contact}]]
|
||||||
|
(dispatch [:update-chat! {:chat-id whisper-identity
|
||||||
|
:pending-contact? true}])
|
||||||
|
(dispatch [:update-contact! (assoc contact :pending true)])))
|
||||||
|
((after stop-watching-contact))))
|
||||||
|
|
||||||
|
(register-handler :open-contact-menu
|
||||||
|
(u/side-effect!
|
||||||
|
(fn [_ [_ list-selection-fn {:keys [name] :as contact}]]
|
||||||
|
(list-selection-fn {:title name
|
||||||
|
:options [(label :t/remove-contact)]
|
||||||
|
:callback (fn [index]
|
||||||
|
(case index
|
||||||
|
0 (dispatch [:remove-contact contact])
|
||||||
|
:default))
|
||||||
|
:cancel-text (label :t/cancel)}))))
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
(ns status-im.contacts.screen
|
(ns status-im.contacts.screen
|
||||||
(:require-macros [status-im.utils.views :refer [defview]])
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
(:require [reagent.core :as r]
|
||||||
[reagent.core :as r]
|
[clojure.string :as str]
|
||||||
|
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
text
|
text
|
||||||
image
|
image
|
||||||
|
@ -12,38 +13,40 @@
|
||||||
list-item] :as react]
|
list-item] :as react]
|
||||||
[status-im.components.action-button :refer [action-button
|
[status-im.components.action-button :refer [action-button
|
||||||
action-button-item]]
|
action-button-item]]
|
||||||
[status-im.contacts.views.contact :refer [contact-extended-view on-press]]
|
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar-with-search]]
|
||||||
[status-im.components.toolbar.styles :refer [toolbar-background2]]
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.components.drawer.view :refer [open-drawer]]
|
[status-im.components.drawer.view :refer [open-drawer]]
|
||||||
[status-im.components.icons.custom-icons :refer [ion-icon]]
|
[status-im.components.icons.custom-icons :refer [ion-icon]]
|
||||||
[status-im.components.styles :refer [color-blue
|
[status-im.contacts.views.contact :refer [contact-view]]
|
||||||
hamburger-icon
|
[status-im.utils.platform :refer [platform-specific]]
|
||||||
icon-search
|
|
||||||
create-icon]]
|
|
||||||
[status-im.contacts.styles :as st]
|
|
||||||
[status-im.i18n :refer [label]]
|
[status-im.i18n :refer [label]]
|
||||||
[status-im.utils.platform :refer [platform-specific]]))
|
[status-im.contacts.styles :as st]
|
||||||
|
[status-im.components.styles :refer [color-blue
|
||||||
|
create-icon
|
||||||
|
icon-search]]))
|
||||||
|
|
||||||
(def contacts-limit 50)
|
(def contacts-limit 50)
|
||||||
|
|
||||||
(defn toolbar-view []
|
(defn toolbar-view [show-search?]
|
||||||
(let [new-contact? (get-in platform-specific [:contacts :new-contact-in-toolbar?])
|
(let [new-contact? (get-in platform-specific [:contacts :new-contact-in-toolbar?])
|
||||||
actions (cond->> [{:image {:source {:uri :icon_search}
|
actions (if new-contact?
|
||||||
:style icon-search}
|
[(act/add #(dispatch [:navigate-to :new-contact]))])]
|
||||||
:handler (fn [])}]
|
(toolbar-with-search
|
||||||
new-contact?
|
{:show-search? show-search?
|
||||||
(into [{:image {:source {:uri :icon_add}
|
:search-key :contact-list
|
||||||
:style icon-search}
|
|
||||||
:handler #(dispatch [:navigate-to :new-contact])}]))]
|
|
||||||
[toolbar {:nav-action {:image {:source {:uri :icon_hamburger}
|
|
||||||
:style hamburger-icon}
|
|
||||||
:handler open-drawer}
|
|
||||||
:title (label :t/contacts)
|
:title (label :t/contacts)
|
||||||
:background-color toolbar-background2
|
:search-placeholder (label :t/search-for)
|
||||||
:style {:elevation 0}
|
:nav-action (act/hamburger open-drawer)
|
||||||
:actions actions}]))
|
:actions actions
|
||||||
|
:on-search-submit (fn [text]
|
||||||
|
(when-not (str/blank? text)
|
||||||
|
(dispatch [:set :contacts-filter #(let [name (-> (or (:name %) "")
|
||||||
|
(str/lower-case))
|
||||||
|
text (str/lower-case text)]
|
||||||
|
(not= (.indexOf name text) -1))])
|
||||||
|
(dispatch [:set :contact-list-search-text text])
|
||||||
|
(dispatch [:navigate-to :contact-list-search-results])))})))
|
||||||
|
|
||||||
(defn subtitle-view [subtitle contacts-count]
|
(defn subtitle-view [subtitle contacts-count]
|
||||||
[view st/contact-group-header-inner
|
[view st/contact-group-header-inner
|
||||||
|
@ -81,9 +84,11 @@
|
||||||
[view
|
[view
|
||||||
(doall
|
(doall
|
||||||
(map (fn [contact]
|
(map (fn [contact]
|
||||||
(let [click-handler (or click-handler on-press)]
|
|
||||||
^{:key contact}
|
^{:key contact}
|
||||||
[contact-extended-view contact nil (click-handler contact) nil]))
|
[contact-view {:contact contact
|
||||||
|
:extended? true
|
||||||
|
:on-click click-handler
|
||||||
|
:more-on-click nil}])
|
||||||
contacts))]
|
contacts))]
|
||||||
(when (<= contacts-limit (count contacts))
|
(when (<= contacts-limit (count contacts))
|
||||||
[view st/show-all
|
[view st/show-all
|
||||||
|
@ -110,16 +115,18 @@
|
||||||
[ion-icon {:name :md-create
|
[ion-icon {:name :md-create
|
||||||
:style create-icon}]]]])
|
:style create-icon}]]]])
|
||||||
|
|
||||||
(defn contact-list []
|
(defn contact-list [_]
|
||||||
(let [peoples (subscribe [:get-added-people-with-limit contacts-limit])
|
(let [peoples (subscribe [:get-added-people-with-limit contacts-limit])
|
||||||
dapps (subscribe [:get-added-dapps-with-limit contacts-limit])
|
dapps (subscribe [:get-added-dapps-with-limit contacts-limit])
|
||||||
people-count (subscribe [:added-people-count])
|
people-count (subscribe [:added-people-count])
|
||||||
dapps-count (subscribe [:added-dapps-count])
|
dapps-count (subscribe [:added-dapps-count])
|
||||||
click-handler (subscribe [:get :contacts-click-handler])
|
click-handler (subscribe [:get :contacts-click-handler])
|
||||||
|
show-search (subscribe [:get-in [:toolbar-search :show]])
|
||||||
show-toolbar-shadow? (r/atom false)]
|
show-toolbar-shadow? (r/atom false)]
|
||||||
(fn []
|
(fn [current-view?]
|
||||||
[view st/contacts-list-container
|
[view st/contacts-list-container
|
||||||
[toolbar-view]
|
[toolbar-view (and current-view?
|
||||||
|
(= @show-search :contact-list))]
|
||||||
[view {:style st/toolbar-shadow}
|
[view {:style st/toolbar-shadow}
|
||||||
(when @show-toolbar-shadow?
|
(when @show-toolbar-shadow?
|
||||||
[linear-gradient {:style st/contact-group-header-gradient-bottom
|
[linear-gradient {:style st/contact-group-header-gradient-bottom
|
||||||
|
@ -128,7 +135,8 @@
|
||||||
[scroll-view {:style st/contact-groups
|
[scroll-view {:style st/contact-groups
|
||||||
:onScroll (fn [e]
|
:onScroll (fn [e]
|
||||||
(let [offset (.. e -nativeEvent -contentOffset -y)]
|
(let [offset (.. e -nativeEvent -contentOffset -y)]
|
||||||
(reset! show-toolbar-shadow? (<= st/contact-group-header-height offset))))}
|
(reset! show-toolbar-shadow?
|
||||||
|
(<= st/contact-group-header-height offset))))}
|
||||||
(when (pos? @dapps-count)
|
(when (pos? @dapps-count)
|
||||||
[contact-group-view
|
[contact-group-view
|
||||||
@dapps
|
@dapps
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
(ns status-im.contacts.search-results
|
||||||
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
|
(:require [re-frame.core :refer [subscribe dispatch]]
|
||||||
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
|
[status-im.components.react :refer [view
|
||||||
|
text
|
||||||
|
icon
|
||||||
|
list-view
|
||||||
|
list-item]]
|
||||||
|
[status-im.components.toolbar.view :refer [toolbar]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
|
[status-im.contacts.views.contact :refer [contact-view]]
|
||||||
|
[status-im.utils.listview :refer [to-datasource]]
|
||||||
|
[status-im.utils.platform :refer [platform-specific]]
|
||||||
|
[status-im.i18n :refer [label]]
|
||||||
|
[status-im.contacts.styles :as st]))
|
||||||
|
|
||||||
|
(defview contacts-search-results []
|
||||||
|
[search-text [:get :contact-list-search-text]
|
||||||
|
contacts [:contacts-with-letters]]
|
||||||
|
[view st/search-container
|
||||||
|
[status-bar]
|
||||||
|
[toolbar {:nav-action (act/back #(dispatch [:navigate-back]))
|
||||||
|
:title search-text
|
||||||
|
:style (get-in platform-specific [:component-styles :toolbar])}]
|
||||||
|
(if (empty? contacts)
|
||||||
|
[view st/search-empty-view
|
||||||
|
;; todo change icon
|
||||||
|
[icon :group_big st/empty-contacts-icon]
|
||||||
|
[text {:style st/empty-contacts-text}
|
||||||
|
"No contacts found"]]
|
||||||
|
[list-view {:dataSource (to-datasource contacts)
|
||||||
|
:renderRow (fn [row _ _]
|
||||||
|
(list-item [contact-view {:contact row
|
||||||
|
:letter? true
|
||||||
|
:extended? true}]))}])])
|
|
@ -10,17 +10,19 @@
|
||||||
color-gray2]]
|
color-gray2]]
|
||||||
[status-im.components.toolbar.styles :refer [toolbar-background2]]))
|
[status-im.components.toolbar.styles :refer [toolbar-background2]]))
|
||||||
|
|
||||||
(def contacts-list-container
|
;; Contacts list
|
||||||
{:flex 1})
|
|
||||||
|
|
||||||
(def toolbar-shadow
|
(def toolbar-shadow
|
||||||
{:height 2
|
{:height 2
|
||||||
:backgroundColor toolbar-background2})
|
:background-color toolbar-background2})
|
||||||
|
|
||||||
(def contact-groups
|
(def contact-groups
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:background-color toolbar-background2})
|
:background-color toolbar-background2})
|
||||||
|
|
||||||
|
(def contacts-list-container
|
||||||
|
{:flex 1})
|
||||||
|
|
||||||
(def empty-contact-groups
|
(def empty-contact-groups
|
||||||
(merge contact-groups
|
(merge contact-groups
|
||||||
{:align-items :center
|
{:align-items :center
|
||||||
|
@ -170,7 +172,7 @@
|
||||||
{:width 4
|
{:width 4
|
||||||
:height 16})
|
:height 16})
|
||||||
|
|
||||||
; new contact
|
; New contact
|
||||||
|
|
||||||
(def contact-form-container
|
(def contact-form-container
|
||||||
{:flex 1
|
{:flex 1
|
||||||
|
@ -222,3 +224,17 @@
|
||||||
:margin-top 18
|
:margin-top 18
|
||||||
:width 20
|
:width 20
|
||||||
:height 20})
|
:height 20})
|
||||||
|
|
||||||
|
;; Contacts search
|
||||||
|
|
||||||
|
(def search-container
|
||||||
|
{:flex 1
|
||||||
|
:background-color color-white})
|
||||||
|
|
||||||
|
(def search-empty-view
|
||||||
|
{:flex 1
|
||||||
|
:background-color color-white
|
||||||
|
:align-items :center
|
||||||
|
:justify-content :center})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.contacts.subs
|
(ns status-im.contacts.subs
|
||||||
(:require-macros [reagent.ratom :refer [reaction]])
|
(:require-macros [reagent.ratom :refer [reaction]])
|
||||||
(:require [re-frame.core :refer [register-sub subscribe]]
|
(:require [re-frame.core :refer [register-sub subscribe]]
|
||||||
|
[clojure.string :as str]
|
||||||
[status-im.utils.identicon :refer [identicon]]
|
[status-im.utils.identicon :refer [identicon]]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
|
@ -34,7 +35,6 @@
|
||||||
(let [contacts (subscribe [:all-added-contacts])]
|
(let [contacts (subscribe [:all-added-contacts])]
|
||||||
(reaction (filter :dapp? @contacts)))))
|
(reaction (filter :dapp? @contacts)))))
|
||||||
|
|
||||||
|
|
||||||
(register-sub :get-added-people-with-limit
|
(register-sub :get-added-people-with-limit
|
||||||
(fn [_ [_ limit]]
|
(fn [_ [_ limit]]
|
||||||
(let [contacts (subscribe [:all-added-people])]
|
(let [contacts (subscribe [:all-added-people])]
|
||||||
|
|
|
@ -7,8 +7,11 @@
|
||||||
(defn is-address? [s]
|
(defn is-address? [s]
|
||||||
(.isAddress web3.prototype s))
|
(.isAddress web3.prototype s))
|
||||||
|
|
||||||
(defn unique-identity? [identity]
|
(defn contact-can-be-added? [identity]
|
||||||
(not (contacts/exists? identity)))
|
(if (contacts/exists? identity)
|
||||||
|
(-> (contacts/get-by-id identity)
|
||||||
|
(get :pending))
|
||||||
|
true))
|
||||||
|
|
||||||
(defn valid-length? [identity]
|
(defn valid-length? [identity]
|
||||||
(let [length (count identity)]
|
(let [length (count identity)]
|
||||||
|
@ -18,11 +21,11 @@
|
||||||
(is-address? identity))))
|
(is-address? identity))))
|
||||||
|
|
||||||
(s/def ::identity-length valid-length?)
|
(s/def ::identity-length valid-length?)
|
||||||
(s/def ::unique-identity unique-identity?)
|
(s/def ::contact-can-be-added contact-can-be-added?)
|
||||||
(s/def ::not-empty-string (s/and string? not-empty))
|
(s/def ::not-empty-string (s/and string? not-empty))
|
||||||
(s/def ::name ::not-empty-string)
|
(s/def ::name ::not-empty-string)
|
||||||
(s/def ::whisper-identity (s/and ::not-empty-string
|
(s/def ::whisper-identity (s/and ::not-empty-string
|
||||||
::unique-identity
|
::contact-can-be-added
|
||||||
::identity-length))
|
::identity-length))
|
||||||
|
|
||||||
(s/def ::contact (s/keys :req-un [::name ::whisper-identity]
|
(s/def ::contact (s/keys :req-un [::name ::whisper-identity]
|
||||||
|
|
|
@ -3,37 +3,31 @@
|
||||||
(:require [status-im.components.react :refer [view text icon touchable-highlight]]
|
(:require [status-im.components.react :refer [view text icon touchable-highlight]]
|
||||||
[re-frame.core :refer [dispatch]]
|
[re-frame.core :refer [dispatch]]
|
||||||
[status-im.contacts.styles :as st]
|
[status-im.contacts.styles :as st]
|
||||||
[status-im.contacts.views.contact-inner :refer [contact-inner-view]]))
|
[status-im.contacts.views.contact-inner :refer [contact-inner-view]]
|
||||||
|
[status-im.utils.platform :refer [platform-specific]]))
|
||||||
|
|
||||||
(defn on-press [{:keys [whisper-identity]}]
|
(defn- on-press [{:keys [whisper-identity]}]
|
||||||
#(dispatch [:start-chat whisper-identity {} :navigation-replace]))
|
(dispatch [:start-chat whisper-identity {} :navigation-replace]))
|
||||||
|
|
||||||
|
(defn- more-on-press [contact]
|
||||||
|
(dispatch [:open-contact-menu (:list-selection-fn platform-specific) contact]))
|
||||||
|
|
||||||
(defn letter-view [letter]
|
(defn letter-view [letter]
|
||||||
[view st/letter-container
|
[view st/letter-container
|
||||||
(when letter
|
(when letter
|
||||||
[text {:style st/letter-text} letter])])
|
[text {:style st/letter-text} letter])])
|
||||||
|
|
||||||
(defview contact-view-with-letter [{:keys [whisper-identity letter] :as contact} click-handler action params]
|
(defview contact-view [{{:keys [whisper-identity letter dapp?] :as contact} :contact
|
||||||
[touchable-highlight
|
:keys [extended? letter? on-click more-on-click info]}]
|
||||||
{:onPress #(click-handler contact action params)}
|
|
||||||
[view st/contact-container
|
|
||||||
[letter-view letter]
|
|
||||||
[contact-inner-view contact]]])
|
|
||||||
|
|
||||||
(defview contact-view [{:keys [whisper-identity] :as contact}]
|
|
||||||
[chat [:get-chat whisper-identity]]
|
[chat [:get-chat whisper-identity]]
|
||||||
[touchable-highlight
|
[touchable-highlight
|
||||||
{:onPress (on-press contact)}
|
{:on-press #((or on-click on-press) contact)}
|
||||||
[view st/contact-container
|
|
||||||
[contact-inner-view contact]]])
|
|
||||||
|
|
||||||
(defview contact-extended-view [{:keys [whisper-identity] :as contact} info click-handler more-click-handler]
|
|
||||||
[chat [:get-chat whisper-identity]]
|
|
||||||
[touchable-highlight
|
|
||||||
{:onPress click-handler}
|
|
||||||
[view st/contact-container
|
[view st/contact-container
|
||||||
|
(when letter?
|
||||||
|
[letter-view letter])
|
||||||
[contact-inner-view contact info]
|
[contact-inner-view contact info]
|
||||||
|
(when (and extended? (not dapp?))
|
||||||
[touchable-highlight
|
[touchable-highlight
|
||||||
{:on-press more-click-handler}
|
{:on-press #((or more-on-click more-on-press) contact)}
|
||||||
[view st/more-btn
|
[view st/more-btn
|
||||||
[icon :more_vertical st/more-btn-icon]]]]])
|
[icon :more_vertical st/more-btn-icon]]])]])
|
||||||
|
|
|
@ -6,12 +6,11 @@
|
||||||
touchable-highlight
|
touchable-highlight
|
||||||
list-view
|
list-view
|
||||||
list-item]]
|
list-item]]
|
||||||
[status-im.contacts.views.contact :refer [contact-view
|
[status-im.contacts.views.contact :refer [contact-view]]
|
||||||
on-press
|
|
||||||
contact-view-with-letter]]
|
|
||||||
[status-im.components.text-field.view :refer [text-field]]
|
[status-im.components.text-field.view :refer [text-field]]
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.components.toolbar.styles :refer [toolbar-background1]]
|
[status-im.components.toolbar.styles :refer [toolbar-background1]]
|
||||||
[status-im.components.drawer.view :refer [drawer-view open-drawer]]
|
[status-im.components.drawer.view :refer [drawer-view open-drawer]]
|
||||||
[status-im.components.styles :refer [icon-search
|
[status-im.components.styles :refer [icon-search
|
||||||
|
@ -42,11 +41,10 @@
|
||||||
(defn render-row [chat-modal click-handler action params]
|
(defn render-row [chat-modal click-handler action params]
|
||||||
(fn [row _ _]
|
(fn [row _ _]
|
||||||
(list-item
|
(list-item
|
||||||
(if chat-modal
|
[contact-view {:contact row
|
||||||
[contact-view-with-letter row click-handler action params]
|
:letter? chat-modal
|
||||||
[contact-view row
|
:on-click (if click-handler
|
||||||
(or click-handler
|
#(click-handler row action params))}])))
|
||||||
(on-press row))]))))
|
|
||||||
|
|
||||||
(defn contact-list-entry [{:keys [click-handler icon icon-style label]}]
|
(defn contact-list-entry [{:keys [click-handler icon icon-style label]}]
|
||||||
[touchable-highlight
|
[touchable-highlight
|
||||||
|
@ -71,14 +69,10 @@
|
||||||
:t/contacts-group-dapps
|
:t/contacts-group-dapps
|
||||||
:t/contacts-group-new-chat)))
|
:t/contacts-group-new-chat)))
|
||||||
:nav-action (when modal
|
:nav-action (when modal
|
||||||
{:handler #(dispatch [:navigate-back])
|
(act/back #(dispatch [:navigate-back])))
|
||||||
:image {:source {:uri :icon_back}
|
|
||||||
:style icon-back}})
|
|
||||||
:background-color toolbar-background1
|
:background-color toolbar-background1
|
||||||
:style (get-in platform-specific [:component-styles :toolbar])
|
:style (get-in platform-specific [:component-styles :toolbar])
|
||||||
:actions [{:image {:source {:uri :icon_search}
|
:actions [(act/search #())]}]])
|
||||||
:style icon-search}
|
|
||||||
:handler (fn [])}]}]])
|
|
||||||
|
|
||||||
(defview contact-list []
|
(defview contact-list []
|
||||||
[contacts [:contacts-with-letters]
|
[contacts [:contacts-with-letters]
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
[status-im.utils.identicon :refer [identicon]]
|
[status-im.utils.identicon :refer [identicon]]
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.components.toolbar.styles :refer [toolbar-title-container
|
[status-im.components.toolbar.styles :refer [toolbar-title-container
|
||||||
toolbar-title-text
|
toolbar-title-text
|
||||||
toolbar-background1]]
|
toolbar-background1]]
|
||||||
|
@ -24,6 +25,7 @@
|
||||||
[cljs.spec :as s]
|
[cljs.spec :as s]
|
||||||
[status-im.contacts.validations :as v]
|
[status-im.contacts.validations :as v]
|
||||||
[status-im.contacts.styles :as st]
|
[status-im.contacts.styles :as st]
|
||||||
|
[status-im.data-store.contacts :as contacts]
|
||||||
[status-im.utils.gfycat.core :refer [generate-gfy]]
|
[status-im.utils.gfycat.core :refer [generate-gfy]]
|
||||||
[status-im.utils.hex :refer [normalize-hex]]
|
[status-im.utils.hex :refer [normalize-hex]]
|
||||||
[status-im.utils.platform :refer [platform-specific]]))
|
[status-im.utils.platform :refer [platform-specific]]))
|
||||||
|
@ -44,11 +46,15 @@
|
||||||
:address id
|
:address id
|
||||||
:photo-path (identicon whisper-identity)
|
:photo-path (identicon whisper-identity)
|
||||||
:whisper-identity whisper-identity}]
|
:whisper-identity whisper-identity}]
|
||||||
(dispatch [:add-new-contact contact]))
|
(if (contacts/exists? whisper-identity)
|
||||||
|
(dispatch [:add-pending-contact whisper-identity])
|
||||||
|
(dispatch [:add-new-contact contact])))
|
||||||
(dispatch [:set :new-contact-public-key-error (label :t/unknown-address)]))))
|
(dispatch [:set :new-contact-public-key-error (label :t/unknown-address)]))))
|
||||||
|
(if (contacts/exists? id)
|
||||||
|
(dispatch [:add-pending-contact id])
|
||||||
(dispatch [:add-new-contact {:name (generate-gfy)
|
(dispatch [:add-new-contact {:name (generate-gfy)
|
||||||
:photo-path (identicon id)
|
:photo-path (identicon id)
|
||||||
:whisper-identity id}])))
|
:whisper-identity id}]))))
|
||||||
|
|
||||||
(defn- validation-error-message
|
(defn- validation-error-message
|
||||||
[whisper-identity {:keys [address public-key]} error]
|
[whisper-identity {:keys [address public-key]} error]
|
||||||
|
@ -57,7 +63,7 @@
|
||||||
(normalize-hex whisper-identity))
|
(normalize-hex whisper-identity))
|
||||||
(label :t/can-not-add-yourself)
|
(label :t/can-not-add-yourself)
|
||||||
|
|
||||||
(not (s/valid? ::v/unique-identity whisper-identity))
|
(not (s/valid? ::v/contact-can-be-added whisper-identity))
|
||||||
(label :t/contact-already-added)
|
(label :t/contact-already-added)
|
||||||
|
|
||||||
(not (s/valid? ::v/whisper-identity whisper-identity))
|
(not (s/valid? ::v/whisper-identity whisper-identity))
|
||||||
|
@ -103,9 +109,7 @@
|
||||||
[status-bar]
|
[status-bar]
|
||||||
[toolbar {:background-color toolbar-background1
|
[toolbar {:background-color toolbar-background1
|
||||||
:style (get-in platform-specific [:component-styles :toolbar])
|
:style (get-in platform-specific [:component-styles :toolbar])
|
||||||
:nav-action {:image {:source {:uri :icon_back}
|
:nav-action (act/back #(dispatch [:navigate-back]))
|
||||||
:style icon-back}
|
|
||||||
:handler #(dispatch [:navigate-back])}
|
|
||||||
:title (label :t/add-new-contact)
|
:title (label :t/add-new-contact)
|
||||||
:actions (toolbar-actions new-contact-identity account error)}]
|
:actions (toolbar-actions new-contact-identity account error)}]
|
||||||
[view st/form-container
|
[view st/form-container
|
||||||
|
|
|
@ -9,19 +9,15 @@
|
||||||
|
|
||||||
(defn get-by-id
|
(defn get-by-id
|
||||||
[whisper-identity]
|
[whisper-identity]
|
||||||
(data-store/get-by-id whisper-identity))
|
(data-store/get-by-id-cljs whisper-identity))
|
||||||
|
|
||||||
(defn save
|
(defn save
|
||||||
[{:keys [whisper-identity pending] :as contact}]
|
[{:keys [whisper-identity pending] :as contact}]
|
||||||
(let [{pending-db :pending
|
(let [{pending-db :pending
|
||||||
:as contact-db} (data-store/get-by-id whisper-identity)
|
:as contact-db} (data-store/get-by-id whisper-identity)
|
||||||
contact (assoc contact :pending (boolean (if contact-db
|
contact (assoc contact :pending
|
||||||
;; TODO:
|
(boolean (if contact-db
|
||||||
;; this is temporary fix for pending users
|
(if (nil? pending) pending-db pending)
|
||||||
;; we need to change this (if ...) to (and pending-db pending)
|
|
||||||
(if (nil? pending)
|
|
||||||
pending-db
|
|
||||||
(and pending-db pending))
|
|
||||||
pending)))]
|
pending)))]
|
||||||
(data-store/save contact (if contact-db true false))))
|
(data-store/save contact (if contact-db true false))))
|
||||||
|
|
||||||
|
@ -29,6 +25,9 @@
|
||||||
[contacts]
|
[contacts]
|
||||||
(mapv save contacts))
|
(mapv save contacts))
|
||||||
|
|
||||||
|
(defn delete [contact]
|
||||||
|
(data-store/delete contact))
|
||||||
|
|
||||||
(defn exists?
|
(defn exists?
|
||||||
[whisper-identity]
|
[whisper-identity]
|
||||||
(data-store/exists? whisper-identity))
|
(data-store/exists? whisper-identity))
|
|
@ -0,0 +1,15 @@
|
||||||
|
(ns status-im.data-store.processed-messages
|
||||||
|
(:require [status-im.data-store.realm.processed-messages :as data-store]
|
||||||
|
[taoensso.timbre :as log])
|
||||||
|
(:refer-clojure :exclude [exists?]))
|
||||||
|
|
||||||
|
(defn get-filtered
|
||||||
|
[condition]
|
||||||
|
(data-store/get-filtered-as-list condition))
|
||||||
|
|
||||||
|
(defn save
|
||||||
|
[processed-message]
|
||||||
|
(data-store/save processed-message))
|
||||||
|
|
||||||
|
(defn delete [condition]
|
||||||
|
(data-store/delete condition))
|
|
@ -14,12 +14,21 @@
|
||||||
|
|
||||||
(defn get-by-id
|
(defn get-by-id
|
||||||
[whisper-identity]
|
[whisper-identity]
|
||||||
(realm/get-one-by-field-clj @realm/account-realm :contact :whisper-identity whisper-identity))
|
(realm/get-one-by-field @realm/account-realm :contact :whisper-identity whisper-identity))
|
||||||
|
|
||||||
|
(defn get-by-id-cljs
|
||||||
|
[whisper-identity]
|
||||||
|
(some-> (get-by-id whisper-identity)
|
||||||
|
(js->clj :keywordize-keys true)))
|
||||||
|
|
||||||
(defn save
|
(defn save
|
||||||
[contact update?]
|
[contact update?]
|
||||||
(realm/save @realm/account-realm :contact contact update?))
|
(realm/save @realm/account-realm :contact contact update?))
|
||||||
|
|
||||||
|
(defn delete
|
||||||
|
[{:keys [whisper-identity]}]
|
||||||
|
(realm/delete @realm/account-realm (get-by-id whisper-identity)))
|
||||||
|
|
||||||
(defn exists?
|
(defn exists?
|
||||||
[whisper-identity]
|
[whisper-identity]
|
||||||
(realm/exists? @realm/account-realm :contact {:whisper-identity whisper-identity}))
|
(realm/exists? @realm/account-realm :contact {:whisper-identity whisper-identity}))
|
|
@ -0,0 +1,25 @@
|
||||||
|
(ns status-im.data-store.realm.processed-messages
|
||||||
|
(:require [status-im.data-store.realm.core :as realm])
|
||||||
|
(:refer-clojure :exclude [exists?]))
|
||||||
|
|
||||||
|
(defn get-all
|
||||||
|
[]
|
||||||
|
(-> (realm/get-all @realm/account-realm :processed-message)
|
||||||
|
(realm/sorted :ttl :asc)))
|
||||||
|
|
||||||
|
(defn get-filtered
|
||||||
|
[condition]
|
||||||
|
(realm/filtered (get-all) condition))
|
||||||
|
|
||||||
|
(defn get-filtered-as-list
|
||||||
|
[condition]
|
||||||
|
(-> (get-filtered condition)
|
||||||
|
realm/realm-collection->list))
|
||||||
|
|
||||||
|
(defn save
|
||||||
|
[processed-message]
|
||||||
|
(realm/save @realm/account-realm :processed-message processed-message))
|
||||||
|
|
||||||
|
(defn delete
|
||||||
|
[condition]
|
||||||
|
(realm/delete @realm/account-realm (get-filtered condition)))
|
|
@ -7,6 +7,7 @@
|
||||||
[status-im.data-store.realm.schemas.account.v1.kv-store :as kv-store]
|
[status-im.data-store.realm.schemas.account.v1.kv-store :as kv-store]
|
||||||
[status-im.data-store.realm.schemas.account.v1.message :as message]
|
[status-im.data-store.realm.schemas.account.v1.message :as message]
|
||||||
[status-im.data-store.realm.schemas.account.v1.pending-message :as pending-message]
|
[status-im.data-store.realm.schemas.account.v1.pending-message :as pending-message]
|
||||||
|
[status-im.data-store.realm.schemas.account.v1.processed-message :as processed-message]
|
||||||
[status-im.data-store.realm.schemas.account.v1.request :as request]
|
[status-im.data-store.realm.schemas.account.v1.request :as request]
|
||||||
[status-im.data-store.realm.schemas.account.v1.tag :as tag]
|
[status-im.data-store.realm.schemas.account.v1.tag :as tag]
|
||||||
[status-im.data-store.realm.schemas.account.v1.user-status :as user-status]
|
[status-im.data-store.realm.schemas.account.v1.user-status :as user-status]
|
||||||
|
@ -20,6 +21,7 @@
|
||||||
kv-store/schema
|
kv-store/schema
|
||||||
message/schema
|
message/schema
|
||||||
pending-message/schema
|
pending-message/schema
|
||||||
|
processed-message/schema
|
||||||
request/schema
|
request/schema
|
||||||
tag/schema
|
tag/schema
|
||||||
user-status/schema])
|
user-status/schema])
|
||||||
|
@ -34,6 +36,7 @@
|
||||||
(kv-store/migration old-realm new-realm)
|
(kv-store/migration old-realm new-realm)
|
||||||
(message/migration old-realm new-realm)
|
(message/migration old-realm new-realm)
|
||||||
(pending-message/migration old-realm new-realm)
|
(pending-message/migration old-realm new-realm)
|
||||||
|
(processed-message/migration old-realm new-realm)
|
||||||
(request/migration old-realm new-realm)
|
(request/migration old-realm new-realm)
|
||||||
(tag/migration old-realm new-realm)
|
(tag/migration old-realm new-realm)
|
||||||
(user-status/migration old-realm new-realm))
|
(user-status/migration old-realm new-realm))
|
|
@ -0,0 +1,13 @@
|
||||||
|
(ns status-im.data-store.realm.schemas.account.v1.processed-message
|
||||||
|
(:require [taoensso.timbre :as log]))
|
||||||
|
|
||||||
|
(def schema {:name :processed-message
|
||||||
|
:primaryKey :id
|
||||||
|
:properties {:id :string
|
||||||
|
:message-id :string
|
||||||
|
:type {:type "string"
|
||||||
|
:optional true}
|
||||||
|
:ttl :int}})
|
||||||
|
|
||||||
|
(defn migration [old-realm new-realm]
|
||||||
|
(log/debug "migrating processed-message schema"))
|
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
(defmethod nav/preload-data! :discover
|
(defmethod nav/preload-data! :discover
|
||||||
[db _]
|
[db _]
|
||||||
(dispatch [:set :discover-show-search? false])
|
|
||||||
(-> db
|
(-> db
|
||||||
|
(assoc-in [:toolbar-search :show] nil)
|
||||||
(assoc :tags (discoveries/get-all-tags))
|
(assoc :tags (discoveries/get-all-tags))
|
||||||
(assoc :discoveries (->> (discoveries/get-all :desc)
|
(assoc :discoveries (->> (discoveries/get-all :desc)
|
||||||
(map (fn [{:keys [message-id] :as discover}]
|
(map (fn [{:keys [message-id] :as discover}]
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.discover.screen
|
(ns status-im.discover.screen
|
||||||
(:require-macros [status-im.utils.views :refer [defview]])
|
(:require-macros [status-im.utils.views :refer [defview]])
|
||||||
(:require
|
(:require
|
||||||
|
[reagent.core :as r]
|
||||||
[re-frame.core :refer [dispatch subscribe]]
|
[re-frame.core :refer [dispatch subscribe]]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
|
@ -8,52 +9,33 @@
|
||||||
text
|
text
|
||||||
text-input
|
text-input
|
||||||
icon]]
|
icon]]
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar-with-search]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.components.drawer.view :refer [open-drawer]]
|
[status-im.components.drawer.view :refer [open-drawer]]
|
||||||
[status-im.discover.styles :as st]
|
|
||||||
[status-im.i18n :refer [label]]
|
|
||||||
[status-im.components.carousel.carousel :refer [carousel]]
|
[status-im.components.carousel.carousel :refer [carousel]]
|
||||||
[status-im.discover.views.popular-list :refer [discover-popular-list]]
|
[status-im.discover.views.popular-list :refer [discover-popular-list]]
|
||||||
[status-im.discover.views.discover-list-item :refer [discover-list-item]]
|
[status-im.discover.views.discover-list-item :refer [discover-list-item]]
|
||||||
[status-im.contacts.styles :as contacts-styles]
|
|
||||||
[status-im.utils.platform :refer [platform-specific]]
|
[status-im.utils.platform :refer [platform-specific]]
|
||||||
[reagent.core :as r]))
|
[status-im.i18n :refer [label]]
|
||||||
|
[status-im.discover.styles :as st]
|
||||||
|
[status-im.contacts.styles :as contacts-st]))
|
||||||
|
|
||||||
(defn get-hashtags [status]
|
(defn get-hashtags [status]
|
||||||
(let [hashtags (map #(str/lower-case (str/replace % #"#" "")) (re-seq #"[^ !?,;:.]+" status))]
|
(let [hashtags (map #(str/lower-case (str/replace % #"#" "")) (re-seq #"[^ !?,;:.]+" status))]
|
||||||
(or hashtags [])))
|
(or hashtags [])))
|
||||||
|
|
||||||
(defn title-content [show-search?]
|
(defn toolbar-view [show-search?]
|
||||||
[view st/discover-toolbar-content
|
[toolbar-with-search
|
||||||
(if show-search?
|
{:show-search? show-search?
|
||||||
[text-input {:style st/discover-search-input
|
:search-key :discover
|
||||||
:auto-focus true
|
:title (label :t/discover)
|
||||||
:placeholder (label :t/search-tags)
|
:search-placeholder (label :t/search-tags)
|
||||||
:on-blur (fn [e]
|
:nav-action (act/hamburger open-drawer)
|
||||||
(dispatch [:set :discover-show-search? false]))
|
:on-search-submit (fn [text]
|
||||||
:on-submit-editing (fn [e]
|
(when-not (str/blank? text)
|
||||||
(let [search (aget e "nativeEvent" "text")
|
(let [hashtags (get-hashtags text)]
|
||||||
hashtags (get-hashtags search)]
|
|
||||||
(dispatch [:set :discover-search-tags hashtags])
|
(dispatch [:set :discover-search-tags hashtags])
|
||||||
(dispatch [:navigate-to :discover-search-results])))}]
|
(dispatch [:navigate-to :discover-search-results]))))}])
|
||||||
[view
|
|
||||||
[text {:style st/discover-title
|
|
||||||
:font :toolbar-title}
|
|
||||||
(label :t/discover)]])])
|
|
||||||
|
|
||||||
(defn toogle-search [current-value]
|
|
||||||
(dispatch [:set :discover-show-search? (not current-value)]))
|
|
||||||
|
|
||||||
(defn discover-toolbar [show-search?]
|
|
||||||
[toolbar
|
|
||||||
{:style st/discover-toolbar
|
|
||||||
:nav-action {:image {:source {:uri :icon_hamburger}
|
|
||||||
:style st/hamburger-icon}
|
|
||||||
:handler open-drawer}
|
|
||||||
:custom-content [title-content show-search?]
|
|
||||||
:actions [{:image {:source {:uri :icon_search}
|
|
||||||
:style st/search-icon}
|
|
||||||
:handler #(toogle-search show-search?)}]}])
|
|
||||||
|
|
||||||
(defn title [label-kw spacing?]
|
(defn title [label-kw spacing?]
|
||||||
[view st/section-spacing
|
[view st/section-spacing
|
||||||
|
@ -91,19 +73,20 @@
|
||||||
:current-account current-account}]))]]))
|
:current-account current-account}]))]]))
|
||||||
|
|
||||||
(defview discover [current-view?]
|
(defview discover [current-view?]
|
||||||
[show-search? [:get :discover-show-search?]
|
[show-search [:get-in [:toolbar-search :show]]
|
||||||
contacts [:get :contacts]
|
contacts [:get :contacts]
|
||||||
current-account [:get-current-account]
|
current-account [:get-current-account]
|
||||||
discoveries [:get-recent-discoveries]]
|
discoveries [:get-recent-discoveries]]
|
||||||
[view st/discover-container
|
[view st/discover-container
|
||||||
[discover-toolbar (and current-view? show-search?)]
|
[toolbar-view (and current-view?
|
||||||
|
(= show-search :discover))]
|
||||||
(if discoveries
|
(if discoveries
|
||||||
[scroll-view st/scroll-view-container
|
[scroll-view st/scroll-view-container
|
||||||
[discover-popular {:contacts contacts
|
[discover-popular {:contacts contacts
|
||||||
:current-account current-account}]
|
:current-account current-account}]
|
||||||
[discover-recent {:current-account current-account}]]
|
[discover-recent {:current-account current-account}]]
|
||||||
[view contacts-styles/empty-contact-groups
|
[view contacts-st/empty-contact-groups
|
||||||
;; todo change icon
|
;; todo change icon
|
||||||
[icon :group_big contacts-styles/empty-contacts-icon]
|
[icon :group_big contacts-st/empty-contacts-icon]
|
||||||
[text {:style contacts-styles/empty-contacts-text}
|
[text {:style contacts-st/empty-contacts-text}
|
||||||
(label :t/no-statuses-discovered)]])])
|
(label :t/no-statuses-discovered)]])])
|
||||||
|
|
|
@ -9,12 +9,13 @@
|
||||||
list-view
|
list-view
|
||||||
list-item
|
list-item
|
||||||
scroll-view]]
|
scroll-view]]
|
||||||
[status-im.i18n :refer [label]]
|
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.discover.views.discover-list-item :refer [discover-list-item]]
|
[status-im.discover.views.discover-list-item :refer [discover-list-item]]
|
||||||
[status-im.discover.styles :as st]
|
|
||||||
[status-im.utils.platform :refer [platform-specific]]
|
[status-im.utils.platform :refer [platform-specific]]
|
||||||
[status-im.contacts.styles :as contacts-styles]
|
[status-im.i18n :refer [label]]
|
||||||
|
[status-im.discover.styles :as st]
|
||||||
|
[status-im.contacts.styles :as contacts-st]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
(defn render-separator [_ row-id _]
|
(defn render-separator [_ row-id _]
|
||||||
|
@ -43,20 +44,19 @@
|
||||||
datasource (to-datasource discoveries)]
|
datasource (to-datasource discoveries)]
|
||||||
[view st/discover-tag-container
|
[view st/discover-tag-container
|
||||||
[status-bar]
|
[status-bar]
|
||||||
[toolbar {:nav-action {:image {:source {:uri :icon_back}
|
[toolbar {:nav-action (act/back #(dispatch [:navigate-back]))
|
||||||
:style st/icon-back}
|
|
||||||
:handler #(dispatch [:navigate-back])}
|
|
||||||
:custom-content (title-content tags)
|
:custom-content (title-content tags)
|
||||||
:style st/discover-tag-toolbar}]
|
:style st/discover-tag-toolbar}]
|
||||||
(if (empty? discoveries)
|
(if (empty? discoveries)
|
||||||
[view st/empty-view
|
[view st/empty-view
|
||||||
;; todo change icon
|
;; todo change icon
|
||||||
[icon :group_big contacts-styles/empty-contacts-icon]
|
[icon :group_big contacts-st/empty-contacts-icon]
|
||||||
[text {:style contacts-styles/empty-contacts-text}
|
[text {:style contacts-st/empty-contacts-text}
|
||||||
(label :t/no-statuses-found)]]
|
(label :t/no-statuses-found)]]
|
||||||
[list-view {:dataSource datasource
|
[list-view {:dataSource datasource
|
||||||
:renderRow (fn [row _ _]
|
:renderRow (fn [row _ _]
|
||||||
(list-item [discover-list-item {:message row
|
(list-item [discover-list-item
|
||||||
|
{:message row
|
||||||
:current-account current-account}]))
|
:current-account current-account}]))
|
||||||
:renderSeparator render-separator
|
:renderSeparator render-separator
|
||||||
:style st/recent-list}])]))
|
:style st/recent-list}])]))
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
(ns status-im.discover.styles
|
(ns status-im.discover.styles
|
||||||
(:require [status-im.components.styles :refer [color-gray2
|
(:require [status-im.components.styles :refer [color-gray2
|
||||||
color-white]]
|
color-white
|
||||||
|
color-light-gray]]
|
||||||
[status-im.components.toolbar.styles :refer [toolbar-background2]]))
|
[status-im.components.toolbar.styles :refer [toolbar-background2]]))
|
||||||
|
|
||||||
;; common
|
;; Common
|
||||||
|
|
||||||
(def row-separator
|
(def row-separator
|
||||||
{:border-bottom-width 1
|
{:border-bottom-width 1
|
||||||
|
@ -22,30 +23,6 @@
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:justify-content :center})
|
:justify-content :center})
|
||||||
|
|
||||||
;; Toolbar
|
|
||||||
|
|
||||||
(def discover-toolbar-content
|
|
||||||
{:flex 1
|
|
||||||
:align-items :center
|
|
||||||
:justify-content :center})
|
|
||||||
|
|
||||||
(def discover-toolbar
|
|
||||||
{:background-color toolbar-background2
|
|
||||||
:elevation 0})
|
|
||||||
|
|
||||||
(def discover-search-input
|
|
||||||
{:flex 1
|
|
||||||
:align-self "stretch"
|
|
||||||
:margin-left 18
|
|
||||||
:font-size 14
|
|
||||||
:color "#7099e6"})
|
|
||||||
|
|
||||||
(def discover-title
|
|
||||||
{:color "#000000de"
|
|
||||||
:align-self :center
|
|
||||||
:text-align :center
|
|
||||||
:font-size 16})
|
|
||||||
|
|
||||||
(def section-spacing
|
(def section-spacing
|
||||||
{:padding 16})
|
{:padding 16})
|
||||||
|
|
||||||
|
@ -134,7 +111,7 @@
|
||||||
|
|
||||||
(def discover-tag-container
|
(def discover-tag-container
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:backgroundColor "#eef2f5"})
|
:backgroundColor color-light-gray})
|
||||||
|
|
||||||
(def tag-title-scroll
|
(def tag-title-scroll
|
||||||
{:flex 1
|
{:flex 1
|
||||||
|
@ -165,10 +142,6 @@
|
||||||
{:flex 1
|
{:flex 1
|
||||||
:backgroundColor color-white})
|
:backgroundColor color-white})
|
||||||
|
|
||||||
(def hamburger-icon
|
|
||||||
{:width 16
|
|
||||||
:height 12})
|
|
||||||
|
|
||||||
(def search-icon
|
(def search-icon
|
||||||
{:width 17
|
{:width 17
|
||||||
:height 17})
|
:height 17})
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
(ns status-im.group-settings.views.member
|
(ns status-im.group-settings.views.member
|
||||||
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
[status-im.contacts.views.contact :refer [contact-extended-view]]
|
[status-im.contacts.views.contact :refer [contact-view]]
|
||||||
[status-im.i18n :refer [label]]))
|
[status-im.i18n :refer [label]]))
|
||||||
|
|
||||||
(defn member-view [{:keys [whisper-identity role] :as contact}]
|
(defn member-view [{:keys [whisper-identity role] :as contact}]
|
||||||
;; TODO implement :role property for group chat contact
|
;; TODO implement :role property for group chat contact
|
||||||
[contact-extended-view contact role
|
[contact-view
|
||||||
#(dispatch [:set :selected-participants #{whisper-identity}])])
|
{:contact contact
|
||||||
|
:extended? true
|
||||||
|
:info role
|
||||||
|
:on-click #(dispatch [:set :selected-participants #{whisper-identity}])}])
|
||||||
|
|
|
@ -68,6 +68,7 @@
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
(fn [_ [_ address]]
|
(fn [_ [_ address]]
|
||||||
(dispatch [:initialize-account-db])
|
(dispatch [:initialize-account-db])
|
||||||
|
(dispatch [:load-processed-messages])
|
||||||
(dispatch [:initialize-protocol address])
|
(dispatch [:initialize-protocol address])
|
||||||
(dispatch [:initialize-sync-listener])
|
(dispatch [:initialize-sync-listener])
|
||||||
(dispatch [:initialize-chats])
|
(dispatch [:initialize-chats])
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
orientation
|
orientation
|
||||||
splash-screen]]
|
splash-screen]]
|
||||||
[status-im.components.main-tabs :refer [main-tabs]]
|
[status-im.components.main-tabs :refer [main-tabs]]
|
||||||
|
[status-im.contacts.search-results :refer [contacts-search-results]]
|
||||||
[status-im.contacts.views.contact-list :refer [contact-list]]
|
[status-im.contacts.views.contact-list :refer [contact-list]]
|
||||||
[status-im.contacts.views.new-contact :refer [new-contact]]
|
[status-im.contacts.views.new-contact :refer [new-contact]]
|
||||||
[status-im.qr-scanner.screen :refer [qr-scanner]]
|
[status-im.qr-scanner.screen :refer [qr-scanner]]
|
||||||
|
@ -82,6 +83,7 @@
|
||||||
:new-group new-group
|
:new-group new-group
|
||||||
:group-settings group-settings
|
:group-settings group-settings
|
||||||
:contact-list main-tabs
|
:contact-list main-tabs
|
||||||
|
:contact-list-search-results contacts-search-results
|
||||||
:group-contacts contact-list
|
:group-contacts contact-list
|
||||||
:new-contact new-contact
|
:new-contact new-contact
|
||||||
:qr-scanner qr-scanner
|
:qr-scanner qr-scanner
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
[status-im.components.icons.custom-icons :refer [ion-icon]]
|
[status-im.components.icons.custom-icons :refer [ion-icon]]
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.components.toolbar.styles :refer [toolbar-background1]]
|
[status-im.components.toolbar.styles :refer [toolbar-background1]]
|
||||||
[status-im.utils.image-processing :refer [img->base64]]
|
[status-im.utils.image-processing :refer [img->base64]]
|
||||||
[status-im.profile.photo-capture.styles :as st]
|
[status-im.profile.photo-capture.styles :as st]
|
||||||
|
@ -35,9 +36,7 @@
|
||||||
[view st/container
|
[view st/container
|
||||||
[status-bar]
|
[status-bar]
|
||||||
[toolbar {:title (label :t/image-source-title)
|
[toolbar {:title (label :t/image-source-title)
|
||||||
:nav-action {:image {:source {:uri :icon_back}
|
:nav-action (act/back #(dispatch [:navigate-back]))
|
||||||
:style icon-back}
|
|
||||||
:handler #(dispatch [:navigate-back])}
|
|
||||||
:background-color toolbar-background1}]
|
:background-color toolbar-background1}]
|
||||||
[camera {:style {:flex 1}
|
[camera {:style {:flex 1}
|
||||||
:aspect (:fill aspects)
|
:aspect (:fill aspects)
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
;; discoveries
|
;; discoveries
|
||||||
(def watch-user! discoveries/watch-user!)
|
(def watch-user! discoveries/watch-user!)
|
||||||
|
(def stop-watching-user! discoveries/stop-watching-user!)
|
||||||
(def contact-request! discoveries/contact-request!)
|
(def contact-request! discoveries/contact-request!)
|
||||||
(def broadcast-profile! discoveries/broadcast-profile!)
|
(def broadcast-profile! discoveries/broadcast-profile!)
|
||||||
(def send-status! discoveries/send-status!)
|
(def send-status! discoveries/send-status!)
|
||||||
|
|
|
@ -46,6 +46,13 @@
|
||||||
:topics [(make-discover-topic identity)]}
|
:topics [(make-discover-topic identity)]}
|
||||||
(l/message-listener (dissoc options :identity))))
|
(l/message-listener (dissoc options :identity))))
|
||||||
|
|
||||||
|
(defn stop-watching-user!
|
||||||
|
[{:keys [web3 identity] :as options}]
|
||||||
|
(f/remove-filter!
|
||||||
|
web3
|
||||||
|
{:from identity
|
||||||
|
:topics [(make-discover-topic identity)]}))
|
||||||
|
|
||||||
(s/def :contact-request/contact map?)
|
(s/def :contact-request/contact map?)
|
||||||
|
|
||||||
(s/def :contact-request/payload
|
(s/def :contact-request/payload
|
||||||
|
|
|
@ -5,12 +5,15 @@
|
||||||
[status-im.data-store.contacts :as contacts]
|
[status-im.data-store.contacts :as contacts]
|
||||||
[status-im.data-store.messages :as messages]
|
[status-im.data-store.messages :as messages]
|
||||||
[status-im.data-store.pending-messages :as pending-messages]
|
[status-im.data-store.pending-messages :as pending-messages]
|
||||||
|
[status-im.data-store.processed-messages :as processed-messages]
|
||||||
[status-im.data-store.chats :as chats]
|
[status-im.data-store.chats :as chats]
|
||||||
[status-im.protocol.core :as protocol]
|
[status-im.protocol.core :as protocol]
|
||||||
[status-im.constants :refer [text-content-type
|
[status-im.constants :refer [text-content-type
|
||||||
blocks-per-hour]]
|
blocks-per-hour]]
|
||||||
[status-im.i18n :refer [label]]
|
[status-im.i18n :refer [label]]
|
||||||
[status-im.utils.random :as random]
|
[status-im.utils.random :as random]
|
||||||
|
[status-im.protocol.message-cache :as cache]
|
||||||
|
[status-im.utils.datetime :as dt]
|
||||||
[taoensso.timbre :as log :refer-macros [debug]]
|
[taoensso.timbre :as log :refer-macros [debug]]
|
||||||
[status-im.constants :as c]
|
[status-im.constants :as c]
|
||||||
[status-im.components.status :as status]))
|
[status-im.components.status :as status]))
|
||||||
|
@ -77,8 +80,16 @@
|
||||||
|
|
||||||
(register-handler :incoming-message
|
(register-handler :incoming-message
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
(fn [_ [_ type {:keys [payload] :as message}]]
|
(fn [_ [_ type {:keys [payload ttl id] :as message}]]
|
||||||
(debug :incoming-message type)
|
(let [message-id (or id (:message-id payload))]
|
||||||
|
(when-not (cache/exists? message-id type)
|
||||||
|
(let [ttl-s (* 1000 (or ttl 120))
|
||||||
|
processed-message {:id (random/id)
|
||||||
|
:message-id message-id
|
||||||
|
:type type
|
||||||
|
:ttl (+ (dt/now-ms) ttl-s)}]
|
||||||
|
(cache/add! processed-message)
|
||||||
|
(processed-messages/save processed-message))
|
||||||
(case type
|
(case type
|
||||||
:message (dispatch [:received-protocol-message! message])
|
:message (dispatch [:received-protocol-message! message])
|
||||||
:group-message (dispatch [:received-protocol-message! message])
|
:group-message (dispatch [:received-protocol-message! message])
|
||||||
|
@ -103,7 +114,7 @@
|
||||||
:payload {:message-id id
|
:payload {:message-id id
|
||||||
:group-id group-id}}]
|
:group-id group-id}}]
|
||||||
(dispatch [:message-sent message']))
|
(dispatch [:message-sent message']))
|
||||||
(debug "Unknown message type" type)))))
|
(debug "Unknown message type" type)))))))
|
||||||
|
|
||||||
(defn system-message
|
(defn system-message
|
||||||
([message-id timestamp content]
|
([message-id timestamp content]
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
(ns status-im.protocol.message-cache)
|
||||||
|
|
||||||
|
(defonce messages-set (atom #{}))
|
||||||
|
(defonce messages-map (atom {}))
|
||||||
|
|
||||||
|
(defn init!
|
||||||
|
[messages]
|
||||||
|
(reset! messages-set (into #{} messages))
|
||||||
|
(reset! messages-map (->> messages
|
||||||
|
(map (fn [{:keys [message-id type] :as message}]
|
||||||
|
[[message-id type] message]))
|
||||||
|
(into {}))))
|
||||||
|
|
||||||
|
(defn add!
|
||||||
|
[{:keys [message-id type] :as message}]
|
||||||
|
(swap! messages-set conj message)
|
||||||
|
(swap! messages-map conj [[message-id type] message]))
|
||||||
|
|
||||||
|
(defn exists?
|
||||||
|
[message-id type]
|
||||||
|
(get @messages-map [message-id type]))
|
|
@ -28,7 +28,8 @@
|
||||||
(assoc :content content')
|
(assoc :content content')
|
||||||
prn-str
|
prn-str
|
||||||
u/from-utf8)]
|
u/from-utf8)]
|
||||||
(-> message (select-keys [:from :to :topics :ttl])
|
(-> message
|
||||||
|
(select-keys [:from :to :topics :ttl])
|
||||||
(assoc :payload payload'))))
|
(assoc :payload payload'))))
|
||||||
|
|
||||||
(s/def :shh/pending-message
|
(s/def :shh/pending-message
|
||||||
|
@ -110,7 +111,7 @@
|
||||||
(let [message (get-in messages [id to])
|
(let [message (get-in messages [id to])
|
||||||
message' (when message
|
message' (when message
|
||||||
(assoc message :was-sent? true
|
(assoc message :was-sent? true
|
||||||
:attemps 1))]
|
:attempts 1))]
|
||||||
(if message'
|
(if message'
|
||||||
(assoc-in messages [id to] message')
|
(assoc-in messages [id to] message')
|
||||||
messages))))]
|
messages))))]
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
icon-back]]
|
icon-back]]
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.toolbar.view :refer [toolbar]]
|
[status-im.components.toolbar.view :refer [toolbar]]
|
||||||
|
[status-im.components.toolbar.actions :as act]
|
||||||
[status-im.components.toolbar.styles :refer [toolbar-background1]]
|
[status-im.components.toolbar.styles :refer [toolbar-background1]]
|
||||||
[status-im.qr-scanner.styles :as st]
|
[status-im.qr-scanner.styles :as st]
|
||||||
[status-im.utils.types :refer [json->clj]]
|
[status-im.utils.types :refer [json->clj]]
|
||||||
|
@ -20,12 +21,7 @@
|
||||||
[toolbar {:title title
|
[toolbar {:title title
|
||||||
:background-color toolbar-background1
|
:background-color toolbar-background1
|
||||||
:nav-action (when modal
|
:nav-action (when modal
|
||||||
{:handler #(dispatch [:navigate-back])
|
(act/back #(dispatch [:navigate-back])))}]])
|
||||||
:image {:source {:uri :icon_back}
|
|
||||||
:style icon-back}})
|
|
||||||
:actions [{:image {:source {:uri :icon_lock_white}
|
|
||||||
:style icon-search}
|
|
||||||
:handler #()}]}]])
|
|
||||||
|
|
||||||
(defview qr-scanner []
|
(defview qr-scanner []
|
||||||
[identifier [:get :current-qr-context]]
|
[identifier [:get :current-qr-context]]
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
:chat-name "Chat name"
|
:chat-name "Chat name"
|
||||||
:notifications-title "Notifications and sounds"
|
:notifications-title "Notifications and sounds"
|
||||||
:offline "Offline"
|
:offline "Offline"
|
||||||
|
:search-for "Search for..."
|
||||||
|
:cancel "Cancel"
|
||||||
|
|
||||||
;drawer
|
;drawer
|
||||||
:invite-friends "Invite friends"
|
:invite-friends "Invite friends"
|
||||||
|
@ -108,7 +110,6 @@
|
||||||
:new-group-chat "New group chat"
|
:new-group-chat "New group chat"
|
||||||
|
|
||||||
;discover
|
;discover
|
||||||
|
|
||||||
:discover "Discover"
|
:discover "Discover"
|
||||||
:none "None"
|
:none "None"
|
||||||
:search-tags "Type your search tags here"
|
:search-tags "Type your search tags here"
|
||||||
|
@ -123,6 +124,7 @@
|
||||||
;contacts
|
;contacts
|
||||||
:contacts "Contacts"
|
:contacts "Contacts"
|
||||||
:new-contact "New Contact"
|
:new-contact "New Contact"
|
||||||
|
:remove-contact "Remove contact"
|
||||||
:show-all "SHOW ALL"
|
:show-all "SHOW ALL"
|
||||||
:contacts-group-dapps "ÐApps"
|
:contacts-group-dapps "ÐApps"
|
||||||
:contacts-group-people "People"
|
:contacts-group-people "People"
|
||||||
|
|
Loading…
Reference in New Issue