remove participants

This commit is contained in:
michaelr 2016-04-11 19:20:58 +03:00
parent 16f00678fa
commit b8ace7d0ce
12 changed files with 162 additions and 32 deletions

View File

@ -14,6 +14,7 @@
[syng-im.components.chats.chats-list :refer [chats-list]]
[syng-im.components.chats.new-group :refer [new-group]]
[syng-im.components.chat.new-participants :refer [new-participants]]
[syng-im.components.chat.remove-participants :refer [remove-participants]]
[syng-im.utils.logging :as log]
[syng-im.navigation :as nav]
[syng-im.utils.encryption]))
@ -44,6 +45,7 @@
(init-back-button-handler! nav)
(case view-id
:add-participants (r/as-element [new-participants {:navigator nav}])
:remove-participants (r/as-element [remove-participants {:navigator nav}])
:chat-list (r/as-element [chats-list {:navigator nav}])
:new-group (r/as-element [new-group {:navigator nav}])
:contact-list (r/as-element [contact-list {:navigator nav}])

View File

@ -57,10 +57,14 @@
:elevation 2}
:actions [{:title "Add Contact to chat"
:icon res/add-icon
:showWithText true}
{:title "Remove Contact from chat"
:icon res/trash-icon
:showWithText true}]
:onActionSelected (fn [position]
(case position
0 (dispatch [:show-add-participants navigator])))
0 (dispatch [:show-add-participants navigator])
1 (dispatch [:show-remove-participants navigator])))
:onIconClicked (fn []
(nav-pop navigator))}])
[list-view {:dataSource datasource

View File

@ -0,0 +1,36 @@
(ns syng-im.components.chat.remove-participants
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[syng-im.resources :as res]
[syng-im.components.react :refer [view toolbar-android android? text-input]]
[syng-im.components.realm :refer [list-view]]
[syng-im.utils.listview :refer [to-realm-datasource]]
[syng-im.components.chats.new-participant-contact :refer [new-participant-contact]]
[reagent.core :as r]
[syng-im.navigation :refer [nav-pop]]))
(defn remove-participants [{:keys [navigator]}]
(let [contacts (subscribe [:current-chat-contacts])]
(fn []
(let [contacts-ds (to-realm-datasource @contacts)]
[view {:style {:flex 1
:backgroundColor "white"}}
(when android?
;; TODO add IOS version
[toolbar-android {:logo res/logo-icon
:title "Remove Participants"
:titleColor "#4A5258"
:style {:backgroundColor "white"
:height 56
:elevation 2}
:actions [{:title "Remove"
:icon res/trash-icon
:show "always"}]
:onActionSelected (fn [position]
(dispatch [:remove-selected-participants navigator]))
:navIcon res/nav-back-icon
:onIconClicked (fn []
(nav-pop navigator))}])
[list-view {:dataSource contacts-ds
:renderRow (fn [row section-id row-id]
(r/as-element [new-participant-contact (js->clj row :keywordize-keys true) navigator]))
:style {:backgroundColor "white"}}]]))))

View File

@ -9,7 +9,7 @@
(defn chat-list-item [chat-obj navigator]
[touchable-highlight {:on-press (fn []
(dispatch [:show-chat (aget chat-obj "chat-id") navigator]))}
(dispatch [:show-chat (aget chat-obj "chat-id") navigator :push]))}
[view {:style {:flexDirection "row"
:width 260
:marginVertical 5}}

View File

@ -19,7 +19,8 @@
[syng-im.handlers.sign-up :as sign-up-service]
[syng-im.models.chats :refer [create-chat
chat-add-participants]]
chat-add-participants
chat-remove-participants]]
[syng-im.models.chat :refer [signal-chat-updated
set-current-chat-id
current-chat-id
@ -33,8 +34,11 @@
[syng-im.utils.logging :as log]
[syng-im.protocol.api :as api]
[syng-im.constants :refer [text-content-type]]
[syng-im.navigation :refer [nav-push]]
[syng-im.utils.crypt :refer [gen-random-bytes]]))
[syng-im.navigation :refer [nav-push
nav-replace
nav-pop]]
[syng-im.utils.crypt :refer [gen-random-bytes]]
[syng-im.utils.random :as random]))
;; -- Middleware ------------------------------------------------------------
;;
@ -82,9 +86,11 @@
db))
(register-handler :navigate-to
(fn [db [action navigator route]]
(fn [db [action navigator route nav-type]]
(log/debug action route)
(nav-push navigator route)
(case nav-type
:push (nav-push navigator route)
:replace (nav-replace navigator route))
db))
;; -- Protocol --------------------------------------------------------------
@ -130,6 +136,13 @@
:content (str (or inviter-name from) " invited " (or invitee-name identity))
:content-type text-content-type})))
(defn removed-participant-msg [chat-id identity]
(let [contact-name (:name (contacts/contact-by-identity identity))]
(save-message chat-id {:from "system"
:msg-id (random/id)
:content (str "You've removed " (or contact-name identity))
:content-type text-content-type})))
(register-handler :group-chat-invite-acked
(fn [db [action from group-id ack-msg-id]]
(log/debug action from group-id ack-msg-id)
@ -250,10 +263,10 @@
;; -- Chats --------------------------------------------------------------
(register-handler :show-chat
(fn [db [action chat-id navigator]]
(fn [db [action chat-id navigator nav-type]]
(log/debug action "chat-id" chat-id)
(let [db (set-current-chat-id db chat-id)]
(dispatch [:navigate-to navigator {:view-id :chat}])
(dispatch [:navigate-to navigator {:view-id :chat} nav-type])
db)))
(register-handler :set-sign-up-chat
@ -287,6 +300,25 @@
(log/debug action identity add?)
(update-new-participants-selection db identity add?)))
(register-handler :show-remove-participants
(fn [db [action navigator]]
(log/debug action)
(nav-push navigator {:view-id :remove-participants})
(clear-new-participants db)))
(register-handler :remove-selected-participants
(fn [db [action navigator]]
(log/debug action)
(let [identities (-> (new-participants-selection db)
(vec))
chat-id (current-chat-id db)]
(chat-remove-participants chat-id identities)
(nav-pop navigator)
(doseq [ident identities]
(api/group-remove-participant chat-id ident)
(removed-participant-msg chat-id ident))
(signal-chat-updated db chat-id))))
(register-handler :show-add-participants
(fn [db [action navigator]]
(log/debug action)
@ -300,7 +332,7 @@
(vec))
chat-id (current-chat-id db)]
(chat-add-participants chat-id identities)
(dispatch [:show-chat chat-id navigator])
(nav-pop navigator)
(doseq [ident identities]
(api/group-add-participant chat-id ident))
db)))
@ -323,7 +355,7 @@
(vec))
group-id (api/start-group-chat identities group-name)
db (create-chat db group-id identities true group-name)]
(dispatch [:show-chat group-id navigator])
(dispatch [:show-chat group-id navigator :replace])
db)))
(register-handler :group-chat-invite-received

View File

@ -4,7 +4,8 @@
[clojure.string :refer [join blank?]]
[syng-im.db :as db]
[syng-im.utils.logging :as log]
[syng-im.constants :refer [group-chat-colors]]))
[syng-im.constants :refer [group-chat-colors]]
[syng-im.persistence.realm-queries :refer [include-query]]))
(defn signal-chats-updated [db]
(update-in db db/updated-chats-signal-path (fn [current]
@ -64,18 +65,33 @@
(defn chat-add-participants [chat-id identities]
(r/write
(fn []
(let [chat (-> (r/get-by-field :chats :chat-id chat-id)
(r/single))
contacts (aget chat "contacts")
contacts-count (aget contacts "length")
colors (drop contacts-count group-chat-colors)
new-contacts (mapv (fn [ident {:keys [background text]}]
{:identity ident
:background-color background
:text-color text}) identities colors)]
(let [contacts (-> (r/get-by-field :chats :chat-id chat-id)
(r/single)
(aget "contacts"))
colors-in-use (->> (.map contacts (fn [object index collection]
{:text-color (aget object "text-color")
:background-color (aget object "background-color")}))
(set))
colors (->> group-chat-colors
(filter (fn [color]
(not (contains? colors-in-use color)))))
new-contacts (mapv (fn [ident {:keys [background text]}]
{:identity ident
:background-color background
:text-color text}) identities colors)]
(doseq [contact new-contacts]
(.push contacts (clj->js contact)))))))
(defn chat-remove-participants [chat-id identities]
(r/write
(fn []
(let [query (include-query :identity identities)
chat (-> (r/get-by-field :chats :chat-id chat-id)
(r/single))]
(-> (aget chat "contacts")
(r/filtered query)
(r/delete))))))
(defn active-group-chats []
(let [results (-> (r/get-all :chats)
(r/filtered "group-chat = true"))]

View File

@ -4,6 +4,8 @@
[syng-im.utils.utils :refer [log toast]]
[syng-im.persistence.realm :as realm]
[syng-im.persistence.realm :as r]
[syng-im.persistence.realm-queries :refer [include-query
exclude-query]]
[clojure.string :as s]))
;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45
@ -93,12 +95,15 @@
(r/sorted :name :asc)))
(defn contacts-list-exclude [exclude-idents]
(let [exclude-query (->> exclude-idents
(map (fn [ident]
(str "whisper-identity != '" ident "'")))
(s/join " && "))]
(let [query (exclude-query :whisper-identity exclude-idents)]
(-> (r/get-all :contacts)
(r/filtered exclude-query)
(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))))
(defn contact-by-identity [identity]

View File

@ -115,8 +115,7 @@
(read-string value))
(defn delete [obj]
(write (fn []
(.delete realm obj))))
(.delete realm obj))
(defn exists? [schema-name field value]
(> (.-length (get-by-field schema-name field value))

View File

@ -0,0 +1,19 @@
(ns syng-im.persistence.realm-queries
(:require [clojure.string :as s]
[syng-im.utils.types :refer [to-string]]))
(defn include-query [field-name values]
(->> values
(map (fn [val]
(str (to-string field-name) " == " (if (string? val)
(str "'" val "'")
val))))
(s/join " || ")))
(defn exclude-query [field-name values]
(->> values
(map (fn [val]
(str (to-string field-name) " != " (if (string? val)
(str "'" val "'")
val))))
(s/join " && ")))

View File

@ -17,8 +17,9 @@
(contains-key? [_ key]
(r/exists? :kv-store :key key))
(delete [_ key]
(-> (r/get-by-field :kv-store :key key)
(r/single)
(r/delete))))
(r/write (fn []
(-> (r/get-by-field :kv-store :key key)
(r/single)
(r/delete))))))
(def kv-store (->SimpleKvStore))

View File

@ -14,3 +14,4 @@
(def att (js/require "./images/att.png"))
(def v (js/require "./images/v.png"))
(def add-icon (js/require "./images/add.png"))
(def trash-icon (js/require "./images/trash.png"))

View File

@ -9,7 +9,8 @@
chat-by-id]]
[syng-im.models.messages :refer [get-messages]]
[syng-im.models.contacts :refer [contacts-list
contacts-list-exclude]]
contacts-list-exclude
contacts-list-include]]
[syng-im.handlers.suggestions :refer [get-suggestions]]))
;; -- Chat --------------------------------------------------------------
@ -114,3 +115,17 @@
:contacts
(map :identity))]
(contacts-list-exclude current-participants)))))))
(register-sub :current-chat-contacts
(fn [db _]
(let [current-chat-id (-> (current-chat-id @db)
(reaction))
chat (-> (when-let [chat-id @current-chat-id]
(chat-by-id chat-id))
(reaction))]
(reaction
(when @chat
(let [current-participants (->> @chat
:contacts
(map :identity))]
(contacts-list-include current-participants)))))))