Merge remote-tracking branch 'origin/develop' into real-data. Fix contacts synchronization.
# Conflicts: # .re-natal # android/app/build.gradle # android/app/src/main/java/com/statusim/MainActivity.java # android/settings.gradle # src/status_im/chat/handlers.cljs # src/status_im/chat/screen.cljs # src/status_im/chats_list/views/chat_list_item.cljs # src/status_im/db.cljs # src/status_im/group_settings/screen.cljs Former-commit-id: dcc607022f4e62e4c544495220c3130c5c30b026
@ -15,6 +15,7 @@
|
||||
"react-native-circle-checkbox",
|
||||
"react-native-randombytes",
|
||||
"dismissKeyboard",
|
||||
"react-native-linear-gradient",
|
||||
"react-native-android-sms-listener"
|
||||
],
|
||||
"imageDirs": [
|
||||
|
@ -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
|
||||
|
||||
|
@ -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')
|
||||
|
@ -4,6 +4,7 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
|
||||
<uses-permission android:name="android.permission.READ_PROFILE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
|
||||
<application
|
||||
|
@ -10,6 +10,7 @@ import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import com.github.ethereum.go_ethereum.cmd.Geth;
|
||||
import com.bitgo.randombytes.RandomBytesPackage;
|
||||
import com.BV.LinearGradient.LinearGradientPackage;
|
||||
import com.centaurwarchief.smslistener.SmsListener;
|
||||
|
||||
import java.util.Arrays;
|
||||
@ -80,6 +81,7 @@ public class MainActivity extends ReactActivity {
|
||||
new ReactNativeContacts(),
|
||||
new ReactNativeI18n(),
|
||||
new RandomBytesPackage(),
|
||||
new LinearGradientPackage(),
|
||||
new SmsListener(this)
|
||||
);
|
||||
}
|
||||
|
BIN
android/app/src/main/res/drawable-hdpi/icon_ok_purple.png
Normal file
After Width: | Height: | Size: 644 B |
BIN
android/app/src/main/res/drawable-hdpi/icon_tab_chats.png
Normal file
After Width: | Height: | Size: 537 B |
BIN
android/app/src/main/res/drawable-hdpi/icon_tab_contacts.png
Normal file
After Width: | Height: | Size: 792 B |
BIN
android/app/src/main/res/drawable-hdpi/icon_tab_discovery.png
Normal file
After Width: | Height: | Size: 891 B |
BIN
android/app/src/main/res/drawable-mdpi/icon_ok_purple.png
Normal file
After Width: | Height: | Size: 504 B |
BIN
android/app/src/main/res/drawable-mdpi/icon_tab_chats.png
Normal file
After Width: | Height: | Size: 295 B |
BIN
android/app/src/main/res/drawable-mdpi/icon_tab_contacts.png
Normal file
After Width: | Height: | Size: 504 B |
BIN
android/app/src/main/res/drawable-mdpi/icon_tab_discovery.png
Normal file
After Width: | Height: | Size: 617 B |
BIN
android/app/src/main/res/drawable-xhdpi/icon_ok_purple.png
Normal file
After Width: | Height: | Size: 931 B |
BIN
android/app/src/main/res/drawable-xhdpi/icon_tab_chats.png
Normal file
After Width: | Height: | Size: 435 B |
BIN
android/app/src/main/res/drawable-xhdpi/icon_tab_contacts.png
Normal file
After Width: | Height: | Size: 936 B |
BIN
android/app/src/main/res/drawable-xhdpi/icon_tab_discovery.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
android/app/src/main/res/drawable-xxhdpi/icon_ok_purple.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
android/app/src/main/res/drawable-xxhdpi/icon_tab_chats.png
Normal file
After Width: | Height: | Size: 651 B |
BIN
android/app/src/main/res/drawable-xxhdpi/icon_tab_contacts.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
android/app/src/main/res/drawable-xxhdpi/icon_tab_discovery.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
android/app/src/main/res/drawable-xxxhdpi/icon_ok_purple.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
android/app/src/main/res/drawable-xxxhdpi/icon_tab_chats.png
Normal file
After Width: | Height: | Size: 777 B |
BIN
android/app/src/main/res/drawable-xxxhdpi/icon_tab_contacts.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
android/app/src/main/res/drawable-xxxhdpi/icon_tab_discovery.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
android/app/src/main/res/mipmap-hdpi/ic_launcher.png
Normal file → Executable file
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 2.4 KiB |
BIN
android/app/src/main/res/mipmap-mdpi/ic_launcher.png
Normal file → Executable file
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 1.4 KiB |
BIN
android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Normal file → Executable file
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 3.5 KiB |
BIN
android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Normal file → Executable file
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 6.5 KiB |
BIN
android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Executable file
After Width: | Height: | Size: 10 KiB |
@ -14,5 +14,7 @@ include ':realm'
|
||||
project(':realm').projectDir = new File(rootProject.projectDir, '../node_modules/realm/android')
|
||||
include ':randombytes'
|
||||
project(':randombytes').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-randombytes/app')
|
||||
include ':react-native-linear-gradient'
|
||||
project(':react-native-linear-gradient').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-linear-gradient/android')
|
||||
include ':ReactNativeAndroidSmsListener'
|
||||
project(':ReactNativeAndroidSmsListener').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-android-sms-listener/android')
|
||||
|
2
env/dev/env/android/main.cljs
vendored
@ -10,7 +10,7 @@
|
||||
(def root-el (r/as-element [reloader]))
|
||||
|
||||
(figwheel/watch-and-reload
|
||||
:websocket-url "ws://localhost:3449/figwheel-ws"
|
||||
:websocket-url "ws://10.0.3.2:3449/figwheel-ws"
|
||||
:heads-up-display false
|
||||
:jsload-callback #(swap! cnt inc))
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
"react-native-contacts": "^0.2.4",
|
||||
"react-native-i18n": "0.0.8",
|
||||
"react-native-invertible-scroll-view": "^1.0.0",
|
||||
"react-native-linear-gradient": "^1.5.7",
|
||||
"react-native-loading-spinner-overlay": "0.0.8",
|
||||
"react-native-randombytes": "^2.0.0",
|
||||
"react-native-vector-icons": "^1.3.4",
|
||||
|
@ -12,10 +12,9 @@
|
||||
[status-im.chat.screen :refer [chat]]
|
||||
[status-im.chats-list.screen :refer [chats-list]]
|
||||
[status-im.new-group.screen :refer [new-group]]
|
||||
[status-im.participants.views.create :refer [new-participants]]
|
||||
[status-im.participants.views.add :refer [new-participants]]
|
||||
[status-im.participants.views.remove :refer [remove-participants]]
|
||||
[status-im.group-settings.screen :refer [group-settings]]
|
||||
[status-im.group-settings.views.chat-name-edit :refer [chat-name-edit]]
|
||||
[status-im.profile.screen :refer [profile my-profile]]
|
||||
[status-im.utils.utils :refer [toast]]
|
||||
[status-im.utils.encryption]))
|
||||
@ -43,7 +42,6 @@
|
||||
:chat-list [chats-list]
|
||||
:new-group [new-group]
|
||||
:group-settings [group-settings]
|
||||
:chat-name-edit [chat-name-edit]
|
||||
:contact-list [contact-list]
|
||||
:chat [chat]
|
||||
:profile [profile]
|
||||
|
@ -7,12 +7,13 @@
|
||||
[status-im.protocol.api :as api]
|
||||
[status-im.models.messages :as messages]
|
||||
[status-im.constants :refer [text-content-type
|
||||
content-type-command]]
|
||||
content-type-command]]
|
||||
[status-im.utils.random :as random]
|
||||
[status-im.chat.sign-up :as sign-up-service]
|
||||
[status-im.models.chats :as chats]
|
||||
[status-im.navigation.handlers :as nav]
|
||||
[status-im.utils.handlers :as u]
|
||||
[status-im.persistence.realm :as r]
|
||||
[status-im.handlers.server :as server]
|
||||
[status-im.utils.phone-number :refer [format-phone-number]]
|
||||
[status-im.utils.datetime :as time]))
|
||||
@ -192,7 +193,8 @@
|
||||
((enrich add-commands))
|
||||
((enrich clear-input))
|
||||
((enrich clear-staged-commands))
|
||||
((after send-message!))
|
||||
;; todo uncomment once
|
||||
;((after send-message!))
|
||||
((after save-message-to-realm!))
|
||||
((after save-commands-to-realm!))
|
||||
((after handle-commands))))
|
||||
@ -295,10 +297,14 @@
|
||||
|
||||
(defmethod nav/preload-data! :chat
|
||||
[{:keys [current-chat-id] :as db} [_ _ id]]
|
||||
(-> 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!))))
|
||||
|
@ -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]
|
||||
|
@ -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.))
|
||||
|
@ -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]]])))
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
30
src/status_im/components/main_tabs.cljs
Normal file
@ -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}]}])
|
@ -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))
|
||||
|
||||
|
56
src/status_im/components/tabs/styles.cljs
Normal file
@ -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})
|
||||
|
19
src/status_im/components/tabs/tab.cljs
Normal file
@ -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])]])
|
26
src/status_im/components/tabs/tabs.cljs
Normal file
@ -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))]]))
|
@ -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)]
|
||||
|
@ -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]])
|
||||
|
@ -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})
|
||||
|
@ -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]
|
||||
|
@ -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]])
|
||||
|
@ -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
|
||||
|
@ -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 [])}}]
|
||||
|
@ -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))))
|
||||
|
@ -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]])
|
||||
|
@ -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})
|
@ -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
|
||||
|
@ -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]))))
|
||||
|
@ -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]])
|
@ -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]]]])
|
||||
|
@ -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)))
|
||||
|
@ -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]))
|
||||
|
@ -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))))
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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]]
|
||||
|
@ -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))
|
||||
|
@ -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]))))
|
||||
|
||||
|
23
src/status_im/participants/handlers.cljs
Normal file
@ -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))
|
7
src/status_im/participants/subs.cljs
Normal file
@ -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))
|
30
src/status_im/participants/views/add.cljs
Normal file
@ -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}]])
|
@ -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]])
|
||||
|
@ -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}]]))))
|
@ -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}]])
|
||||
|
@ -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]]
|
||||
|
115
src/status_im/protocol/handlers.cljs
Normal file
@ -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}))))
|
@ -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))))
|
||||
|
11
src/status_im/utils/subs.cljs
Normal file
@ -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))))
|