diff --git a/.re-natal b/.re-natal
index 56b16e17bf..1455b14c43 100644
--- a/.re-natal
+++ b/.re-natal
@@ -15,6 +15,7 @@
"react-native-circle-checkbox",
"react-native-randombytes",
"dismissKeyboard",
+ "react-native-linear-gradient",
"react-native-android-sms-listener"
],
"imageDirs": [
diff --git a/README.md b/README.md
index 3635c7175e..107e330d6c 100644
--- a/README.md
+++ b/README.md
@@ -30,7 +30,7 @@ A Clojure library designed to ... well, that part is up to you.
adb reverse tcp:8081 tcp:8081
adb reverse tcp:3449 tcp:3449
react-native run-android
-
+(re-frame.core/dispatch [:set-signed-up true])
## License
diff --git a/android/app/build.gradle b/android/app/build.gradle
index a81c12cdc1..379551061c 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -128,6 +128,7 @@ dependencies {
compile "com.facebook.react:react-native:+" // From node_modules
compile project(':react-native-contacts')
compile project(':react-native-i18n')
+ compile project(':react-native-linear-gradient')
compile project(':ReactNativeAndroidSmsListener')
// compile(name:'geth', ext:'aar')
compile(group: 'status-im', name: 'android-geth', version: '1.4.0-201604110816-a97a114', ext: 'aar')
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index a7eb44af57..d8e1a14016 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -4,6 +4,7 @@
+
db
- (assoc :current-chat-id (or id current-chat-id))
- load-messages!
- init-chat))
+ (let [chat-id (or id current-chat-id)
+ messages (get-in db [:chats chat-id :messages])
+ db' (assoc db :current-chat-id chat-id)]
+ (if (seq messages)
+ db'
+ (-> db'
+ load-messages!
+ init-chat))))
(defn prepare-chat
[{:keys [contacts] :as db} [_ contcat-id]]
@@ -334,3 +340,45 @@
(register-handler :switch-command-suggestions
(fn [db [_]]
(suggestions/switch-command-suggestions db)))
+
+(defn remove-chat
+ [{:keys [current-chat-id] :as db} _]
+ (update db :chats dissoc current-chat-id))
+
+(defn notify-about-leaving!
+ [{:keys [current-chat-id]} _]
+ (api/leave-group-chat current-chat-id))
+
+; todo do we really need this message?
+(defn leaving-message!
+ [{:keys [current-chat-id]} _]
+ (messages/save-message
+ current-chat-id
+ {:from "system"
+ :msg-id (random/id)
+ :content "You left this chat"
+ :content-type text-content-type}))
+
+(defn delete-messages!
+ [{:keys [current-chat-id]} _]
+ (r/write
+ (fn []
+ (r/delete (r/get-by-field :msgs :chat-id current-chat-id)))))
+
+(defn delete-chat!
+ [{:keys [current-chat-id]} _]
+ (r/write
+ (fn []
+ (-> (r/get-by-field :chats :chat-id current-chat-id)
+ (r/single)
+ (r/delete)))))
+
+(register-handler :leave-group-chat
+ ;; todo oreder of operations tbd
+ (after (fn [_ _] (dispatch [:navigation-replace :chat-list])))
+ (-> remove-chat
+ ;; todo uncomment
+ ;((after notify-about-leaving!))
+ ;((after leaving-message!))
+ ((after delete-messages!))
+ ((after delete-chat!))))
diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs
index 8289fe7bb9..19723aba22 100644
--- a/src/status_im/chat/screen.cljs
+++ b/src/status_im/chat/screen.cljs
@@ -64,8 +64,8 @@
(defn on-action-selected [position]
(case position
- 0 (dispatch [:show-add-participants])
- 1 (dispatch [:show-remove-participants])
+ 0 (dispatch [:navigate-to :add-participants])
+ 1 (dispatch [:navigate-to :remove-participants])
2 (dispatch [:leave-group-chat])))
(defn overlay [{:keys [on-click-outside]} items]
diff --git a/src/status_im/chat/sign_up.cljs b/src/status_im/chat/sign_up.cljs
index 62f0df393a..ef855d0021 100644
--- a/src/status_im/chat/sign_up.cljs
+++ b/src/status_im/chat/sign_up.cljs
@@ -4,6 +4,7 @@
[status-im.persistence.simple-kv-store :as kv]
[status-im.protocol.state.storage :as s]
[status-im.models.chats :as c]
+ [status-im.components.styles :refer [default-chat-color]]
[status-im.utils.utils :refer [log on-error http-post toast]]
[status-im.utils.random :as random]
[status-im.utils.sms-listener :refer [add-sms-listener
@@ -192,6 +193,7 @@
(def console-chat
{:chat-id "console"
:name "console"
+ :color default-chat-color
:group-chat false
:is-active true
:timestamp (.getTime (js/Date.))
diff --git a/src/status_im/chats_list/screen.cljs b/src/status_im/chats_list/screen.cljs
index 700ee209b2..48babbcee1 100644
--- a/src/status_im/chats_list/screen.cljs
+++ b/src/status_im/chats_list/screen.cljs
@@ -1,11 +1,11 @@
(ns status-im.chats-list.screen
(:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [list-view
- list-item
- view
- text
- image
- touchable-highlight]]
+ list-item
+ view
+ text
+ image
+ touchable-highlight]]
[status-im.utils.listview :refer [to-datasource]]
[reagent.core :as r]
[status-im.chats-list.views.chat-list-item :refer [chat-list-item]]
@@ -15,10 +15,10 @@
[status-im.components.styles :refer [color-blue
toolbar-background2]]
[status-im.components.toolbar :refer [toolbar]]
+ [status-im.components.main-tabs :refer [main-tabs]]
[status-im.components.icons.ionicons :refer [icon]]
[status-im.chats-list.styles :as st]))
-
(defn chats-list-toolbar []
[toolbar {:nav-action {:image {:source {:uri :icon_hamburger}
:style st/hamburger-icon}
@@ -40,7 +40,9 @@
:renderRow (fn [row _ _]
(list-item [chat-list-item row]))
:style st/list-container}]
- [action-button {:buttonColor color-blue}
+ [action-button {:buttonColor color-blue
+ :offsetY 72
+ :offsetX 16}
[action-button-item
{:title "New Chat"
:buttonColor :#9b59b6
@@ -52,4 +54,5 @@
:buttonColor :#1abc9c
:onPress #(dispatch [:show-group-new])}
[icon {:name :person-stalker
- :style st/person-stalker-icon}]]]]])))
+ :style st/person-stalker-icon}]]]
+ [main-tabs]]])))
diff --git a/src/status_im/chats_list/styles.cljs b/src/status_im/chats_list/styles.cljs
index ca72f89042..0fae1d82fd 100644
--- a/src/status_im/chats_list/styles.cljs
+++ b/src/status_im/chats_list/styles.cljs
@@ -6,7 +6,8 @@
online-color
text1-color
text2-color
- new-messages-count-color]]))
+ new-messages-count-color]]
+ [status-im.components.tabs.styles :refer [tab-height]]))
(def chat-container
{:flexDirection :row
@@ -102,7 +103,8 @@
:backgroundColor :white})
(def list-container
- {:backgroundColor :white})
+ {:backgroundColor :white
+ :marginBottom tab-height})
(def create-icon
{:fontSize 20
diff --git a/src/status_im/chats_list/views/chat_list_item.cljs b/src/status_im/chats_list/views/chat_list_item.cljs
index 215f392520..0c343f9b59 100644
--- a/src/status_im/chats_list/views/chat_list_item.cljs
+++ b/src/status_im/chats_list/views/chat_list_item.cljs
@@ -10,7 +10,7 @@
(defn chat-list-item [{:keys [chat-id] :as chat}]
[touchable-highlight
- {:on-press #(dispatch [:show-chat chat-id :push])}
+ {:on-press #(dispatch [:navigate-to :chat chat-id])}
[view [chat-list-item-inner-view (merge chat
;; TODO stub data
{:new-messages-count 3
diff --git a/src/status_im/components/main_tabs.cljs b/src/status_im/components/main_tabs.cljs
new file mode 100644
index 0000000000..5b8751b39d
--- /dev/null
+++ b/src/status_im/components/main_tabs.cljs
@@ -0,0 +1,30 @@
+(ns status-im.components.main-tabs
+ (:require-macros [status-im.utils.views :refer [defview]])
+ (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
+ [status-im.components.react :refer [view
+ text-input
+ text
+ image
+ touchable-highlight]]
+ [status-im.components.tabs.tabs :refer [tabs]]
+ [status-im.utils.logging :as log]))
+
+(defview main-tabs []
+ [view-id [:get :view-id]]
+ [tabs {:selected-index (case view-id
+ :chat-list 0
+ :discovery 1
+ :contact-list 2
+ 0)
+ :tab-list [{:handler #(dispatch [:navigate-to
+ :chat-list])
+ :title "Chats"
+ :icon :icon_tab_chats}
+ {:handler #(dispatch [:navigate-to
+ :discovery])
+ :title "Discover"
+ :icon :icon_tab_discovery}
+ {:handler #(dispatch [:navigate-to
+ :contact-list])
+ :title "Contacts"
+ :icon :icon_tab_contacts}]}])
diff --git a/src/status_im/components/react.cljs b/src/status_im/components/react.cljs
index d45088bd05..930f6deedf 100644
--- a/src/status_im/components/react.cljs
+++ b/src/status_im/components/react.cljs
@@ -35,9 +35,20 @@
(def picker-item (r/adapt-react-class (.-Item (.-Picker js/React))))
-(defn icon [n style]
- [image {:source {:uri (keyword (str "icon_" (name n)))}
- :style style}])
+(defn icon
+ ([n] (icon n {}))
+ ([n style]
+ [image {:source {:uri (keyword (str "icon_" (name n)))}
+ :style style}]))
+
+;(def react-linear-gradient (.-default (js/require "react-native-linear-gradient")))
+;(def linear-gradient (r/adapt-react-class react-linear-gradient))
+
+(set! js/window.LinearGradient (js/require "react-native-linear-gradient"))
+(defn linear-gradient [props]
+ (js/React.createElement js/LinearGradient
+ (clj->js (merge {:inverted true} props))))
+
(def platform (.. js/React -Platform -OS))
diff --git a/src/status_im/components/tabs/styles.cljs b/src/status_im/components/tabs/styles.cljs
new file mode 100644
index 0000000000..2c25c2417b
--- /dev/null
+++ b/src/status_im/components/tabs/styles.cljs
@@ -0,0 +1,56 @@
+(ns status-im.components.tabs.styles
+ (:require [status-im.components.styles :refer [font
+ title-font
+ color-white
+ chat-background
+ online-color
+ selected-message-color
+ separator-color
+ text1-color
+ text2-color
+ toolbar-background1]]))
+
+(def tab-height 56)
+
+(def tabs
+ {:flex 1
+ :position :absolute
+ :bottom 0
+ :right 0
+ :left 0
+ })
+
+(def top-gradient
+ {:flexDirection :row
+ :height 3})
+
+(def tabs-container
+ {:flexDirection :row
+ :height tab-height
+ :opacity 1
+ :backgroundColor :white
+ :justifyContent :center
+ :alignItems :center})
+
+(def tab
+ {:flex 1
+ :height tab-height
+ :justifyContent :center
+ :alignItems :center})
+
+(def tab-title
+ {:fontFamily "sans-serif"
+ :fontSize 14
+ :color "#6e93d8"})
+
+(def tab-icon
+ {:width 24
+ :height 24
+ :marginBottom 1})
+
+(def tab-container
+ {:flex 1
+ :height tab-height
+ :justifyContent :center
+ :alignItems :center})
+
diff --git a/src/status_im/components/tabs/tab.cljs b/src/status_im/components/tabs/tab.cljs
new file mode 100644
index 0000000000..4205549a5a
--- /dev/null
+++ b/src/status_im/components/tabs/tab.cljs
@@ -0,0 +1,19 @@
+(ns status-im.components.tabs.tab
+ (:require-macros [status-im.utils.views :refer [defview]])
+ (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
+ [status-im.components.react :refer [view
+ text-input
+ text
+ image
+ touchable-highlight]]
+ [reagent.core :as r]
+ [status-im.components.tabs.styles :as st]))
+
+(defview tab [{:keys [handler title icon selected-index index]}]
+ [touchable-highlight {:style st/tab
+ :onPress handler}
+ [view {:style st/tab-container}
+ [image {:source {:uri icon}
+ :style st/tab-icon}]
+ (when (= selected-index index)
+ [text {:style st/tab-title} title])]])
diff --git a/src/status_im/components/tabs/tabs.cljs b/src/status_im/components/tabs/tabs.cljs
new file mode 100644
index 0000000000..23450c80be
--- /dev/null
+++ b/src/status_im/components/tabs/tabs.cljs
@@ -0,0 +1,26 @@
+(ns status-im.components.tabs.tabs
+ (:require-macros [status-im.utils.views :refer [defview]])
+ (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
+ [status-im.components.react :refer [view
+ text-input
+ text
+ image
+ touchable-highlight
+ linear-gradient]]
+ [reagent.core :as r]
+ [status-im.components.tabs.styles :as st]
+ [status-im.components.tabs.tab :refer [tab]]))
+
+(defn create-tab [index data selected-index]
+ (let [data (merge data {:key index
+ :index index
+ :selected-index selected-index})]
+ [tab data]))
+
+(defview tabs [{:keys [style tab-list selected-index]}]
+ (let [style (merge st/tabs style)]
+ [view {:style style}
+ [linear-gradient {:colors [ "rgba(24, 52, 76, 0.01)" "rgba(24, 52, 76, 0.085)" "rgba(24, 52, 76, 0.165)"]
+ :style st/top-gradient}]
+ [view st/tabs-container
+ (doall (map-indexed #(create-tab %1 %2 selected-index) tab-list))]]))
diff --git a/src/status_im/contacts/handlers.cljs b/src/status_im/contacts/handlers.cljs
index 7a384d04fd..268b701815 100644
--- a/src/status_im/contacts/handlers.cljs
+++ b/src/status_im/contacts/handlers.cljs
@@ -73,7 +73,7 @@
(defn request-stored-contacts [contacts]
(let [contacts-by-hash (get-contacts-by-hash contacts)
- data (keys contacts-by-hash)]
+ data (or (keys contacts-by-hash) ())]
(http-post "get-contacts" {:phone-number-hashes data}
(fn [{:keys [contacts]}]
(let [contacts' (add-identity contacts-by-hash contacts)]
diff --git a/src/status_im/contacts/screen.cljs b/src/status_im/contacts/screen.cljs
index 12cee44a65..11d75bdc2a 100644
--- a/src/status_im/contacts/screen.cljs
+++ b/src/status_im/contacts/screen.cljs
@@ -2,13 +2,14 @@
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[status-im.components.react :refer [view text
- image
- touchable-highlight
- list-view
- list-item]]
+ image
+ touchable-highlight
+ list-view
+ list-item]]
[status-im.contacts.views.contact :refer [contact-view]]
[status-im.components.styles :refer [toolbar-background2]]
[status-im.components.toolbar :refer [toolbar]]
+ [status-im.components.main-tabs :refer [main-tabs]]
[status-im.contacts.styles :as st]
[status-im.utils.listview :as lw]))
@@ -32,4 +33,5 @@
[list-view {:dataSource (lw/to-datasource contacts)
:enableEmptySections true
:renderRow render-row
- :style st/contacts-list}])])
+ :style st/contacts-list}])
+ [main-tabs]])
diff --git a/src/status_im/contacts/styles.cljs b/src/status_im/contacts/styles.cljs
index 4cbec2cdff..7455363d38 100644
--- a/src/status_im/contacts/styles.cljs
+++ b/src/status_im/contacts/styles.cljs
@@ -3,7 +3,8 @@
title-font
text1-color
color-white
- online-color]]))
+ online-color]]
+ [status-im.components.tabs.styles :refer [tab-height]]))
(def search-icon
{:width 17
@@ -14,7 +15,8 @@
:backgroundColor :white})
(def contacts-list
- {:backgroundColor :white})
+ {:backgroundColor :white
+ :marginBottom tab-height})
(def contact-photo-container
{:borderRadius 50})
diff --git a/src/status_im/db.cljs b/src/status_im/db.cljs
index 3482925e8a..a46c61f087 100644
--- a/src/status_im/db.cljs
+++ b/src/status_im/db.cljs
@@ -7,28 +7,29 @@
(def default-view :chat-list)
;; initial state of app-db
-(def app-db {:identity-password "replace-me-with-user-entered-password"
- :identity "me"
- :contacts []
- :contacts-ids #{}
- :selected-contacts #{}
- :current-chat-id "console"
- :chat {:command nil
- :last-message nil}
- :chats {}
- :chats-updated-signal 0
- :show-actions false
- :new-participants #{}
- :signed-up true
- :view-id default-view
- :navigation-stack (list default-view)
+(def app-db {:identity-password "replace-me-with-user-entered-password"
+ :identity "me"
+ :contacts []
+ :contacts-ids #{}
+ :selected-contacts #{}
+ :current-chat-id "console"
+ :chat {:command nil
+ :last-message nil}
+ :chats {}
+ :chats-updated-signal 0
+ :show-actions false
+ :selected-participants #{}
+ :signed-up true
+ :view-id default-view
+ :navigation-stack (list default-view)
;; TODO fix hardcoded values
- :photo-path nil
- :username "My Name"
- :phone-number "3147984309"
- :email "myemail@gmail.com"
- :status "Hi, this is my status"
- :current-tag nil})
+ :photo-path nil
+ :username "My Name"
+ :phone-number "3147984309"
+ :email "myemail@gmail.com"
+ :status "Hi, this is my status"
+ :current-tag nil
+ :disable-group-creation false})
(def protocol-initialized-path [:protocol-initialized])
(defn chat-input-text-path [chat-id]
diff --git a/src/status_im/discovery/screen.cljs b/src/status_im/discovery/screen.cljs
index d5d62f5925..ab2c80e314 100644
--- a/src/status_im/discovery/screen.cljs
+++ b/src/status_im/discovery/screen.cljs
@@ -3,10 +3,11 @@
(:require
[re-frame.core :refer [dispatch subscribe]]
[status-im.components.react :refer [view
- scroll-view
- text
- text-input]]
+ scroll-view
+ text
+ text-input]]
[status-im.components.toolbar :refer [toolbar]]
+ [status-im.components.main-tabs :refer [main-tabs]]
[status-im.discovery.views.popular :refer [popular]]
[status-im.discovery.views.recent :refer [discovery-recent]]
[status-im.discovery.styles :as st]))
@@ -22,7 +23,7 @@
:autoFocus true
:placeholder "Type your search tags here"
:onSubmitEditing (fn [e]
- (let [search (aget e "nativeEvent" "text")
+ (let [search (aget e "nativeEvent" "text")
hashtags (get-hashtags search)]
(dispatch [:broadcast-status search hashtags])))}]
[view
@@ -43,10 +44,11 @@
:action {:image {:source {:uri :icon_search}
:style st/search-icon}
:handler #(toogle-search show-search)}}]
- [scroll-view {:style {}}
+ [scroll-view st/scroll-view-container
[view st/section-spacing
[text {:style st/discovery-subtitle} "Popular tags"]]
[popular]
[view st/section-spacing
[text {:style st/discovery-subtitle} "Recent"]]
- [discovery-recent]]])
+ [discovery-recent]]
+ [main-tabs]])
diff --git a/src/status_im/discovery/styles.cljs b/src/status_im/discovery/styles.cljs
index d1d5d650eb..979cd287a0 100644
--- a/src/status_im/discovery/styles.cljs
+++ b/src/status_im/discovery/styles.cljs
@@ -1,14 +1,15 @@
(ns status-im.discovery.styles
(:require [status-im.components.styles :refer [font
- title-font
- color-white
- chat-background
- online-color
- selected-message-color
- separator-color
- text1-color
- text2-color
- toolbar-background1]]))
+ title-font
+ color-white
+ chat-background
+ online-color
+ selected-message-color
+ separator-color
+ text1-color
+ text2-color
+ toolbar-background1]]
+ [status-im.components.tabs.styles :refer [tab-height]]))
;; common
@@ -39,14 +40,14 @@
(def discovery-title
{:color "#000000de"
- :alignSelf :center
+ :alignSelf :center
:textAlign :center
:fontFamily "sans-serif"
:fontSize 16})
(def discovery-toolbar
{:backgroundColor "#eef2f5"
- :elevation 0})
+ :elevation 0})
(def discovery-subtitle
{:color "#8f838c93"
@@ -58,6 +59,9 @@
:paddingTop 15
:paddingBottom 15})
+(def scroll-view-container
+ {:marginBottom tab-height})
+
;; discovery_popular.cljs
(def carousel-page-style
@@ -71,86 +75,86 @@
;; discovery_populat_list.cljs
(def tag-name
- {:color "#7099e6"
- :fontFamily "sans-serif-medium"
- :fontSize 14
- :paddingRight 5
- :paddingBottom 2
- :alignItems :center
+ {:color "#7099e6"
+ :fontFamily "sans-serif-medium"
+ :fontSize 14
+ :paddingRight 5
+ :paddingBottom 2
+ :alignItems :center
:justifyContent :center})
(def tag-name-container
- {:flexDirection "column"
+ {:flexDirection "column"
:backgroundColor "#eef2f5"
- :borderRadius 5
- :padding 4})
+ :borderRadius 5
+ :padding 4})
(def tag-count
- {:color "#838c93"
- :fontFamily "sans-serif"
- :fontSize 12
- :paddingRight 5
- :paddingBottom 2
- :alignItems :center
+ {:color "#838c93"
+ :fontFamily "sans-serif"
+ :fontSize 12
+ :paddingRight 5
+ :paddingBottom 2
+ :alignItems :center
:justifyContent :center})
(def tag-count-container
- {:flex 0.2
+ {:flex 0.2
:flexDirection "column"
- :alignItems "flex-end"
- :paddingTop 10
- :paddingRight 9})
+ :alignItems "flex-end"
+ :paddingTop 10
+ :paddingRight 9})
(def popular-list-container
- {:flex 1
+ {:flex 1
:backgroundColor :white
- :paddingLeft 10
- :paddingTop 16})
+ :paddingLeft 10
+ :paddingTop 16})
(def popular-list
{:backgroundColor :white
- :paddingTop 13})
+ :paddingTop 13})
;; discover_popular_list_item.cjls
(def popular-list-item
{:flexDirection :row
- :paddingTop 10
+ :paddingTop 10
:paddingBottom 10})
(def popular-list-item-status
- {:color "black"
+ {:color "black"
:fontFamily "sans-serif"
:lineHeight 22
- :fontSize 14})
+ :fontSize 14})
(def popular-list-item-name
- {:color "black"
+ {:color "black"
:fontFamily "sans-serif-medium"
- :fontSize 14
+ :fontSize 14
:lineHeight 24})
(def popular-list-item-name-container
- {:flex 0.8
+ {:flex 0.8
:flexDirection "column"})
(def popular-list-item-avatar-container
- {:flex 0.2
+ {:flex 0.2
:flexDirection "column"
- :alignItems :center
- :paddingTop 5})
+ :alignItems :center
+ :paddingTop 5})
(def popular-list-item-avatar
- {:resizeMode "contain"
+ {:resizeMode "contain"
:borderRadius 150
- :width 40
- :height 40})
+ :width 40
+ :height 40})
;; discovery_recent
(def recent-list
{:backgroundColor :white
- :paddingLeft 15})
+ :paddingLeft 15})
;; discovery_tag
@@ -158,22 +162,27 @@
{:flex 1
:backgroundColor "#eef2f5"})
+(def tag-title-container
+ {:flex 1
+ :alignItems "center"
+ :justifyContent "center"})
+
(def tag-title
- {:color "#7099e6"
- :fontFamily "sans-serif-medium"
- :fontSize 14
- :paddingRight 5
+ {:color "#7099e6"
+ :fontFamily "sans-serif-medium"
+ :fontSize 14
+ :paddingRight 5
:paddingBottom 2})
-(def tag-title-container
+(def tag-container
{:backgroundColor "#eef2f5"
- :flexWrap :wrap
- :borderRadius 5
- :padding 4})
+ :flexWrap :wrap
+ :borderRadius 5
+ :padding 4})
(def icon-back
- {:width 8
- :height 14})
+ {:width 8
+ :height 14})
(def icon-search
{:width 17
diff --git a/src/status_im/discovery/tag.cljs b/src/status_im/discovery/tag.cljs
index 1b4f0fbc9b..a872b48000 100644
--- a/src/status_im/discovery/tag.cljs
+++ b/src/status_im/discovery/tag.cljs
@@ -17,7 +17,8 @@
(defn title-content [tag]
[view st/tag-title-container
- [text {:style st/tag-title} (str " #" tag)]])
+ [view {:style st/tag-container}
+ [text {:style st/tag-title} (str " #" tag)]]])
(defn discovery-tag []
(let [tag (subscribe [:get :current-tag])
@@ -31,7 +32,7 @@
:style st/icon-back}
:handler #(dispatch [:navigate-back])}
:title "Add Participants"
- :content (title-content @tag)
+ :custom-content (title-content @tag)
:action {:image {:source {:uri :icon_search}
:style st/icon-search}
:handler (fn [])}}]
diff --git a/src/status_im/group_settings/handlers.cljs b/src/status_im/group_settings/handlers.cljs
index d62ae27276..82eab18d7b 100644
--- a/src/status_im/group_settings/handlers.cljs
+++ b/src/status_im/group_settings/handlers.cljs
@@ -1,72 +1,144 @@
(ns status-im.group-settings.handlers
- (:require [re-frame.core :refer [register-handler debug dispatch]]
+ (:require [re-frame.core :refer [register-handler debug dispatch after
+ enrich]]
[status-im.persistence.realm :as r]
- [status-im.models.messages :refer [clear-history]]))
+ [status-im.chat.handlers :refer [delete-messages!]]
+ [status-im.protocol.api :as api]
+ [status-im.utils.random :as random]
+ [status-im.models.contacts :as contacts]
+ [status-im.models.messages :as messages]
+ [status-im.models.chats :as chats]
+ [status-im.constants :refer [text-content-type]]
+ [status-im.utils.handlers :as u]
+ [status-im.navigation.handlers :as nav]))
-(defn set-chat-name [db]
- (let [chat-id (:current-chat-id db)
- name (:new-chat-name db)]
- (r/write (fn []
- (-> (r/get-by-field :chats :chat-id chat-id)
- (r/single)
- (aset "name" name))))
- (assoc-in db [:chats chat-id :name] name)))
+(defmethod nav/preload-data! :group-settings
+ [db _]
+ (assoc db :selected-participants #{}))
-(defn set-chat-color [db]
- (let [chat-id (:current-chat-id db)
- color (:new-chat-color db)]
- (r/write (fn []
- (-> (r/get-by-field :chats :chat-id chat-id)
- (r/single)
- (aset "color" color))))
- (assoc-in db [:chats chat-id :color] color)))
+(defn save-chat-property!
+ [db-name property-name]
+ (fn [{:keys [current-chat-id] :as db} _]
+ (let [property (db-name db)]
+ (r/write (fn []
+ (-> (r/get-by-field :chats :chat-id current-chat-id)
+ (r/single)
+ (aset (name property-name) property)))))))
-(defn delete-chat [chat-id]
- (r/write
- (fn []
- (-> (r/get-by-field :chats :chat-id chat-id)
- (r/single)
- (r/delete))))
- ;; TODO temp. Update chat in db atom
- (dispatch [:initialize-chats]))
+(defn update-chat-property
+ [db-name property-name]
+ (fn [{:keys [current-chat-id] :as db} _]
+ (let [property (db-name db)]
+ (assoc-in db [:chats current-chat-id property-name] property))))
+
+(defn prepare-chat-settings
+ [{:keys [current-chat-id] :as db} _]
+ (let [{:keys [name color]} (-> db
+ (get-in [:chats current-chat-id])
+ (select-keys [:name :color]))]
+ (-> db
+ (assoc :new-chat-name name
+ :new-chat-color color
+ :group-settings {}))))
(register-handler :show-group-settings
- (fn [db _]
- (let [chat-id (:current-chat-id db)
- chat-name (get-in db [:chats chat-id :name])
- chat-color (get-in db [:chats chat-id :color])
- db (assoc db
- :new-chat-name chat-name
- :new-chat-color chat-color
- :group-settings-show-color-picker false
- :group-settings-selected-member nil)]
- (dispatch [:navigate-to :group-settings])
- db)))
+ (after (fn [_ _] (dispatch [:navigate-to :group-settings])))
+ prepare-chat-settings)
(register-handler :set-chat-name
- (fn [db [action]]
- (set-chat-name db)))
+ (after (save-chat-property! :new-chat-name :name))
+ (update-chat-property :new-chat-name :name))
(register-handler :set-chat-color
- (fn [db [action]]
- (set-chat-color db)))
+ (after (save-chat-property! :new-chat-color :color))
+ (update-chat-property :new-chat-color :color))
-(register-handler :set-new-chat-name
- (fn [db [action name]]
- (assoc db :new-chat-name name)))
-
-(register-handler :set-new-chat-color
- (fn [db [action color]]
- (assoc db :new-chat-color color)))
-
-(register-handler :select-group-chat-member
- (fn [db [action identity]]
- (assoc db :group-settings-selected-member identity)))
-
-(register-handler :set-group-settings-show-color-picker
- (fn [db [action show?]]
- (assoc db :group-settings-show-color-picker show?)))
+(defn clear-messages
+ [{:keys [current-chat-id] :as db} _]
+ (assoc-in db [:chats current-chat-id :messages] '()))
(register-handler :clear-history
- (fn [db [action]]
- (clear-history (:current-chat-id db))))
+ (after delete-messages!)
+ clear-messages)
+
+(register-handler :group-settings
+ (fn [db [_ k v]]
+ (assoc-in db [:group-settings k] v)))
+
+(defn remove-identities [collection identities]
+ (remove #(identities (:identity %)) collection))
+
+(defn remove-members
+ [{:keys [current-chat-id selected-participants] :as db} _]
+ (update-in db [:chats current-chat-id :contacts]
+ remove-identities selected-participants))
+
+(defn remove-members-from-realm!
+ [{:keys [current-chat-id selected-participants] :as db} _]
+ (let [chat (get-in db [:chats current-chat-id])]
+ (r/write
+ (fn []
+ (r/create
+ :chats
+ (update chat :contacts remove-identities selected-participants)
+ true)))))
+
+(defn notify-about-removing!
+ [{:keys [current-chat-id selected-participants]} _]
+ (doseq [participant selected-participants]
+ (api/group-remove-participant current-chat-id participant)))
+
+(defn system-message [msg-id content]
+ {:from "system"
+ :msg-id msg-id
+ :content content
+ :content-type text-content-type})
+
+(defn removed-participant-msg [chat-id identity]
+ (let [contact-name (:name (contacts/contact-by-identity identity))]
+ (->> (str "You've removed " (or contact-name identity))
+ (system-message (random/id))
+ (messages/save-message chat-id))))
+
+(defn create-removing-messages!
+ [{:keys [current-chat-id selected-participants]} _]
+ (doseq [participant selected-participants]
+ (removed-participant-msg current-chat-id participant)))
+
+(defn deselect-members [db _]
+ (assoc db :selected-participants #{}))
+
+(register-handler :remove-participants
+ ;; todo check if user have rights to add/remove participants
+ ;; todo order of operations tbd
+ (-> remove-members
+ ;; todo shouldn't this be done only after receiving of the "ack message"
+ ;; about the api call that removes participants from the group?
+ ((after remove-members-from-realm!))
+ ;; todo uncomment
+ ;((after notify-about-removing!))
+ ((after create-removing-messages!))
+ ((enrich deselect-members))
+ debug))
+
+(defn add-memebers
+ [{:keys [current-chat-id selected-participants] :as db} _]
+ (let [new-identities (map #(hash-map :identity %) selected-participants)]
+ (update db [:chats current-chat-id :contacts] concat new-identities)))
+
+(defn add-members-to-realm!
+ [{:keys [current-chat-id selected-participants]} _]
+ (chats/chat-add-participants current-chat-id selected-participants))
+
+(defn notify-about-new-members!
+ [{:keys [current-chat-id selected-participants]} _]
+ (doseq [identity selected-participants]
+ (api/group-add-participant current-chat-id identity)))
+
+(register-handler :add-new-participants
+ ;; todo order of operations tbd
+ (-> add-memebers
+ ((after add-members-to-realm!))
+ ;; todo uncomment
+ ;((after notify-about-new-members!))
+ ((enrich deselect-members))))
diff --git a/src/status_im/group_settings/screen.cljs b/src/status_im/group_settings/screen.cljs
index 6fb75a1151..1c49c4f094 100644
--- a/src/status_im/group_settings/screen.cljs
+++ b/src/status_im/group_settings/screen.cljs
@@ -16,26 +16,26 @@
[status-im.group-settings.styles.group-settings :as st]
[status-im.group-settings.views.member :refer [member-view]]))
-(defn remove-member [{:keys [whisper-identity]}]
- (dispatch [:chat-remove-member whisper-identity]))
+(defn remove-member []
+ (dispatch [:remove-participants]))
(defn close-member-menu []
- (dispatch [:select-group-chat-member nil]))
+ (dispatch [:set :selected-participants #{}]))
;; TODO not in design
(defview member-menu []
- [member [:group-settings-selected-member]]
- [modal {:animated false
- :transparent false
- :onRequestClose close-member-menu}
- [touchable-highlight {:style st/modal-container
- :on-press close-member-menu}
- [view st/modal-inner-container
- [text {:style st/modal-member-name}
- (:name member)]
- [touchable-highlight {:on-press #(remove-member member)}
- [text {:style st/modal-remove-text}
- "Remove"]]]]])
+ [{:keys [name] :as participant} [:selected-participant]]
+ (when participant
+ [modal {:animated false
+ :transparent false
+ :onRequestClose close-member-menu}
+ [touchable-highlight {:style st/modal-container
+ :on-press close-member-menu}
+ [view st/modal-inner-container
+ [text {:style st/modal-member-name} name]
+ [touchable-highlight {:on-press remove-member}
+ [text {:style st/modal-remove-text}
+ "Remove"]]]]]))
(defview chat-members []
[members [:current-chat-contacts]]
@@ -43,9 +43,6 @@
(for [member members]
^{:key member} [member-view member])])
-(defn show-chat-name-edit []
- (dispatch [:navigate-to :chat-name-edit]))
-
(defn setting-view [{:keys [icon-style custom-icon handler title subtitle]
icon-name :icon}]
[touchable-highlight {:on-press handler}
@@ -60,7 +57,7 @@
subtitle])]]])
(defn close-chat-color-picker []
- (dispatch [:set-group-settings-show-color-picker false]))
+ (dispatch [:group-settings :show-color-picker false]))
(defn set-chat-color []
(close-chat-color-picker)
@@ -68,8 +65,8 @@
;; TODO not in design
(defview chat-color-picker []
- [show-color-picker [:get :group-settings-show-color-picker]
- new-color [:get :new-chat-color]]
+ [show-color-picker [:group-settings :show-color-picker]
+ new-color [:get :new-chat-color]]
[modal {:animated false
:transparent false
:onRequestClose close-chat-color-picker}
@@ -77,11 +74,11 @@
:on-press close-chat-color-picker}
[view st/modal-color-picker-inner-container
[picker {:selectedValue new-color
- :onValueChange #(dispatch [:set-new-chat-color %])}
- [picker-item {:label "Blue" :value "#7099e6"}]
- [picker-item {:label "Purple" :value "#a187d5"}]
- [picker-item {:label "Green" :value "green"}]
- [picker-item {:label "Red" :value "red"}]]
+ :onValueChange #(dispatch [:set :new-chat-color %])}
+ [picker-item {:label "Blue" :value "#7099e6"}]
+ [picker-item {:label "Purple" :value "#a187d5"}]
+ [picker-item {:label "Green" :value "green"}]
+ [picker-item {:label "Red" :value "red"}]]
[touchable-highlight {:on-press set-chat-color}
[text {:style st/modal-color-picker-save-btn-text}
"Save"]]]]])
@@ -91,7 +88,7 @@
[view {:style (st/chat-color-icon chat-color)}])
(defn show-chat-color-picker []
- (dispatch [:set-group-settings-show-color-picker true]))
+ (dispatch [:group-settings :show-color-picker true]))
(defn settings-view []
(let [settings [{:custom-icon [chat-color-icon]
@@ -108,18 +105,18 @@
{:icon :muted
:icon-style {:width 18
:height 21}}))
- {:icon :close-gray
- :icon-style {:width 12
- :height 12}
- :title "Clear history"
+ {:icon :close-gray
+ :icon-style {:width 12
+ :height 12}
+ :title "Clear history"
;; TODO show confirmation dialog?
- :handler #(dispatch [:clear-history])}
- {:icon :bin
- :icon-style {:width 12
- :height 18}
- :title "Delete and leave"
+ :handler #(dispatch [:clear-history])}
+ {:icon :bin
+ :icon-style {:width 12
+ :height 18}
+ :title "Delete and leave"
;; TODO show confirmation dialog?
- :handler #(dispatch [:leave-group-chat])}]]
+ :handler #(dispatch [:leave-group-chat])}]]
[view st/settings-container
(for [setting settings]
^{:key setting} [setting-view setting])]))
@@ -136,26 +133,45 @@
[toolbar {:title "Chat settings"
:custom-action [chat-icon]}])
+(defn focus []
+ (dispatch [:set ::name-input-focused true]))
+
+(defn blur []
+ (dispatch [:set ::name-input-focused false]))
+
+(defn save []
+ (dispatch [:set-chat-name]))
+
+(defview chat-name []
+ [name [:chat :name]
+ new-name [:get :new-chat-name]
+ focused? [:get ::name-input-focused]]
+ [view
+ [text {:style st/chat-name-text} "Chat name"]
+ [view (st/chat-name-value-container focused?)
+ [text-input {:style st/chat-name-value
+ :ref #(when (and % focused?) (.focus %))
+ :on-change-text #(dispatch [:set :new-chat-name %])
+ :on-focus focus
+ :on-blur blur}
+ name]
+ (if (or focused? (not= name new-name))
+ [touchable-highlight {:style st/chat-name-btn-edit-container
+ :on-press save}
+ [view [icon :ok-purple st/add-members-icon]]]
+ [touchable-highlight {:style st/chat-name-btn-edit-container
+ :on-press focus}
+ [text {:style st/chat-name-btn-edit-text} "Edit"]])]])
+
(defview group-settings []
- [chat-name [:chat :name]
- selected-member [:group-settings-selected-member]
- show-color-picker [:get :group-settings-show-color-picker]]
+ [show-color-picker [:group-settings :show-color-picker]]
[view st/group-settings
[new-group-toolbar]
[scroll-view st/body
- [text {:style st/chat-name-text}
- "Chat name"]
- [view st/chat-name-value-container
- [text {:style st/chat-name-value}
- chat-name]
- [touchable-highlight {:style st/chat-name-btn-edit-container
- :on-press show-chat-name-edit}
- [text {:style st/chat-name-btn-edit-text}
- "Edit"]]]
- [text {:style st/members-text}
- "Members"]
+ [chat-name]
+ [text {:style st/members-text} "Members"]
+ [touchable-highlight {:on-press #(dispatch [:navigate-to :add-participants])}
;; TODO add participants view is not in design
- [touchable-highlight {:on-press #(dispatch [:show-add-participants])}
[view st/add-members-container
[icon :add-gray st/add-members-icon]
[text {:style st/add-members-text}
@@ -166,5 +182,4 @@
[settings-view]]
(when show-color-picker
[chat-color-picker])
- (when selected-member
- [member-menu])])
+ [member-menu]])
diff --git a/src/status_im/group_settings/styles/chat_name_edit.cljs b/src/status_im/group_settings/styles/chat_name_edit.cljs
deleted file mode 100644
index d185480652..0000000000
--- a/src/status_im/group_settings/styles/chat_name_edit.cljs
+++ /dev/null
@@ -1,19 +0,0 @@
-(ns status-im.group-settings.styles.chat-name-edit
- (:require [status-im.components.styles :refer [font
- color-white
- text1-color]]))
-
-(def save-action-icon
- {:width 18
- :height 14})
-
-(def chat-name-container
- {:flex 1
- :flexDirection :column
- :backgroundColor color-white})
-
-(def chat-name-input
- {:marginLeft 12
- :fontSize 14
- :fontFamily font
- :color text1-color})
diff --git a/src/status_im/group_settings/styles/group_settings.cljs b/src/status_im/group_settings/styles/group_settings.cljs
index 2deb557a63..91d407c604 100644
--- a/src/status_im/group_settings/styles/group_settings.cljs
+++ b/src/status_im/group_settings/styles/group_settings.cljs
@@ -24,17 +24,17 @@
:backgroundColor color-white})
(def modal-member-name
- {:color text2-color
- :fontFamily font
- :fontSize 14
- :lineHeight 20})
+ {:color text2-color
+ :fontFamily font
+ :fontSize 14
+ :lineHeight 20})
(def modal-remove-text
- {:margin 10
- :color text1-color
- :fontFamily font
- :fontSize 14
- :lineHeight 20})
+ {:margin 10
+ :color text1-color
+ :fontFamily font
+ :fontSize 14
+ :lineHeight 20})
(def modal-color-picker-inner-container
{:borderRadius 10
@@ -42,12 +42,12 @@
:backgroundColor color-white})
(def modal-color-picker-save-btn-text
- {:margin 10
- :alignSelf :center
- :color text1-color
- :fontFamily font
- :fontSize 14
- :lineHeight 20})
+ {:margin 10
+ :alignSelf :center
+ :color text1-color
+ :fontFamily font
+ :fontSize 14
+ :lineHeight 20})
(def chat-members-container
{:marginBottom 10})
@@ -76,14 +76,14 @@
:fontSize 14
:lineHeight 20})
-(def chat-name-value-container
+(defn chat-name-value-container [focused?]
{:flexDirection :row
:marginLeft 16
:height 56
:alignItems :center
:justifyContent :center
- :borderBottomWidth 1
- :borderBottomColor separator-color})
+ :borderBottomWidth 2
+ :borderBottomColor (if focused? color-purple separator-color)})
(def chat-name-value
{:flex 1
@@ -96,11 +96,11 @@
:justifyContent :center})
(def chat-name-btn-edit-text
- {:marginTop -1
- :color text2-color
- :fontFamily font
- :fontSize 16
- :lineHeight 20})
+ {:marginTop -1
+ :color text2-color
+ :fontFamily font
+ :fontSize 16
+ :lineHeight 20})
(def members-text
{:marginTop 24
diff --git a/src/status_im/group_settings/subs.cljs b/src/status_im/group_settings/subs.cljs
index 55085b2256..f2b6ac1db3 100644
--- a/src/status_im/group_settings/subs.cljs
+++ b/src/status_im/group_settings/subs.cljs
@@ -1,14 +1,13 @@
(ns status-im.group-settings.subs
(:require-macros [reagent.ratom :refer [reaction]])
- (:require [re-frame.core :refer [register-sub]]
- [status-im.models.contacts :refer [contact-by-identity]]))
+ (:require [re-frame.core :refer [register-sub]]))
-(register-sub :group-settings-selected-member
- (fn [db [_]]
+(register-sub :selected-participant
+ (fn [db _]
(reaction
- (let [identity (get @db :group-settings-selected-member)]
- (contact-by-identity identity)))))
+ (let [identity (first (:selected-participants @db))]
+ (get-in @db [:contacts identity])))))
-(register-sub :group-settings-show-color-picker
- (fn [db [_]]
- (reaction (get @db :group-settings-show-color-picker))))
+(register-sub :group-settings
+ (fn [db [_ k]]
+ (reaction (get-in @db [:group-settings k]))))
diff --git a/src/status_im/group_settings/views/chat_name_edit.cljs b/src/status_im/group_settings/views/chat_name_edit.cljs
deleted file mode 100644
index 523b94653b..0000000000
--- a/src/status_im/group_settings/views/chat_name_edit.cljs
+++ /dev/null
@@ -1,31 +0,0 @@
-(ns status-im.group-settings.views.chat-name-edit
- (:require-macros [status-im.utils.views :refer [defview]])
- (:require [reagent.core :as r]
- [re-frame.core :refer [subscribe dispatch dispatch-sync]]
- [status-im.components.react :refer [view text-input]]
- [status-im.components.toolbar :refer [toolbar]]
- [status-im.group-settings.styles.chat-name-edit :as st]
- [status-im.components.styles :refer [toolbar-background2
- text2-color]]))
-
-(defn save-group-chat-name []
- (dispatch [:set-chat-name])
- (dispatch [:navigate-back]))
-
-(defn chat-name-edit-toolbar [chat-name]
- [toolbar {:background-color toolbar-background2
- :title "Edit chat name"
- ;; TODO change to dark 'ok' icon
- :action {:image {:source {:uri :icon_ok}
- :style st/save-action-icon}
- :handler save-group-chat-name}}])
-
-(defview chat-name-edit []
- [new-chat-name [:get :new-chat-name]]
- [view st/chat-name-container
- [chat-name-edit-toolbar]
- [text-input {:style st/chat-name-input
- :autoFocus true
- :placeholderTextColor text2-color
- :onChangeText #(dispatch [:set-new-chat-name %])}
- new-chat-name]])
diff --git a/src/status_im/group_settings/views/member.cljs b/src/status_im/group_settings/views/member.cljs
index 73889c611f..240d6a09c8 100644
--- a/src/status_im/group_settings/views/member.cljs
+++ b/src/status_im/group_settings/views/member.cljs
@@ -38,6 +38,6 @@
[text {:style st/role-text}
role])]
[touchable-highlight
- {:on-press #(dispatch [:select-group-chat-member whisper-identity])}
+ {:on-press #(dispatch [:set :selected-participants #{whisper-identity}])}
[view st/more-btn
[icon :more-vertical st/more-btn-icon]]]])
diff --git a/src/status_im/handlers.cljs b/src/status_im/handlers.cljs
index e7d2687eed..4010049665 100644
--- a/src/status_im/handlers.cljs
+++ b/src/status_im/handlers.cljs
@@ -1,46 +1,23 @@
(ns status-im.handlers
(:require
- [re-frame.core :refer [register-handler after dispatch debug enrich]]
+ [re-frame.core :refer [register-handler after dispatch debug]]
[schema.core :as s :include-macros true]
- [status-im.persistence.realm :as r]
[status-im.db :refer [app-db schema]]
[status-im.persistence.simple-kv-store :as kv]
[status-im.protocol.state.storage :as storage]
- [status-im.db :as db :refer [app-db schema]]
- [status-im.protocol.api :refer [init-protocol]]
- [status-im.protocol.protocol-handler :refer [make-handler]]
- [status-im.models.protocol :refer [update-identity
- set-initialized]]
- [status-im.models.contacts :as contacts]
- [status-im.models.messages :refer [save-message
- update-message!
- clear-history]]
[status-im.models.commands :refer [set-commands]]
- [status-im.handlers.server :as server]
[status-im.chat.suggestions :refer [load-commands]]
- [status-im.models.chats :refer [chat-exists?
- create-chat
- chat-add-participants
- chat-remove-participants
- set-chat-active
- re-join-group-chat
- chat-by-id2]]
[status-im.utils.logging :as log]
- [status-im.protocol.api :as api]
- [status-im.constants :refer [text-content-type
- content-type-command]]
- [status-im.navigation :refer [nav-push
- nav-replace
- nav-pop]]
[status-im.utils.crypt :refer [gen-random-bytes]]
- [status-im.utils.random :as random]
[status-im.utils.handlers :as u]
status-im.chat.handlers
- [status-im.group-settings.handlers :refer [delete-chat]]
+ status-im.group-settings.handlers
status-im.navigation.handlers
- status-im.discovery.handlers
status-im.contacts.handlers
- status-im.new-group.handlers))
+ status-im.discovery.handlers
+ status-im.new-group.handlers
+ status-im.participants.handlers
+ status-im.protocol.handlers))
;; -- Middleware ------------------------------------------------------------
;;
@@ -63,6 +40,11 @@
(fn [db [_ k v]]
(assoc db k v))))
+(register-handler :set-in
+ (debug
+ (fn [db [_ path v]]
+ (assoc-in db path v))))
+
(register-handler :initialize-db
(fn [_ _]
(assoc app-db
@@ -100,192 +82,8 @@
(log/debug action commands)
(set-commands db commands)))
-;; -- Protocol --------------------------------------------------------------
-
-(register-handler :initialize-protocol
- (u/side-effect!
- (fn [db [_]]
- (init-protocol (make-handler db)))))
-
-(register-handler :protocol-initialized
- (fn [db [_ identity]]
- (-> db
- (update-identity identity)
- (set-initialized true))))
-
-(defn system-message [msg-id content]
- {:from "system"
- :msg-id msg-id
- :content content
- :content-type text-content-type})
-
-(defn joined-chat-msg [chat-id from msg-id]
- (let [contact-name (:name (contacts/contact-by-identity from))]
- (save-message chat-id {:from "system"
- :msg-id (str msg-id "_" from)
- :content (str (or contact-name from) " received chat invitation")
- :content-type text-content-type})))
-
-(defn participant-invited-to-group-msg [chat-id identity from msg-id]
- (let [inviter-name (:name (contacts/contact-by-identity from))
- invitee-name (if (= identity (api/my-identity))
- "You"
- (:name (contacts/contact-by-identity identity)))]
- (save-message chat-id {:from "system"
- :msg-id msg-id
- :content (str (or inviter-name from) " invited " (or invitee-name identity))
- :content-type text-content-type})))
-
-(defn participant-removed-from-group-msg [chat-id identity from msg-id]
- (let [remover-name (:name (contacts/contact-by-identity from))
- removed-name (:name (contacts/contact-by-identity identity))]
- (->> (str (or remover-name from) " removed " (or removed-name identity))
- (system-message msg-id)
- (save-message chat-id))))
-
-(defn you-removed-from-group-msg [chat-id from msg-id]
- (let [remover-name (:name (contacts/contact-by-identity from))]
- (->> (str (or remover-name from) " removed you from group chat")
- (system-message msg-id)
- (save-message chat-id))))
-
-(defn participant-left-group-msg [chat-id from msg-id]
- (let [left-name (:name (contacts/contact-by-identity from))]
- (->> (str (or left-name from) " left")
- (system-message msg-id)
- (save-message chat-id))))
-
-(defn removed-participant-msg [chat-id identity]
- (let [contact-name (:name (contacts/contact-by-identity identity))]
- (->> (str "You've removed " (or contact-name identity))
- (system-message (random/id))
- (save-message chat-id))))
-
-(defn left-chat-msg [chat-id]
- (save-message chat-id {:from "system"
- :msg-id (random/id)
- :content "You left this chat"
- :content-type text-content-type}))
-
-(register-handler :group-chat-invite-acked
- (u/side-effect!
- (fn [_ [action from group-id ack-msg-id]]
- (log/debug action from group-id ack-msg-id)
- (joined-chat-msg group-id from ack-msg-id))))
-
-(register-handler :participant-removed-from-group
- (u/side-effect!
- (fn [_ [action from group-id identity msg-id]]
- (log/debug action msg-id from group-id identity)
- (chat-remove-participants group-id [identity])
- (participant-removed-from-group-msg group-id identity from msg-id))))
-
-(register-handler :you-removed-from-group
- (u/side-effect!
- (fn [_ [action from group-id msg-id]]
- (log/debug action msg-id from group-id)
- (you-removed-from-group-msg group-id from msg-id)
- (set-chat-active group-id false))))
-
-(register-handler :participant-left-group
- (u/side-effect!
- (fn [_ [action from group-id msg-id]]
- (log/debug action msg-id from group-id)
- (when-not (= (api/my-identity) from)
- (participant-left-group-msg group-id from msg-id)))))
-
-(register-handler :participant-invited-to-group
- (u/side-effect!
- (fn [_ [action from group-id identity msg-id]]
- (log/debug action msg-id from group-id identity)
- (participant-invited-to-group-msg group-id identity from msg-id))))
-
-(register-handler :acked-msg
- (u/side-effect!
- (fn [_ [action from msg-id]]
- (log/debug action from msg-id)
- (update-message! {:msg-id msg-id
- :delivery-status :delivered}))))
-
-(register-handler :msg-delivery-failed
- (u/side-effect!
- (fn [_ [action msg-id]]
- (log/debug action msg-id)
- (update-message! {:msg-id msg-id
- :delivery-status :failed}))))
-
-(register-handler :leave-group-chat
- (u/side-effect!
- (fn [db [action]]
- (log/debug action)
- (let [chat-id (:current-chat-id db)]
- (api/leave-group-chat chat-id)
- (set-chat-active chat-id false)
- (left-chat-msg chat-id)
- (delete-chat chat-id)
- (dispatch [:navigate-back])))))
-
;; -- User data --------------------------------------------------------------
(register-handler :load-user-phone-number
(fn [db [_]]
;; todo fetch phone number from db
(assoc db :user-phone-number "123")))
-
-;; -- Chats --------------------------------------------------------------
-(defn update-new-participants-selection [db identity add?]
- (update db :new-participants (fn [new-participants]
- (if add?
- (conj new-participants identity)
- (disj new-participants identity)))))
-
-(register-handler :select-new-participant
- (fn [db [action identity add?]]
- (log/debug action identity add?)
- (update-new-participants-selection db identity add?)))
-
-(register-handler :remove-selected-participants
- (fn [db [action]]
- (log/debug action)
- (let [identities (vec (:new-participants db))
- chat-id (:current-chat-id db)]
- (chat-remove-participants chat-id identities)
- (dispatch [:navigate-back])
- (doseq [ident identities]
- (api/group-remove-participant chat-id ident)
- (removed-participant-msg chat-id ident)))))
-
-(register-handler :add-new-participants
- (fn [db [action navigator]]
- (log/debug action)
- (let [identities (vec (:new-participants db))
- chat-id (:current-chat-id db)]
- (chat-add-participants chat-id identities)
- (dispatch [:navigate-back])
- (doseq [ident identities]
- (api/group-add-participant chat-id ident))
- db)))
-
-(defn chat-remove-member [db]
- (let [chat (get-in db [:chats (:current-chat-id db)])
- identity (:group-settings-selected-member db)]
- (r/write
- (fn []
- (r/create :chats
- (update chat :contacts
- (fn [members]
- (filter #(not= (:identity %) identity) members)))
- true)))
- ;; TODO temp. Update chat in db atom
- (dispatch [:initialize-chats])
- db))
-
-(register-handler :chat-remove-member
- (fn [db [action]]
- (let [chat-id (:current-chat-id db)
- identity (:group-settings-selected-member db)
- db (chat-remove-member db)]
- (dispatch [:select-group-chat-member nil])
- ;; TODO fix and uncomment
- (api/group-remove-participant chat-id identity)
- (removed-participant-msg chat-id identity)
- db)))
diff --git a/src/status_im/models/messages.cljs b/src/status_im/models/messages.cljs
index 80e4656e8b..5c8c17fa5f 100644
--- a/src/status_im/models/messages.cljs
+++ b/src/status_im/models/messages.cljs
@@ -62,10 +62,3 @@
(fn []
(when (r/exists? :msgs :msg-id msg-id)
(r/create :msgs msg true)))))
-
-(defn clear-history [chat-id]
- (r/write
- (fn []
- (r/delete (r/get-by-field :msgs :chat-id chat-id))))
- ;; TODO temp. Update chat in db atom
- (dispatch [:initialize-chats]))
diff --git a/src/status_im/navigation.cljs b/src/status_im/navigation.cljs
deleted file mode 100644
index f80b7d3df7..0000000000
--- a/src/status_im/navigation.cljs
+++ /dev/null
@@ -1,17 +0,0 @@
-(ns status-im.navigation)
-
-(def ^{:dynamic true :private true} *nav-render*
- "Flag to suppress navigator re-renders from outside om when pushing/popping."
- true)
-
-(defn nav-pop [nav]
- (binding [*nav-render* true]
- (.pop nav)))
-
-(defn nav-push [nav route]
- (binding [*nav-render* true]
- (.push nav (clj->js route))))
-
-(defn nav-replace [nav route]
- (binding [*nav-render* true]
- (.replace nav (clj->js route))))
diff --git a/src/status_im/navigation/handlers.cljs b/src/status_im/navigation/handlers.cljs
index 28f331a78a..c47134e429 100644
--- a/src/status_im/navigation/handlers.cljs
+++ b/src/status_im/navigation/handlers.cljs
@@ -18,7 +18,9 @@
(update :navigation-stack replace-top-element view-id)
(assoc :view-id view-id)))
-(defmulti preload-data! (fn [_ [_ view-id]] view-id))
+(defmulti preload-data!
+ (fn [db [_ view-id]] (or view-id (:view-id db))))
+
(defmethod preload-data! :default [db _] db)
(register-handler :navigate-to
@@ -27,10 +29,12 @@
(push-view db view-id)))
(register-handler :navigation-replace
+ (enrich preload-data!)
(fn [db [_ view-id]]
(replace-view db view-id)))
(register-handler :navigate-back
+ (enrich preload-data!)
(fn [{:keys [navigation-stack] :as db} _]
(if (>= 1 (count navigation-stack))
db
@@ -46,32 +50,10 @@
(push-view :new-group)
(assoc :new-group #{})))))
-(register-handler :show-chat
- (fn [db [_ chat-id nav-type]]
- (let [update-view-id-fn (if (= :replace nav-type) replace-view push-view)]
- (-> db
- (update-view-id-fn :chat)
- (assoc :current-chat-id chat-id)))))
-
(register-handler :show-contacts
(fn [db _]
(push-view db :contact-list)))
-(defn clear-new-participants [db]
- (assoc db :new-participants #{}))
-
-(register-handler :show-remove-participants
- (fn [db _]
- (-> db
- (push-view :remove-participants)
- clear-new-participants)))
-
-(register-handler :show-add-participants
- (fn [db _]
- (-> db
- (push-view :add-participants)
- clear-new-participants)))
-
(defn show-profile
[db [_ identity]]
(-> db
diff --git a/src/status_im/new_group/handlers.cljs b/src/status_im/new_group/handlers.cljs
index 4d934d1e23..0c34111405 100644
--- a/src/status_im/new_group/handlers.cljs
+++ b/src/status_im/new_group/handlers.cljs
@@ -58,14 +58,31 @@
(defn show-chat!
[{:keys [new-group-id]} _]
- (dispatch [:show-chat new-group-id :replace]))
+ (dispatch [:navigation-replace :chat new-group-id]))
+
+(defn enable-creat-buttion
+ [db _]
+ (assoc db :disable-group-creation false))
(register-handler :create-new-group
(-> start-group-chat!
((enrich prepare-chat))
((enrich add-chat))
((after create-chat!))
- ((after show-chat!))))
+ ((after show-chat!))
+ ((enrich enable-creat-buttion))))
+
+(defn disable-creat-button
+ [db _]
+ (assoc db :disable-group-creation true))
+
+(defn dispatch-create-group
+ [_ [_ group-name]]
+ (dispatch [:create-new-group group-name]))
+
+(register-handler :init-group-creation
+ (after dispatch-create-group)
+ disable-creat-button)
; todo rewrite
(register-handler :group-chat-invite-received
diff --git a/src/status_im/new_group/screen.cljs b/src/status_im/new_group/screen.cljs
index c58832e1dc..a620959d50 100644
--- a/src/status_im/new_group/screen.cljs
+++ b/src/status_im/new_group/screen.cljs
@@ -18,12 +18,14 @@
(defview new-group-toolbar []
- [group-name [:get ::group-name]]
+ [group-name [:get ::group-name]
+ creation-disabled? [:get :disable-group-creation]]
[toolbar
{:title "New group chat"
:action {:image {:source res/v ;; {:uri "icon_search"}
:style st/toolbar-icon}
- :handler #(dispatch [:create-new-group group-name])}}])
+ :handler (when-not creation-disabled?
+ #(dispatch [:init-group-creation group-name]))}}])
(defview group-name-input []
[group-name [:get ::group-name]]
diff --git a/src/status_im/new_group/subs.cljs b/src/status_im/new_group/subs.cljs
index 57d01e1aae..6753a5eacb 100644
--- a/src/status_im/new_group/subs.cljs
+++ b/src/status_im/new_group/subs.cljs
@@ -1,9 +1,7 @@
(ns status-im.new-group.subs
(:require-macros [reagent.ratom :refer [reaction]])
- (:require [re-frame.core :refer [register-sub]]))
+ (:require [re-frame.core :refer [register-sub]]
+ [status-im.utils.subs :as u]))
(register-sub :is-contact-selected?
- (fn [db [_ id]]
- (-> (:selected-contacts @db)
- (contains? id)
- (reaction))))
+ (u/contains-sub :selected-contacts))
diff --git a/src/status_im/new_group/views/contact.cljs b/src/status_im/new_group/views/contact.cljs
index a87b7d5fe2..cfec8a409d 100644
--- a/src/status_im/new_group/views/contact.cljs
+++ b/src/status_im/new_group/views/contact.cljs
@@ -8,7 +8,6 @@
(defn on-toggle [whisper-identity]
(fn [checked?]
- (println checked?)
(let [action (if checked? :select-contact :deselect-contact)]
(dispatch [action whisper-identity]))))
diff --git a/src/status_im/participants/handlers.cljs b/src/status_im/participants/handlers.cljs
new file mode 100644
index 0000000000..fe0e5581c0
--- /dev/null
+++ b/src/status_im/participants/handlers.cljs
@@ -0,0 +1,23 @@
+(ns status-im.participants.handlers
+ (:require [status-im.navigation.handlers :as nav]
+ [re-frame.core :refer [register-handler debug]]))
+
+(defmethod nav/preload-data! :add-participants
+ [db _]
+ (assoc db :selected-participants #{}))
+
+(defmethod nav/preload-data! :remove-participants
+ [db _]
+ (assoc db :selected-participants #{}))
+
+(defn deselect-participant
+ [db [_ id]]
+ (update db :selected-participants disj id))
+
+(register-handler :deselect-participant deselect-participant)
+
+(defn select-participant
+ [db [_ id]]
+ (update db :selected-participants conj id))
+
+(register-handler :select-participant (debug select-participant))
diff --git a/src/status_im/participants/subs.cljs b/src/status_im/participants/subs.cljs
new file mode 100644
index 0000000000..d351667a8a
--- /dev/null
+++ b/src/status_im/participants/subs.cljs
@@ -0,0 +1,7 @@
+(ns status-im.participants.subs
+ (:require-macros [reagent.ratom :refer [reaction]])
+ (:require [re-frame.core :refer [register-sub]]
+ [status-im.utils.subs :as u]))
+
+(register-sub :is-participant-selected?
+ (u/contains-sub :selected-participants))
diff --git a/src/status_im/participants/views/add.cljs b/src/status_im/participants/views/add.cljs
new file mode 100644
index 0000000000..5bab93ea1c
--- /dev/null
+++ b/src/status_im/participants/views/add.cljs
@@ -0,0 +1,30 @@
+(ns status-im.participants.views.add
+ (:require-macros [status-im.utils.views :refer [defview]])
+ (:require [re-frame.core :refer [subscribe dispatch]]
+ [status-im.resources :as res]
+ [status-im.components.react :refer [view list-view list-item]]
+ [status-im.components.toolbar :refer [toolbar]]
+ [status-im.utils.listview :refer [to-datasource]]
+ [status-im.participants.views.contact :refer [participant-contact]]
+ [reagent.core :as r]
+ [status-im.participants.styles :as st]))
+
+(defn new-participants-toolbar []
+ [toolbar
+ {:title "Add Participants"
+ :action {:image {:source res/v ;; {:uri "icon_search"}
+ :style st/new-participant-image}
+ :handler #(do (dispatch [:add-new-participants])
+ (dispatch [:navigate-back]))}}])
+
+(defn new-participants-row
+ [row _ _]
+ (list-item [participant-contact row]))
+
+(defview new-participants []
+ [contacts [:all-new-contacts]]
+ [view st/participants-container
+ [new-participants-toolbar]
+ [list-view {:dataSource (to-datasource contacts)
+ :renderRow new-participants-row
+ :style st/participants-list}]])
diff --git a/src/status_im/participants/views/contact.cljs b/src/status_im/participants/views/contact.cljs
index de6ccd9287..0311510e9b 100644
--- a/src/status_im/participants/views/contact.cljs
+++ b/src/status_im/participants/views/contact.cljs
@@ -1,4 +1,5 @@
(ns status-im.participants.views.contact
+ (:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[status-im.components.react :refer [view]]
[status-im.contacts.views.contact-inner :refer [contact-inner-view]]
@@ -6,14 +7,17 @@
[reagent.core :as r]
[status-im.participants.styles :as st]))
-(defn participant-contact [{:keys [whisper-identity] :as contact}]
- ;; todo must be moved to handlers
- (let [checked (r/atom false)]
- (fn [{:keys [whisper-identity] :as contact}]
- [view st/participant-container
- [item-checkbox {:onToggle (fn [checked?]
- (reset! checked checked?)
- (dispatch [:select-new-participant whisper-identity checked?]))
- :checked @checked
- :size 30}]
- [contact-inner-view contact]])))
+;; todo duplication
+(defn on-toggle [whisper-identity]
+ (fn [checked?]
+ (let [action (if checked? :select-participant :deselect-participant)]
+ (dispatch [action whisper-identity]))))
+
+(defview participant-contact
+ [{:keys [whisper-identity] :as contact}]
+ [checked [:is-participant-selected? whisper-identity]]
+ [view st/participant-container
+ [item-checkbox {:onToggle (on-toggle whisper-identity)
+ :checked checked
+ :size 30}]
+ [contact-inner-view contact]])
diff --git a/src/status_im/participants/views/create.cljs b/src/status_im/participants/views/create.cljs
deleted file mode 100644
index a0ede9b5ef..0000000000
--- a/src/status_im/participants/views/create.cljs
+++ /dev/null
@@ -1,30 +0,0 @@
-(ns status-im.participants.views.create
- (:require [re-frame.core :refer [subscribe dispatch]]
- [status-im.resources :as res]
- [status-im.components.react :refer [view list-view list-item]]
- [status-im.components.toolbar :refer [toolbar]]
- [status-im.utils.listview :refer [to-datasource]]
- [status-im.participants.views.contact :refer [participant-contact]]
- [reagent.core :as r]
- [status-im.participants.styles :as st]))
-
-(defn new-participants-toolbar []
- [toolbar
- {:title "Add Participants"
- :action {:image {:source res/v ;; {:uri "icon_search"}
- :style st/new-participant-image}
- :handler #(dispatch [:add-new-participants])}}])
-
-(defn new-participants-row
- [row _ _]
- (list-item [participant-contact row]))
-
-(defn new-participants []
- (let [contacts (subscribe [:all-new-contacts])]
- (fn []
- (let [contacts-ds (to-datasource @contacts)]
- [view st/participants-container
- [new-participants-toolbar]
- [list-view {:dataSource contacts-ds
- :renderRow new-participants-row
- :style st/participants-list}]]))))
diff --git a/src/status_im/participants/views/remove.cljs b/src/status_im/participants/views/remove.cljs
index 68aa8f0cd4..e7b8103ffe 100644
--- a/src/status_im/participants/views/remove.cljs
+++ b/src/status_im/participants/views/remove.cljs
@@ -1,4 +1,5 @@
(ns status-im.participants.views.remove
+ (:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]]
[status-im.resources :as res]
[status-im.components.react :refer [view text-input text image
@@ -13,21 +14,20 @@
(defn remove-participants-toolbar []
[toolbar
- {:title "Remove Participants"
- :action {:handler #(dispatch [:remove-selected-participants])
- :image {:source res/trash-icon ;; {:uri "icon_search"}
- :style st/remove-participants-image}}}])
+ {:title "Remove Participants"
+ :action {:handler #(do (dispatch [:remove-participants])
+ (dispatch [:navigate-back]))
+ :image {:source res/trash-icon ;; {:uri "icon_search"}
+ :style st/remove-participants-image}}}])
(defn remove-participants-row
[row _ _]
(r/as-element [participant-contact row]))
-(defn remove-participants []
- (let [contacts (subscribe [:current-chat-contacts])]
- (fn []
- (let [contacts-ds (to-datasource @contacts)]
- [view st/participants-container
- [remove-participants-toolbar]
- [list-view {:dataSource contacts-ds
- :renderRow remove-participants-row
- :style st/participants-list}]]))))
+(defview remove-participants []
+ [contacts [:current-chat-contacts]]
+ [view st/participants-container
+ [remove-participants-toolbar]
+ [list-view {:dataSource (to-datasource contacts)
+ :renderRow remove-participants-row
+ :style st/participants-list}]])
diff --git a/src/status_im/profile/screen.cljs b/src/status_im/profile/screen.cljs
index f3082555fd..83470681dc 100644
--- a/src/status_im/profile/screen.cljs
+++ b/src/status_im/profile/screen.cljs
@@ -20,7 +20,7 @@
(defn message-user [identity]
(when identity
- (dispatch [:show-chat identity :push])))
+ (dispatch [:navigate-to :chat identity])))
(defview profile []
[{:keys [name whisper-identity phone-number]} [:contact]]
diff --git a/src/status_im/protocol/handlers.cljs b/src/status_im/protocol/handlers.cljs
new file mode 100644
index 0000000000..4b51c9ec65
--- /dev/null
+++ b/src/status_im/protocol/handlers.cljs
@@ -0,0 +1,115 @@
+; todo everything inside this namespace must be revievew in common with future
+; changes in protocol lib
+(ns status-im.protocol.handlers
+ (:require [status-im.utils.handlers :as u]
+ [status-im.utils.logging :as log]
+ [status-im.protocol.api :as api]
+ [re-frame.core :refer [register-handler dispatch debug]]
+ [status-im.models.contacts :as contacts]
+ [status-im.protocol.api :refer [init-protocol]]
+ [status-im.protocol.protocol-handler :refer [make-handler]]
+ [status-im.models.protocol :refer [update-identity
+ set-initialized]]
+ [status-im.constants :refer [text-content-type]]
+ [status-im.models.messages :as messages]
+ [status-im.models.chats :as chats]))
+
+(register-handler :initialize-protocol
+ (u/side-effect!
+ (fn [db [_]]
+ (init-protocol (make-handler db)))))
+
+(register-handler :protocol-initialized
+ (fn [db [_ identity]]
+ (-> db
+ (update-identity identity)
+ (set-initialized true))))
+
+(defn system-message [msg-id content]
+ {:from "system"
+ :msg-id msg-id
+ :content content
+ :content-type text-content-type})
+
+(defn joined-chat-msg [chat-id from msg-id]
+ (let [contact-name (:name (contacts/contact-by-identity from))]
+ (messages/save-message chat-id {:from "system"
+ :msg-id (str msg-id "_" from)
+ :content (str (or contact-name from) " received chat invitation")
+ :content-type text-content-type})))
+
+(defn participant-invited-to-group-msg [chat-id identity from msg-id]
+ (let [inviter-name (:name (contacts/contact-by-identity from))
+ invitee-name (if (= identity (api/my-identity))
+ "You"
+ (:name (contacts/contact-by-identity identity)))]
+ (messages/save-message chat-id {:from "system"
+ :msg-id msg-id
+ :content (str (or inviter-name from) " invited " (or invitee-name identity))
+ :content-type text-content-type})))
+
+(defn participant-removed-from-group-msg [chat-id identity from msg-id]
+ (let [remover-name (:name (contacts/contact-by-identity from))
+ removed-name (:name (contacts/contact-by-identity identity))]
+ (->> (str (or remover-name from) " removed " (or removed-name identity))
+ (system-message msg-id)
+ (messages/save-message chat-id))))
+
+(defn you-removed-from-group-msg [chat-id from msg-id]
+ (let [remover-name (:name (contacts/contact-by-identity from))]
+ (->> (str (or remover-name from) " removed you from group chat")
+ (system-message msg-id)
+ (messages/save-message chat-id))))
+
+(defn participant-left-group-msg [chat-id from msg-id]
+ (let [left-name (:name (contacts/contact-by-identity from))]
+ (->> (str (or left-name from) " left")
+ (system-message msg-id)
+ (messages/save-message chat-id))))
+
+(register-handler :group-chat-invite-acked
+ (u/side-effect!
+ (fn [_ [action from group-id ack-msg-id]]
+ (log/debug action from group-id ack-msg-id)
+ (joined-chat-msg group-id from ack-msg-id))))
+
+(register-handler :participant-removed-from-group
+ (u/side-effect!
+ (fn [_ [action from group-id identity msg-id]]
+ (log/debug action msg-id from group-id identity)
+ (chats/chat-remove-participants group-id [identity])
+ (participant-removed-from-group-msg group-id identity from msg-id))))
+
+(register-handler :you-removed-from-group
+ (u/side-effect!
+ (fn [_ [action from group-id msg-id]]
+ (log/debug action msg-id from group-id)
+ (you-removed-from-group-msg group-id from msg-id)
+ (chats/set-chat-active group-id false))))
+
+(register-handler :participant-left-group
+ (u/side-effect!
+ (fn [_ [action from group-id msg-id]]
+ (log/debug action msg-id from group-id)
+ (when-not (= (api/my-identity) from)
+ (participant-left-group-msg group-id from msg-id)))))
+
+(register-handler :participant-invited-to-group
+ (u/side-effect!
+ (fn [_ [action from group-id identity msg-id]]
+ (log/debug action msg-id from group-id identity)
+ (participant-invited-to-group-msg group-id identity from msg-id))))
+
+(register-handler :acked-msg
+ (u/side-effect!
+ (fn [_ [action from msg-id]]
+ (log/debug action from msg-id)
+ (messages/update-message! {:msg-id msg-id
+ :delivery-status :delivered}))))
+
+(register-handler :msg-delivery-failed
+ (u/side-effect!
+ (fn [_ [action msg-id]]
+ (log/debug action msg-id)
+ (messages/update-message! {:msg-id msg-id
+ :delivery-status :failed}))))
diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs
index 8c1125d35d..972c57887c 100644
--- a/src/status_im/subs.cljs
+++ b/src/status_im/subs.cljs
@@ -5,8 +5,13 @@
status-im.group-settings.subs
status-im.discovery.subs
status-im.contacts.subs
- status-im.new-group.subs))
+ status-im.new-group.subs
+ status-im.participants.subs))
(register-sub :get
(fn [db [_ k]]
(reaction (k @db))))
+
+(register-sub :get-in
+ (fn [db [_ path]]
+ (reaction (get-in @db path))))
diff --git a/src/status_im/utils/subs.cljs b/src/status_im/utils/subs.cljs
new file mode 100644
index 0000000000..3be283c37e
--- /dev/null
+++ b/src/status_im/utils/subs.cljs
@@ -0,0 +1,11 @@
+(ns status-im.utils.subs
+ (:require-macros [reagent.ratom :refer [reaction]]))
+
+(defn contains-sub
+ "Creates subscrition that cheks if collection (map or set) contains element"
+ [collection]
+ (fn [db [_ element]]
+ (println "WWWWWWWWWW" (type db))
+ (-> (collection @db)
+ (contains? element)
+ (reaction))))