parent
7db7f9be5d
commit
d0b8b20ca9
|
@ -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}])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"}}]]))))
|
|
@ -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}}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"))]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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 " && ")))
|
|
@ -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))
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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)))))))
|
||||
|
|
Loading…
Reference in New Issue