Merge pull request #72 from status-im/group-chat-settings
Group chat settings
Former-commit-id: 9a76ea9855
After Width: | Height: | Size: 358 B |
After Width: | Height: | Size: 823 B |
After Width: | Height: | Size: 217 B |
After Width: | Height: | Size: 585 B |
After Width: | Height: | Size: 412 B |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 616 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 889 B |
After Width: | Height: | Size: 1.7 KiB |
|
@ -14,6 +14,8 @@
|
||||||
[syng-im.new-group.screen :refer [new-group]]
|
[syng-im.new-group.screen :refer [new-group]]
|
||||||
[syng-im.participants.views.create :refer [new-participants]]
|
[syng-im.participants.views.create :refer [new-participants]]
|
||||||
[syng-im.participants.views.remove :refer [remove-participants]]
|
[syng-im.participants.views.remove :refer [remove-participants]]
|
||||||
|
[syng-im.group-settings.screen :refer [group-settings]]
|
||||||
|
[syng-im.group-settings.views.chat-name-edit :refer [chat-name-edit]]
|
||||||
[syng-im.profile.screen :refer [profile my-profile]]
|
[syng-im.profile.screen :refer [profile my-profile]]
|
||||||
[syng-im.utils.utils :refer [toast]]
|
[syng-im.utils.utils :refer [toast]]
|
||||||
[syng-im.utils.encryption]))
|
[syng-im.utils.encryption]))
|
||||||
|
@ -40,6 +42,8 @@
|
||||||
:remove-participants [remove-participants]
|
:remove-participants [remove-participants]
|
||||||
:chat-list [chats-list]
|
:chat-list [chats-list]
|
||||||
:new-group [new-group]
|
:new-group [new-group]
|
||||||
|
:group-settings [group-settings]
|
||||||
|
:chat-name-edit [chat-name-edit]
|
||||||
:contact-list [contact-list]
|
:contact-list [contact-list]
|
||||||
:chat [chat]
|
:chat [chat]
|
||||||
:profile [profile]
|
:profile [profile]
|
||||||
|
|
|
@ -132,11 +132,10 @@
|
||||||
:height 21}
|
:height 21}
|
||||||
:handler #(dispatch [:leave-group-chat])}
|
:handler #(dispatch [:leave-group-chat])}
|
||||||
{:title "Settings"
|
{:title "Settings"
|
||||||
:subtitle "Not implemented"
|
|
||||||
:icon :settings
|
:icon :settings
|
||||||
:icon-style {:width 20
|
:icon-style {:width 20
|
||||||
:height 13}
|
:height 13}
|
||||||
:handler (fn [])}]
|
:handler #(dispatch [:show-group-settings])}]
|
||||||
[{:title "Profile"
|
[{:title "Profile"
|
||||||
:custom-icon [menu-item-icon-profile]
|
:custom-icon [menu-item-icon-profile]
|
||||||
:icon :menu_group
|
:icon :menu_group
|
||||||
|
@ -148,15 +147,13 @@
|
||||||
:icon :search_gray_copy
|
:icon :search_gray_copy
|
||||||
:icon-style {:width 17
|
:icon-style {:width 17
|
||||||
:height 17}
|
:height 17}
|
||||||
:handler nil #_#(dispatch
|
:handler nil}
|
||||||
[:show-remove-participants navigator])}
|
|
||||||
{:title "Notifications and sounds"
|
{:title "Notifications and sounds"
|
||||||
:subtitle "!not implemented"
|
:subtitle "!not implemented"
|
||||||
:icon :muted
|
:icon :muted
|
||||||
:icon-style {:width 18
|
:icon-style {:width 18
|
||||||
:height 21}
|
:height 21}
|
||||||
:handler nil #_#(dispatch [:leave-group-chat
|
:handler nil}
|
||||||
navigator])}
|
|
||||||
{:title "Settings"
|
{:title "Settings"
|
||||||
:subtitle "!not implemented"
|
:subtitle "!not implemented"
|
||||||
:icon :settings
|
:icon :settings
|
||||||
|
@ -227,12 +224,11 @@
|
||||||
:dataSource (to-datasource messages)}]))
|
:dataSource (to-datasource messages)}]))
|
||||||
|
|
||||||
(defview chat []
|
(defview chat []
|
||||||
[is-active [:chat :is-active]
|
[group-chat [:chat :group-chat]
|
||||||
group-chat [:chat :group-chat]
|
|
||||||
show-actions-atom [:show-actions]]
|
show-actions-atom [:show-actions]]
|
||||||
[view st/chat-view
|
[view st/chat-view
|
||||||
[chat-toolbar]
|
[chat-toolbar]
|
||||||
[messages-view group-chat]
|
[messages-view group-chat]
|
||||||
(when group-chat [typing-all])
|
(when group-chat [typing-all])
|
||||||
(when is-active [chat-message-new])
|
[chat-message-new]
|
||||||
(when show-actions-atom [actions-view])])
|
(when show-actions-atom [actions-view])])
|
||||||
|
|
|
@ -30,6 +30,9 @@
|
||||||
text])
|
text])
|
||||||
(def drawer-layout-android (r/adapt-react-class (.-DrawerLayoutAndroid js/React)))
|
(def drawer-layout-android (r/adapt-react-class (.-DrawerLayoutAndroid js/React)))
|
||||||
(def touchable-opacity (r/adapt-react-class (.-TouchableOpacity js/React)))
|
(def touchable-opacity (r/adapt-react-class (.-TouchableOpacity js/React)))
|
||||||
|
(def modal (r/adapt-react-class (.-Modal js/React)))
|
||||||
|
(def picker (r/adapt-react-class (.-Picker js/React)))
|
||||||
|
(def picker-item (r/adapt-react-class (.-Item (.-Picker js/React))))
|
||||||
|
|
||||||
|
|
||||||
(defn icon [n style]
|
(defn icon [n style]
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
|
|
||||||
(def font "sans-serif")
|
(def font "sans-serif")
|
||||||
;; (def font "Avenir-Roman")
|
;; (def font "Avenir-Roman")
|
||||||
(def title-font "sans-serif-medium")
|
(def font-medium "sans-serif-medium")
|
||||||
|
(def title-font font-medium)
|
||||||
|
|
||||||
(def color-blue "#7099e6")
|
(def color-blue "#7099e6")
|
||||||
(def color-blue-transparent "#7099e632")
|
(def color-blue-transparent "#7099e632")
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
(ns syng-im.group-settings.handlers
|
||||||
|
(:require [re-frame.core :refer [register-handler debug dispatch]]
|
||||||
|
[syng-im.persistence.realm :as r]
|
||||||
|
[syng-im.models.messages :refer [clear-history]]))
|
||||||
|
|
||||||
|
(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)))
|
||||||
|
|
||||||
|
(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 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]))
|
||||||
|
|
||||||
|
(register-handler :show-group-settings
|
||||||
|
(fn [db [action]]
|
||||||
|
(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)))
|
||||||
|
|
||||||
|
(register-handler :set-chat-name
|
||||||
|
(fn [db [action]]
|
||||||
|
(set-chat-name db)))
|
||||||
|
|
||||||
|
(register-handler :set-chat-color
|
||||||
|
(fn [db [action]]
|
||||||
|
(set-chat-color db)))
|
||||||
|
|
||||||
|
(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?)))
|
||||||
|
|
||||||
|
(register-handler :clear-history
|
||||||
|
(fn [db [action]]
|
||||||
|
(clear-history (:current-chat-id db))))
|
|
@ -0,0 +1,167 @@
|
||||||
|
(ns syng-im.group-settings.screen
|
||||||
|
(:require-macros [syng-im.utils.views :refer [defview]])
|
||||||
|
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
|
[syng-im.resources :as res]
|
||||||
|
[syng-im.components.react :refer [view
|
||||||
|
text-input
|
||||||
|
text
|
||||||
|
image
|
||||||
|
icon
|
||||||
|
modal
|
||||||
|
picker
|
||||||
|
picker-item
|
||||||
|
scroll-view
|
||||||
|
touchable-highlight]]
|
||||||
|
[syng-im.components.toolbar :refer [toolbar]]
|
||||||
|
[syng-im.components.realm :refer [list-view]]
|
||||||
|
[syng-im.components.styles :refer [color-purple
|
||||||
|
text2-color]]
|
||||||
|
[syng-im.group-settings.styles.group-settings :as st]
|
||||||
|
[syng-im.group-settings.views.member :refer [member-view]]
|
||||||
|
[reagent.core :as r]))
|
||||||
|
|
||||||
|
(defn remove-member [{:keys [whisper-identity]}]
|
||||||
|
(dispatch [:chat-remove-member whisper-identity]))
|
||||||
|
|
||||||
|
(defn close-member-menu []
|
||||||
|
(dispatch [:select-group-chat-member nil]))
|
||||||
|
|
||||||
|
(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"]]]]])
|
||||||
|
|
||||||
|
(defview chat-members []
|
||||||
|
[members [:current-chat-contacts]]
|
||||||
|
[view st/chat-members-container
|
||||||
|
(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}
|
||||||
|
[view st/setting-row
|
||||||
|
[view st/setting-icon-view
|
||||||
|
(or custom-icon
|
||||||
|
[icon icon-name icon-style])]
|
||||||
|
[view st/setting-view
|
||||||
|
[text {:style st/setting-title} title]
|
||||||
|
(when-let [subtitle subtitle]
|
||||||
|
[text {:style st/setting-subtitle}
|
||||||
|
subtitle])]]])
|
||||||
|
|
||||||
|
(defn close-chat-color-picker []
|
||||||
|
(dispatch [:set-group-settings-show-color-picker false]))
|
||||||
|
|
||||||
|
(defn set-chat-color []
|
||||||
|
(close-chat-color-picker)
|
||||||
|
(dispatch [:set-chat-color]))
|
||||||
|
|
||||||
|
(defview chat-color-picker []
|
||||||
|
[show-color-picker [:group-settings-show-color-picker]
|
||||||
|
new-color [:get :new-chat-color]]
|
||||||
|
[modal {:animated false
|
||||||
|
:transparent false
|
||||||
|
:onRequestClose close-chat-color-picker}
|
||||||
|
[touchable-highlight {:style st/modal-container
|
||||||
|
: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"}]]
|
||||||
|
[touchable-highlight {:on-press set-chat-color}
|
||||||
|
[text {:style st/modal-color-picker-save-btn-text}
|
||||||
|
"Save"]]]]])
|
||||||
|
|
||||||
|
(defview chat-color-icon []
|
||||||
|
[chat-color [:chat :color]]
|
||||||
|
[view {:style (st/chat-color-icon chat-color)}])
|
||||||
|
|
||||||
|
(defn show-chat-color-picker []
|
||||||
|
(dispatch [:set-group-settings-show-color-picker true]))
|
||||||
|
|
||||||
|
(defn settings-view []
|
||||||
|
;; TODO implement settings handlers
|
||||||
|
(let [settings [{:custom-icon [chat-color-icon]
|
||||||
|
:title "Change color"
|
||||||
|
:handler show-chat-color-picker}
|
||||||
|
(merge {:title "Notifications and sounds"
|
||||||
|
:subtitle "!not implemented"
|
||||||
|
:handler nil}
|
||||||
|
(if true
|
||||||
|
{:icon :notifications-on
|
||||||
|
:icon-style {:width 16
|
||||||
|
:height 21}}
|
||||||
|
{:icon :muted
|
||||||
|
:icon-style {:width 18
|
||||||
|
:height 21}}))
|
||||||
|
{:icon :close-gray
|
||||||
|
:icon-style {:width 12
|
||||||
|
:height 12}
|
||||||
|
:title "Clear history"
|
||||||
|
:handler #(dispatch [:clear-history])}
|
||||||
|
{:icon :bin
|
||||||
|
:icon-style {:width 12
|
||||||
|
:height 18}
|
||||||
|
:title "Delete and leave"
|
||||||
|
:handler #(dispatch [:leave-group-chat])}]]
|
||||||
|
[view st/settings-container
|
||||||
|
(for [setting settings]
|
||||||
|
^{:key setting} [setting-view setting])]))
|
||||||
|
|
||||||
|
(defview chat-icon []
|
||||||
|
[name [:chat :name]
|
||||||
|
color [:chat :color]]
|
||||||
|
[view (st/chat-icon color)
|
||||||
|
[text {:style st/chat-icon-text} (nth name 0)]])
|
||||||
|
|
||||||
|
(defn new-group-toolbar []
|
||||||
|
[toolbar {:title "Chat settings"
|
||||||
|
:custom-action [chat-icon]}])
|
||||||
|
|
||||||
|
(defview group-settings []
|
||||||
|
[chat-name [:chat :name]
|
||||||
|
selected-member [:group-settings-selected-member]
|
||||||
|
show-color-picker [:get :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"]
|
||||||
|
[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}
|
||||||
|
"Add members"]]]
|
||||||
|
[chat-members]
|
||||||
|
[text {:style st/settings-text}
|
||||||
|
"Settings"]
|
||||||
|
[settings-view]]
|
||||||
|
(when show-color-picker
|
||||||
|
[chat-color-picker])
|
||||||
|
(when selected-member
|
||||||
|
[member-menu])])
|
|
@ -0,0 +1,19 @@
|
||||||
|
(ns syng-im.group-settings.styles.chat-name-edit
|
||||||
|
(:require [syng-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})
|
|
@ -0,0 +1,185 @@
|
||||||
|
(ns syng-im.group-settings.styles.group-settings
|
||||||
|
(:require [syng-im.components.styles :refer [font
|
||||||
|
font-medium
|
||||||
|
title-font
|
||||||
|
color-white
|
||||||
|
color-purple
|
||||||
|
chat-background
|
||||||
|
online-color
|
||||||
|
selected-message-color
|
||||||
|
separator-color
|
||||||
|
text1-color
|
||||||
|
text2-color
|
||||||
|
toolbar-background1]]))
|
||||||
|
|
||||||
|
(def modal-container
|
||||||
|
{:flex 1
|
||||||
|
:justifyContent :center
|
||||||
|
:padding 20})
|
||||||
|
|
||||||
|
(def modal-inner-container
|
||||||
|
{:borderRadius 10
|
||||||
|
:alignItems :center
|
||||||
|
:padding 5
|
||||||
|
:backgroundColor color-white})
|
||||||
|
|
||||||
|
(def modal-member-name
|
||||||
|
{:color text2-color
|
||||||
|
:fontFamily font
|
||||||
|
:fontSize 14
|
||||||
|
:lineHeight 20})
|
||||||
|
|
||||||
|
(def modal-remove-text
|
||||||
|
{:margin 10
|
||||||
|
:color text1-color
|
||||||
|
:fontFamily font
|
||||||
|
:fontSize 14
|
||||||
|
:lineHeight 20})
|
||||||
|
|
||||||
|
(def modal-color-picker-inner-container
|
||||||
|
{:borderRadius 10
|
||||||
|
:padding 5
|
||||||
|
:backgroundColor color-white})
|
||||||
|
|
||||||
|
(def modal-color-picker-save-btn-text
|
||||||
|
{:margin 10
|
||||||
|
:alignSelf :center
|
||||||
|
:color text1-color
|
||||||
|
:fontFamily font
|
||||||
|
:fontSize 14
|
||||||
|
:lineHeight 20})
|
||||||
|
|
||||||
|
(def chat-members-container
|
||||||
|
{:marginBottom 10})
|
||||||
|
|
||||||
|
(defn chat-icon [color]
|
||||||
|
{:margin 10
|
||||||
|
:width 36
|
||||||
|
:height 36
|
||||||
|
:borderRadius 50
|
||||||
|
:backgroundColor color})
|
||||||
|
|
||||||
|
(def chat-icon-text
|
||||||
|
{:marginTop 7
|
||||||
|
:marginLeft 13
|
||||||
|
:color color-white
|
||||||
|
:fontFamily font
|
||||||
|
:fontSize 16
|
||||||
|
:lineHeight 20})
|
||||||
|
|
||||||
|
(def group-settings
|
||||||
|
{:flex 1
|
||||||
|
:flexDirection :column
|
||||||
|
:backgroundColor color-white})
|
||||||
|
|
||||||
|
(def body
|
||||||
|
{:flex 1
|
||||||
|
:flexDirection :column})
|
||||||
|
|
||||||
|
(def chat-name-text
|
||||||
|
{:marginTop 24
|
||||||
|
:marginLeft 16
|
||||||
|
:marginBottom 16
|
||||||
|
:color text2-color
|
||||||
|
:fontFamily font-medium
|
||||||
|
:fontSize 14
|
||||||
|
:lineHeight 20})
|
||||||
|
|
||||||
|
(def chat-name-value-container
|
||||||
|
{:flexDirection :row
|
||||||
|
:marginLeft 16
|
||||||
|
:height 56
|
||||||
|
:alignItems :center
|
||||||
|
:justifyContent :center
|
||||||
|
:borderBottomWidth 1
|
||||||
|
:borderBottomColor separator-color})
|
||||||
|
|
||||||
|
(def chat-name-value
|
||||||
|
{:flex 1
|
||||||
|
:fontSize 16
|
||||||
|
:fontFamily font
|
||||||
|
:color text1-color})
|
||||||
|
|
||||||
|
(def chat-name-btn-edit-container
|
||||||
|
{:padding 16
|
||||||
|
:justifyContent :center})
|
||||||
|
|
||||||
|
(def chat-name-btn-edit-text
|
||||||
|
{:marginTop -1
|
||||||
|
:color text2-color
|
||||||
|
:fontFamily font
|
||||||
|
:fontSize 16
|
||||||
|
:lineHeight 20})
|
||||||
|
|
||||||
|
(def members-text
|
||||||
|
{:marginTop 24
|
||||||
|
:marginLeft 16
|
||||||
|
:marginBottom 16
|
||||||
|
:color text2-color
|
||||||
|
:fontFamily font-medium
|
||||||
|
:fontSize 14
|
||||||
|
:lineHeight 20})
|
||||||
|
|
||||||
|
(def add-members-icon
|
||||||
|
{:marginVertical 19
|
||||||
|
:marginLeft 19
|
||||||
|
:marginHorizontal 3
|
||||||
|
:width 17
|
||||||
|
:height 17})
|
||||||
|
|
||||||
|
(def add-members-container
|
||||||
|
{:flexDirection :row})
|
||||||
|
|
||||||
|
(def add-members-text
|
||||||
|
{:marginTop 18
|
||||||
|
:marginLeft 32
|
||||||
|
:color text2-color
|
||||||
|
:fontFamily font
|
||||||
|
:fontSize 16
|
||||||
|
:lineHeight 20})
|
||||||
|
|
||||||
|
(def settings-text
|
||||||
|
{:marginTop 24
|
||||||
|
:marginLeft 16
|
||||||
|
:marginBottom 16
|
||||||
|
:color text2-color
|
||||||
|
:fontFamily font-medium
|
||||||
|
:fontSize 14
|
||||||
|
:lineHeight 20})
|
||||||
|
|
||||||
|
(def settings-container
|
||||||
|
{:flexDirection :column})
|
||||||
|
|
||||||
|
(def setting-row
|
||||||
|
{:flexDirection :row
|
||||||
|
:height 56})
|
||||||
|
|
||||||
|
(def setting-icon-view
|
||||||
|
{:width 56
|
||||||
|
:height 56
|
||||||
|
:alignItems :center
|
||||||
|
:justifyContent :center})
|
||||||
|
|
||||||
|
(def setting-view
|
||||||
|
{:flex 1
|
||||||
|
:marginLeft 16
|
||||||
|
:alignItems :flex-start
|
||||||
|
:justifyContent :center})
|
||||||
|
|
||||||
|
(def setting-title
|
||||||
|
{:marginTop -2.5
|
||||||
|
:color text1-color
|
||||||
|
:fontSize 16
|
||||||
|
:fontFamily font})
|
||||||
|
|
||||||
|
(def setting-subtitle
|
||||||
|
{:marginTop 1
|
||||||
|
:color text2-color
|
||||||
|
:fontSize 12
|
||||||
|
:fontFamily font})
|
||||||
|
|
||||||
|
(defn chat-color-icon [color]
|
||||||
|
{:borderRadius 50
|
||||||
|
:width 24
|
||||||
|
:height 24
|
||||||
|
:backgroundColor color})
|
|
@ -0,0 +1,78 @@
|
||||||
|
(ns syng-im.group-settings.styles.member
|
||||||
|
(:require [syng-im.components.styles :refer [font
|
||||||
|
title-font
|
||||||
|
text1-color
|
||||||
|
text2-color
|
||||||
|
color-white
|
||||||
|
online-color]]))
|
||||||
|
|
||||||
|
(def contact-photo-container
|
||||||
|
{:borderRadius 50})
|
||||||
|
|
||||||
|
(def photo-image
|
||||||
|
{:borderRadius 50
|
||||||
|
:width 40
|
||||||
|
:height 40})
|
||||||
|
|
||||||
|
(def online-container
|
||||||
|
{:position :absolute
|
||||||
|
:top 24
|
||||||
|
:left 24
|
||||||
|
:width 20
|
||||||
|
:height 20
|
||||||
|
:borderRadius 50
|
||||||
|
:backgroundColor online-color
|
||||||
|
:borderWidth 2
|
||||||
|
:borderColor color-white})
|
||||||
|
|
||||||
|
(def online-dot
|
||||||
|
{:position :absolute
|
||||||
|
:top 6
|
||||||
|
:width 4
|
||||||
|
:height 4
|
||||||
|
:borderRadius 50
|
||||||
|
:backgroundColor color-white})
|
||||||
|
|
||||||
|
(def online-dot-left
|
||||||
|
(assoc online-dot :left 3))
|
||||||
|
|
||||||
|
(def online-dot-right
|
||||||
|
(assoc online-dot :left 9))
|
||||||
|
|
||||||
|
(def contact-container
|
||||||
|
{:flexDirection :row
|
||||||
|
:height 56})
|
||||||
|
|
||||||
|
(def photo-container
|
||||||
|
{:marginTop 8
|
||||||
|
:marginLeft 16
|
||||||
|
:width 44
|
||||||
|
:height 44})
|
||||||
|
|
||||||
|
(def info-container
|
||||||
|
{:flex 1
|
||||||
|
:flexDirection :column
|
||||||
|
:marginLeft 16
|
||||||
|
:justifyContent :center})
|
||||||
|
|
||||||
|
(def name-text
|
||||||
|
{:marginTop -2
|
||||||
|
:fontSize 16
|
||||||
|
:fontFamily font
|
||||||
|
:color text1-color})
|
||||||
|
|
||||||
|
(def role-text
|
||||||
|
{:marginTop 1
|
||||||
|
:fontSize 12
|
||||||
|
:fontFamily font
|
||||||
|
:color text2-color})
|
||||||
|
|
||||||
|
(def more-btn
|
||||||
|
{:width 56
|
||||||
|
:height 56
|
||||||
|
:alignItems :center
|
||||||
|
:justifyContent :center })
|
||||||
|
|
||||||
|
(def more-btn-icon
|
||||||
|
{:width 4
|
||||||
|
:height 16})
|
|
@ -0,0 +1,14 @@
|
||||||
|
(ns syng-im.group-settings.subs
|
||||||
|
(:require-macros [reagent.ratom :refer [reaction]])
|
||||||
|
(:require [re-frame.core :refer [register-sub]]
|
||||||
|
[syng-im.models.contacts :refer [contact-by-identity]]))
|
||||||
|
|
||||||
|
(register-sub :group-settings-selected-member
|
||||||
|
(fn [db [_]]
|
||||||
|
(reaction
|
||||||
|
(let [identity (get @db :group-settings-selected-member)]
|
||||||
|
(contact-by-identity identity)))))
|
||||||
|
|
||||||
|
(register-sub :group-settings-show-color-picker
|
||||||
|
(fn [db [_]]
|
||||||
|
(reaction (get @db :group-settings-show-color-picker))))
|
|
@ -0,0 +1,31 @@
|
||||||
|
(ns syng-im.group-settings.views.chat-name-edit
|
||||||
|
(:require-macros [syng-im.utils.views :refer [defview]])
|
||||||
|
(:require [reagent.core :as r]
|
||||||
|
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
|
[syng-im.components.react :refer [view text-input]]
|
||||||
|
[syng-im.components.toolbar :refer [toolbar]]
|
||||||
|
[syng-im.group-settings.styles.chat-name-edit :as st]
|
||||||
|
[syng-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]])
|
|
@ -0,0 +1,43 @@
|
||||||
|
(ns syng-im.group-settings.views.member
|
||||||
|
(:require [clojure.string :as s]
|
||||||
|
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||||
|
[syng-im.components.react :refer [view
|
||||||
|
image
|
||||||
|
text
|
||||||
|
icon
|
||||||
|
touchable-highlight]]
|
||||||
|
[syng-im.resources :as res]
|
||||||
|
[syng-im.group-settings.styles.member :as st]))
|
||||||
|
|
||||||
|
(defn contact-photo [{:keys [photo-path]}]
|
||||||
|
[view st/contact-photo-container
|
||||||
|
[image {:source (if (s/blank? photo-path)
|
||||||
|
res/user-no-photo
|
||||||
|
{:uri photo-path})
|
||||||
|
:style st/photo-image}]])
|
||||||
|
|
||||||
|
(defn contact-online [{:keys [online]}]
|
||||||
|
(when online
|
||||||
|
[view st/online-container
|
||||||
|
[view st/online-dot-left]
|
||||||
|
[view st/online-dot-right]]))
|
||||||
|
|
||||||
|
(defn member-view [{:keys [whisper-identity name photo-path online role]}]
|
||||||
|
[view st/contact-container
|
||||||
|
[view st/photo-container
|
||||||
|
[contact-photo {:photo-path photo-path}]
|
||||||
|
[contact-online {:online online}]]
|
||||||
|
[view st/info-container
|
||||||
|
[text {:style st/name-text}
|
||||||
|
(if (pos? (count name))
|
||||||
|
name
|
||||||
|
;; todo is this correct behaviour?
|
||||||
|
"Noname")]
|
||||||
|
;; TODO implement :role property for group chat contact
|
||||||
|
(when role
|
||||||
|
[text {:style st/role-text}
|
||||||
|
role])]
|
||||||
|
[touchable-highlight
|
||||||
|
{:on-press #(dispatch [:select-group-chat-member whisper-identity])}
|
||||||
|
[view st/more-btn
|
||||||
|
[icon :more-vertical st/more-btn-icon]]]])
|
|
@ -2,6 +2,7 @@
|
||||||
(:require
|
(:require
|
||||||
[re-frame.core :refer [register-handler after dispatch debug enrich]]
|
[re-frame.core :refer [register-handler after dispatch debug enrich]]
|
||||||
[schema.core :as s :include-macros true]
|
[schema.core :as s :include-macros true]
|
||||||
|
[syng-im.persistence.realm :as r]
|
||||||
[syng-im.db :refer [app-db schema]]
|
[syng-im.db :refer [app-db schema]]
|
||||||
[syng-im.persistence.simple-kv-store :as kv]
|
[syng-im.persistence.simple-kv-store :as kv]
|
||||||
[syng-im.protocol.state.storage :as storage]
|
[syng-im.protocol.state.storage :as storage]
|
||||||
|
@ -11,7 +12,9 @@
|
||||||
[syng-im.models.protocol :refer [update-identity
|
[syng-im.models.protocol :refer [update-identity
|
||||||
set-initialized]]
|
set-initialized]]
|
||||||
[syng-im.models.contacts :as contacts]
|
[syng-im.models.contacts :as contacts]
|
||||||
[syng-im.models.messages :refer [save-message update-message!]]
|
[syng-im.models.messages :refer [save-message
|
||||||
|
update-message!
|
||||||
|
clear-history]]
|
||||||
[syng-im.models.commands :refer [set-commands]]
|
[syng-im.models.commands :refer [set-commands]]
|
||||||
[syng-im.handlers.server :as server]
|
[syng-im.handlers.server :as server]
|
||||||
[syng-im.chat.suggestions :refer [load-commands]]
|
[syng-im.chat.suggestions :refer [load-commands]]
|
||||||
|
@ -32,6 +35,7 @@
|
||||||
[syng-im.utils.crypt :refer [gen-random-bytes]]
|
[syng-im.utils.crypt :refer [gen-random-bytes]]
|
||||||
[syng-im.utils.random :as random]
|
[syng-im.utils.random :as random]
|
||||||
syng-im.chat.handlers
|
syng-im.chat.handlers
|
||||||
|
[syng-im.group-settings.handlers :refer [delete-chat]]
|
||||||
[syng-im.navigation.handlers :as nav]
|
[syng-im.navigation.handlers :as nav]
|
||||||
syng-im.discovery.handlers
|
syng-im.discovery.handlers
|
||||||
syng-im.contacts.handlers))
|
syng-im.contacts.handlers))
|
||||||
|
@ -211,12 +215,14 @@
|
||||||
:delivery-status :failed})))
|
:delivery-status :failed})))
|
||||||
|
|
||||||
(register-handler :leave-group-chat
|
(register-handler :leave-group-chat
|
||||||
(fn [db [action navigator]]
|
(fn [db [action]]
|
||||||
(log/debug action)
|
(log/debug action)
|
||||||
(let [chat-id (:current-chat-id db)]
|
(let [chat-id (:current-chat-id db)]
|
||||||
(api/leave-group-chat chat-id)
|
(api/leave-group-chat chat-id)
|
||||||
(set-chat-active chat-id false)
|
(set-chat-active chat-id false)
|
||||||
(left-chat-msg chat-id))))
|
(left-chat-msg chat-id)
|
||||||
|
(delete-chat chat-id)
|
||||||
|
(dispatch [:navigate-back]))))
|
||||||
|
|
||||||
;; -- User data --------------------------------------------------------------
|
;; -- User data --------------------------------------------------------------
|
||||||
(register-handler :load-user-phone-number
|
(register-handler :load-user-phone-number
|
||||||
|
@ -253,11 +259,36 @@
|
||||||
(let [identities (vec (:new-participants db))
|
(let [identities (vec (:new-participants db))
|
||||||
chat-id (:current-chat-id db)]
|
chat-id (:current-chat-id db)]
|
||||||
(chat-add-participants chat-id identities)
|
(chat-add-participants chat-id identities)
|
||||||
(nav-pop navigator)
|
(dispatch [:navigate-back])
|
||||||
(doseq [ident identities]
|
(doseq [ident identities]
|
||||||
(api/group-add-participant chat-id ident))
|
(api/group-add-participant chat-id ident))
|
||||||
db)))
|
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)))
|
||||||
|
|
||||||
(defn update-new-group-selection [db identity add?]
|
(defn update-new-group-selection [db identity add?]
|
||||||
(update-in db :new-group (fn [new-group]
|
(update-in db :new-group (fn [new-group]
|
||||||
(if add?
|
(if add?
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns syng-im.models.chats
|
(ns syng-im.models.chats
|
||||||
(:require [clojure.set :refer [difference]]
|
(:require [clojure.set :refer [difference]]
|
||||||
|
[re-frame.core :refer [dispatch]]
|
||||||
[syng-im.persistence.realm :as r]
|
[syng-im.persistence.realm :as r]
|
||||||
[syng-im.utils.random :as random :refer [timestamp]]
|
[syng-im.utils.random :as random :refer [timestamp]]
|
||||||
[clojure.string :refer [join blank?]]
|
[clojure.string :refer [join blank?]]
|
||||||
|
@ -113,8 +114,11 @@
|
||||||
(if-let [contact-exists (.find contacts (fn [object index collection]
|
(if-let [contact-exists (.find contacts (fn [object index collection]
|
||||||
(= contact-identity (aget object "identity"))))]
|
(= contact-identity (aget object "identity"))))]
|
||||||
(aset contact-exists "is-in-chat" true)
|
(aset contact-exists "is-in-chat" true)
|
||||||
(.push contacts (clj->js {:identity contact-identity}))))))))
|
(.push contacts (clj->js {:identity contact-identity})))))))
|
||||||
|
;; TODO temp. Update chat in db atom
|
||||||
|
(dispatch [:initialize-chats]))
|
||||||
|
|
||||||
|
;; TODO deprecated? (is there need to remove multiple member at once?)
|
||||||
(defn chat-remove-participants [chat-id identities]
|
(defn chat-remove-participants [chat-id identities]
|
||||||
(r/write
|
(r/write
|
||||||
(fn []
|
(fn []
|
||||||
|
@ -131,7 +135,6 @@
|
||||||
(js->clj (.map results (fn [object _ _]
|
(js->clj (.map results (fn [object _ _]
|
||||||
(aget object "chat-id"))))))
|
(aget object "chat-id"))))))
|
||||||
|
|
||||||
|
|
||||||
(defn set-chat-active [chat-id active?]
|
(defn set-chat-active [chat-id active?]
|
||||||
(r/write (fn []
|
(r/write (fn []
|
||||||
(-> (r/get-by-field :chats :chat-id chat-id)
|
(-> (r/get-by-field :chats :chat-id chat-id)
|
||||||
|
|
|
@ -24,16 +24,20 @@
|
||||||
(r/sorted (r/get-all :contacts) :name :asc))
|
(r/sorted (r/get-all :contacts) :name :asc))
|
||||||
|
|
||||||
(defn contacts-list-exclude [exclude-idents]
|
(defn contacts-list-exclude [exclude-idents]
|
||||||
|
(if (empty? exclude-idents)
|
||||||
|
(contacts-list)
|
||||||
(let [query (exclude-query :whisper-identity exclude-idents)]
|
(let [query (exclude-query :whisper-identity exclude-idents)]
|
||||||
(-> (r/get-all :contacts)
|
(-> (r/get-all :contacts)
|
||||||
(r/filtered query)
|
(r/filtered query)
|
||||||
(r/sorted :name :asc))))
|
(r/sorted :name :asc)))))
|
||||||
|
|
||||||
(defn contacts-list-include [include-indents]
|
(defn contacts-list-include [include-indents]
|
||||||
|
(if (empty? include-indents)
|
||||||
|
()
|
||||||
(let [query (include-query :whisper-identity include-indents)]
|
(let [query (include-query :whisper-identity include-indents)]
|
||||||
(-> (r/get-all :contacts)
|
(-> (r/get-all :contacts)
|
||||||
(r/filtered query)
|
(r/filtered query)
|
||||||
(r/sorted :name :asc))))
|
(r/sorted :name :asc)))))
|
||||||
|
|
||||||
(defn contact-by-identity [identity]
|
(defn contact-by-identity [identity]
|
||||||
(r/single-cljs (r/get-by-field :contacts :whisper-identity identity)))
|
(r/single-cljs (r/get-by-field :contacts :whisper-identity identity)))
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns syng-im.models.messages
|
(ns syng-im.models.messages
|
||||||
(:require [syng-im.persistence.realm :as r]
|
(:require [syng-im.persistence.realm :as r]
|
||||||
|
[re-frame.core :refer [dispatch]]
|
||||||
[cljs.reader :refer [read-string]]
|
[cljs.reader :refer [read-string]]
|
||||||
[syng-im.utils.random :refer [timestamp]]
|
[syng-im.utils.random :refer [timestamp]]
|
||||||
[syng-im.db :as db]
|
[syng-im.db :as db]
|
||||||
|
@ -56,3 +57,10 @@
|
||||||
(fn []
|
(fn []
|
||||||
(when (r/exists? :msgs :msg-id msg-id)
|
(when (r/exists? :msgs :msg-id msg-id)
|
||||||
(r/create :msgs msg true)))))
|
(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]))
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
(push-view db :contact-list)))
|
(push-view db :contact-list)))
|
||||||
|
|
||||||
(defn clear-new-participants [db]
|
(defn clear-new-participants [db]
|
||||||
(assoc-in db :new-participants #{}))
|
(assoc db :new-participants #{}))
|
||||||
|
|
||||||
(register-handler :show-remove-participants
|
(register-handler :show-remove-participants
|
||||||
(fn [db _]
|
(fn [db _]
|
||||||
|
|
|
@ -43,6 +43,8 @@
|
||||||
:primaryKey :chat-id
|
:primaryKey :chat-id
|
||||||
:properties {:chat-id "string"
|
:properties {:chat-id "string"
|
||||||
:name "string"
|
:name "string"
|
||||||
|
:color {:type "string"
|
||||||
|
:default "#a187d5"}
|
||||||
:group-chat {:type "bool"
|
:group-chat {:type "bool"
|
||||||
:indexed true}
|
:indexed true}
|
||||||
:is-active "bool"
|
:is-active "bool"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require-macros [reagent.ratom :refer [reaction]])
|
(:require-macros [reagent.ratom :refer [reaction]])
|
||||||
(:require [re-frame.core :refer [register-sub]]
|
(:require [re-frame.core :refer [register-sub]]
|
||||||
syng-im.chat.subs
|
syng-im.chat.subs
|
||||||
|
syng-im.group-settings.subs
|
||||||
syng-im.discovery.subs
|
syng-im.discovery.subs
|
||||||
syng-im.contacts.subs))
|
syng-im.contacts.subs))
|
||||||
|
|
||||||
|
|