diff --git a/android/app/src/main/res/drawable-hdpi/icon_bin.png b/android/app/src/main/res/drawable-hdpi/icon_bin.png new file mode 100644 index 0000000000..a968627384 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/icon_bin.png differ diff --git a/android/app/src/main/res/drawable-hdpi/icon_notifications_on.png b/android/app/src/main/res/drawable-hdpi/icon_notifications_on.png new file mode 100644 index 0000000000..207cb4c16f Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/icon_notifications_on.png differ diff --git a/android/app/src/main/res/drawable-mdpi/icon_bin.png b/android/app/src/main/res/drawable-mdpi/icon_bin.png new file mode 100644 index 0000000000..d26fff597d Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/icon_bin.png differ diff --git a/android/app/src/main/res/drawable-mdpi/icon_notifications_on.png b/android/app/src/main/res/drawable-mdpi/icon_notifications_on.png new file mode 100644 index 0000000000..89a9ca8f15 Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/icon_notifications_on.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/icon_bin.png b/android/app/src/main/res/drawable-xhdpi/icon_bin.png new file mode 100644 index 0000000000..beed3a3490 Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/icon_bin.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/icon_notifications_on.png b/android/app/src/main/res/drawable-xhdpi/icon_notifications_on.png new file mode 100644 index 0000000000..9322a10bec Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/icon_notifications_on.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/icon_bin.png b/android/app/src/main/res/drawable-xxhdpi/icon_bin.png new file mode 100644 index 0000000000..fa960dbf1d Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/icon_bin.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/icon_notifications_on.png b/android/app/src/main/res/drawable-xxhdpi/icon_notifications_on.png new file mode 100644 index 0000000000..a0ee3c3fd5 Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/icon_notifications_on.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/icon_bin.png b/android/app/src/main/res/drawable-xxxhdpi/icon_bin.png new file mode 100644 index 0000000000..ac64c38731 Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/icon_bin.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/icon_notifications_on.png b/android/app/src/main/res/drawable-xxxhdpi/icon_notifications_on.png new file mode 100644 index 0000000000..cc4a37280a Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/icon_notifications_on.png differ diff --git a/src/syng_im/android/core.cljs b/src/syng_im/android/core.cljs index 125b49b6df..a7c6315b1e 100644 --- a/src/syng_im/android/core.cljs +++ b/src/syng_im/android/core.cljs @@ -14,6 +14,8 @@ [syng-im.new-group.screen :refer [new-group]] [syng-im.participants.views.create :refer [new-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.utils.utils :refer [toast]] [syng-im.utils.encryption])) @@ -40,6 +42,8 @@ :remove-participants [remove-participants] :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] diff --git a/src/syng_im/chat/screen.cljs b/src/syng_im/chat/screen.cljs index a2f14c4f41..dd355b4223 100644 --- a/src/syng_im/chat/screen.cljs +++ b/src/syng_im/chat/screen.cljs @@ -132,11 +132,10 @@ :height 21} :handler #(dispatch [:leave-group-chat])} {:title "Settings" - :subtitle "Not implemented" :icon :settings :icon-style {:width 20 :height 13} - :handler (fn [])}] + :handler #(dispatch [:show-group-settings])}] [{:title "Profile" :custom-icon [menu-item-icon-profile] :icon :menu_group @@ -148,15 +147,13 @@ :icon :search_gray_copy :icon-style {:width 17 :height 17} - :handler nil #_#(dispatch - [:show-remove-participants navigator])} + :handler nil} {:title "Notifications and sounds" :subtitle "!not implemented" :icon :muted :icon-style {:width 18 :height 21} - :handler nil #_#(dispatch [:leave-group-chat - navigator])} + :handler nil} {:title "Settings" :subtitle "!not implemented" :icon :settings @@ -227,12 +224,11 @@ :dataSource (to-datasource messages)}])) (defview chat [] - [is-active [:chat :is-active] - group-chat [:chat :group-chat] + [group-chat [:chat :group-chat] show-actions-atom [:show-actions]] [view st/chat-view [chat-toolbar] [messages-view group-chat] (when group-chat [typing-all]) - (when is-active [chat-message-new]) + [chat-message-new] (when show-actions-atom [actions-view])]) diff --git a/src/syng_im/components/react.cljs b/src/syng_im/components/react.cljs index e19ffe11fe..58c99aa6e4 100644 --- a/src/syng_im/components/react.cljs +++ b/src/syng_im/components/react.cljs @@ -30,6 +30,9 @@ text]) (def drawer-layout-android (r/adapt-react-class (.-DrawerLayoutAndroid 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] diff --git a/src/syng_im/components/styles.cljs b/src/syng_im/components/styles.cljs index b05e37ad82..786555bcf1 100644 --- a/src/syng_im/components/styles.cljs +++ b/src/syng_im/components/styles.cljs @@ -2,7 +2,8 @@ (def font "sans-serif") ;; (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-transparent "#7099e632") diff --git a/src/syng_im/group_settings/handlers.cljs b/src/syng_im/group_settings/handlers.cljs new file mode 100644 index 0000000000..d38e52ab06 --- /dev/null +++ b/src/syng_im/group_settings/handlers.cljs @@ -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)))) diff --git a/src/syng_im/group_settings/screen.cljs b/src/syng_im/group_settings/screen.cljs new file mode 100644 index 0000000000..9d3011b5fb --- /dev/null +++ b/src/syng_im/group_settings/screen.cljs @@ -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])]) diff --git a/src/syng_im/group_settings/styles/chat_name_edit.cljs b/src/syng_im/group_settings/styles/chat_name_edit.cljs new file mode 100644 index 0000000000..0a5afb59d3 --- /dev/null +++ b/src/syng_im/group_settings/styles/chat_name_edit.cljs @@ -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}) diff --git a/src/syng_im/group_settings/styles/group_settings.cljs b/src/syng_im/group_settings/styles/group_settings.cljs new file mode 100644 index 0000000000..092ab7387e --- /dev/null +++ b/src/syng_im/group_settings/styles/group_settings.cljs @@ -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}) diff --git a/src/syng_im/group_settings/styles/member.cljs b/src/syng_im/group_settings/styles/member.cljs new file mode 100644 index 0000000000..a25ea0cd5a --- /dev/null +++ b/src/syng_im/group_settings/styles/member.cljs @@ -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}) diff --git a/src/syng_im/group_settings/subs.cljs b/src/syng_im/group_settings/subs.cljs new file mode 100644 index 0000000000..8ef774b5f6 --- /dev/null +++ b/src/syng_im/group_settings/subs.cljs @@ -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)))) diff --git a/src/syng_im/group_settings/views/chat_name_edit.cljs b/src/syng_im/group_settings/views/chat_name_edit.cljs new file mode 100644 index 0000000000..7ba34e6dd7 --- /dev/null +++ b/src/syng_im/group_settings/views/chat_name_edit.cljs @@ -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]]) diff --git a/src/syng_im/group_settings/views/member.cljs b/src/syng_im/group_settings/views/member.cljs new file mode 100644 index 0000000000..6584724755 --- /dev/null +++ b/src/syng_im/group_settings/views/member.cljs @@ -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]]]]) diff --git a/src/syng_im/handlers.cljs b/src/syng_im/handlers.cljs index 2b90f5991e..37f1e23311 100644 --- a/src/syng_im/handlers.cljs +++ b/src/syng_im/handlers.cljs @@ -2,6 +2,7 @@ (:require [re-frame.core :refer [register-handler after dispatch debug enrich]] [schema.core :as s :include-macros true] + [syng-im.persistence.realm :as r] [syng-im.db :refer [app-db schema]] [syng-im.persistence.simple-kv-store :as kv] [syng-im.protocol.state.storage :as storage] @@ -11,7 +12,9 @@ [syng-im.models.protocol :refer [update-identity set-initialized]] [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.handlers.server :as server] [syng-im.chat.suggestions :refer [load-commands]] @@ -32,6 +35,7 @@ [syng-im.utils.crypt :refer [gen-random-bytes]] [syng-im.utils.random :as random] syng-im.chat.handlers + [syng-im.group-settings.handlers :refer [delete-chat]] [syng-im.navigation.handlers :as nav] syng-im.discovery.handlers syng-im.contacts.handlers)) @@ -211,12 +215,14 @@ :delivery-status :failed}))) (register-handler :leave-group-chat - (fn [db [action navigator]] + (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)))) + (left-chat-msg chat-id) + (delete-chat chat-id) + (dispatch [:navigate-back])))) ;; -- User data -------------------------------------------------------------- (register-handler :load-user-phone-number @@ -253,11 +259,36 @@ (let [identities (vec (:new-participants db)) chat-id (:current-chat-id db)] (chat-add-participants chat-id identities) - (nav-pop navigator) + (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))) + (defn update-new-group-selection [db identity add?] (update-in db :new-group (fn [new-group] (if add? diff --git a/src/syng_im/models/chats.cljs b/src/syng_im/models/chats.cljs index 9bfca22293..de9ea76963 100644 --- a/src/syng_im/models/chats.cljs +++ b/src/syng_im/models/chats.cljs @@ -1,5 +1,6 @@ (ns syng-im.models.chats (:require [clojure.set :refer [difference]] + [re-frame.core :refer [dispatch]] [syng-im.persistence.realm :as r] [syng-im.utils.random :as random :refer [timestamp]] [clojure.string :refer [join blank?]] @@ -113,8 +114,11 @@ (if-let [contact-exists (.find contacts (fn [object index collection] (= contact-identity (aget object "identity"))))] (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] (r/write (fn [] @@ -131,7 +135,6 @@ (js->clj (.map results (fn [object _ _] (aget object "chat-id")))))) - (defn set-chat-active [chat-id active?] (r/write (fn [] (-> (r/get-by-field :chats :chat-id chat-id) diff --git a/src/syng_im/models/contacts.cljs b/src/syng_im/models/contacts.cljs index 6369cb9262..f47986ebca 100644 --- a/src/syng_im/models/contacts.cljs +++ b/src/syng_im/models/contacts.cljs @@ -24,16 +24,20 @@ (r/sorted (r/get-all :contacts) :name :asc)) (defn contacts-list-exclude [exclude-idents] - (let [query (exclude-query :whisper-identity exclude-idents)] - (-> (r/get-all :contacts) - (r/filtered query) - (r/sorted :name :asc)))) + (if (empty? exclude-idents) + (contacts-list) + (let [query (exclude-query :whisper-identity exclude-idents)] + (-> (r/get-all :contacts) + (r/filtered query) + (r/sorted :name :asc))))) (defn contacts-list-include [include-indents] - (let [query (include-query :whisper-identity include-indents)] - (-> (r/get-all :contacts) - (r/filtered query) - (r/sorted :name :asc)))) + (if (empty? include-indents) + () + (let [query (include-query :whisper-identity include-indents)] + (-> (r/get-all :contacts) + (r/filtered query) + (r/sorted :name :asc))))) (defn contact-by-identity [identity] (r/single-cljs (r/get-by-field :contacts :whisper-identity identity))) diff --git a/src/syng_im/models/messages.cljs b/src/syng_im/models/messages.cljs index e650e85127..7f476de7f4 100644 --- a/src/syng_im/models/messages.cljs +++ b/src/syng_im/models/messages.cljs @@ -1,5 +1,6 @@ (ns syng-im.models.messages (:require [syng-im.persistence.realm :as r] + [re-frame.core :refer [dispatch]] [cljs.reader :refer [read-string]] [syng-im.utils.random :refer [timestamp]] [syng-im.db :as db] @@ -56,3 +57,10 @@ (fn [] (when (r/exists? :msgs :msg-id msg-id) (r/create :msgs msg true))))) + +(defn clear-history [chat-id] + (r/write + (fn [] + (r/delete (r/get-by-field :msgs :chat-id chat-id)))) + ;; TODO temp. Update chat in db atom + (dispatch [:initialize-chats])) diff --git a/src/syng_im/navigation/handlers.cljs b/src/syng_im/navigation/handlers.cljs index 98671d3e77..36dd8a768d 100644 --- a/src/syng_im/navigation/handlers.cljs +++ b/src/syng_im/navigation/handlers.cljs @@ -58,7 +58,7 @@ (push-view db :contact-list))) (defn clear-new-participants [db] - (assoc-in db :new-participants #{})) + (assoc db :new-participants #{})) (register-handler :show-remove-participants (fn [db _] diff --git a/src/syng_im/persistence/realm.cljs b/src/syng_im/persistence/realm.cljs index 01879ebb3a..af5050cf78 100644 --- a/src/syng_im/persistence/realm.cljs +++ b/src/syng_im/persistence/realm.cljs @@ -43,6 +43,8 @@ :primaryKey :chat-id :properties {:chat-id "string" :name "string" + :color {:type "string" + :default "#a187d5"} :group-chat {:type "bool" :indexed true} :is-active "bool" diff --git a/src/syng_im/subs.cljs b/src/syng_im/subs.cljs index 5479e808ae..b2d895730c 100644 --- a/src/syng_im/subs.cljs +++ b/src/syng_im/subs.cljs @@ -2,6 +2,7 @@ (:require-macros [reagent.ratom :refer [reaction]]) (:require [re-frame.core :refer [register-sub]] syng-im.chat.subs + syng-im.group-settings.subs syng-im.discovery.subs syng-im.contacts.subs))