2016-03-23 16:48:26 +02:00
|
|
|
(ns syng-im.handlers
|
|
|
|
(:require
|
2016-05-06 14:06:58 +03:00
|
|
|
[re-frame.core :refer [register-handler after dispatch debug enrich]]
|
2016-04-29 16:24:03 +03:00
|
|
|
[schema.core :as s :include-macros true]
|
2016-05-17 16:57:45 +03:00
|
|
|
[syng-im.persistence.realm :as r]
|
2016-05-10 13:58:37 +03:00
|
|
|
[syng-im.db :refer [app-db schema]]
|
2016-05-10 12:31:48 +03:00
|
|
|
[syng-im.persistence.simple-kv-store :as kv]
|
|
|
|
[syng-im.protocol.state.storage :as storage]
|
2016-04-29 16:24:03 +03:00
|
|
|
[syng-im.db :as db :refer [app-db schema]]
|
|
|
|
[syng-im.protocol.api :refer [init-protocol]]
|
|
|
|
[syng-im.protocol.protocol-handler :refer [make-handler]]
|
|
|
|
[syng-im.models.protocol :refer [update-identity
|
|
|
|
set-initialized]]
|
|
|
|
[syng-im.models.contacts :as contacts]
|
|
|
|
[syng-im.models.messages :refer [save-message
|
|
|
|
update-message!
|
2016-05-16 15:19:13 +03:00
|
|
|
clear-history]]
|
2016-05-10 13:58:37 +03:00
|
|
|
[syng-im.models.commands :refer [set-commands]]
|
2016-04-29 16:24:03 +03:00
|
|
|
[syng-im.handlers.server :as server]
|
2016-05-16 12:31:08 +03:00
|
|
|
[syng-im.chat.suggestions :refer [load-commands]]
|
2016-04-29 16:24:03 +03:00
|
|
|
[syng-im.models.chats :refer [chat-exists?
|
|
|
|
create-chat
|
|
|
|
chat-add-participants
|
|
|
|
chat-remove-participants
|
|
|
|
set-chat-active
|
2016-05-06 14:06:58 +03:00
|
|
|
re-join-group-chat
|
2016-05-10 13:58:37 +03:00
|
|
|
chat-by-id2]]
|
2016-04-29 16:24:03 +03:00
|
|
|
[syng-im.utils.logging :as log]
|
|
|
|
[syng-im.protocol.api :as api]
|
|
|
|
[syng-im.constants :refer [text-content-type
|
|
|
|
content-type-command]]
|
|
|
|
[syng-im.navigation :refer [nav-push
|
|
|
|
nav-replace
|
|
|
|
nav-pop]]
|
|
|
|
[syng-im.utils.crypt :refer [gen-random-bytes]]
|
2016-05-06 14:06:58 +03:00
|
|
|
[syng-im.utils.random :as random]
|
2016-05-10 17:40:21 +03:00
|
|
|
syng-im.chat.handlers
|
2016-05-16 19:38:35 +03:00
|
|
|
[syng-im.group-settings.handlers :refer [delete-chat]]
|
2016-05-13 14:58:58 +03:00
|
|
|
[syng-im.navigation.handlers :as nav]
|
|
|
|
syng-im.discovery.handlers
|
2016-05-11 16:06:37 +03:00
|
|
|
syng-im.contacts.handlers))
|
2016-03-23 16:48:26 +02:00
|
|
|
|
|
|
|
;; -- Middleware ------------------------------------------------------------
|
|
|
|
;;
|
|
|
|
;; See https://github.com/Day8/re-frame/wiki/Using-Handler-Middleware
|
|
|
|
;;
|
|
|
|
(defn check-and-throw
|
|
|
|
"throw an exception if db doesn't match the schema."
|
|
|
|
[a-schema db]
|
2016-03-23 21:05:42 +02:00
|
|
|
(if-let [problems (s/check a-schema db)]
|
|
|
|
(throw (js/Error. (str "schema check failed: " problems)))))
|
2016-03-23 16:48:26 +02:00
|
|
|
|
|
|
|
(def validate-schema-mw
|
|
|
|
(after (partial check-and-throw schema)))
|
|
|
|
|
2016-03-29 23:45:31 +03:00
|
|
|
|
|
|
|
;; -- Common --------------------------------------------------------------
|
2016-03-23 16:48:26 +02:00
|
|
|
|
2016-05-11 14:47:40 +03:00
|
|
|
(register-handler :set
|
|
|
|
(debug
|
|
|
|
(fn [db [_ k v]]
|
|
|
|
(assoc db k v))))
|
|
|
|
|
2016-05-13 14:58:58 +03:00
|
|
|
(defn preload-data!
|
|
|
|
[{:keys [view-id] :as db} _]
|
|
|
|
(nav/preload-data! db [nil view-id]))
|
|
|
|
|
2016-03-23 21:05:42 +02:00
|
|
|
(register-handler :initialize-db
|
2016-05-10 12:31:48 +03:00
|
|
|
(fn [_ _]
|
|
|
|
(assoc app-db
|
2016-05-16 12:31:08 +03:00
|
|
|
:signed-up (storage/get kv/kv-store :signed-up))))
|
2016-03-23 16:48:26 +02:00
|
|
|
|
2016-03-28 15:14:57 +03:00
|
|
|
(register-handler :set-loading
|
|
|
|
(fn [db [_ value]]
|
|
|
|
(assoc db :loading value)))
|
|
|
|
|
2016-04-03 19:00:40 +03:00
|
|
|
(register-handler :initialize-crypt
|
|
|
|
(fn [db _]
|
|
|
|
(log/debug "initializing crypt")
|
|
|
|
(gen-random-bytes 1024 (fn [{:keys [error buffer]}]
|
|
|
|
(if error
|
|
|
|
(do
|
|
|
|
(log/error "Failed to generate random bytes to initialize sjcl crypto")
|
|
|
|
(dispatch [:notify-user {:type :error
|
|
|
|
:error error}]))
|
|
|
|
(do
|
|
|
|
(->> (.toString buffer "hex")
|
|
|
|
(.toBits (.. js/ecc -sjcl -codec -hex))
|
|
|
|
(.addEntropy (.. js/ecc -sjcl -random)))
|
|
|
|
(dispatch [:crypt-initialized])))))
|
|
|
|
db))
|
|
|
|
|
|
|
|
(register-handler :crypt-initialized
|
|
|
|
(fn [db _]
|
|
|
|
(log/debug "crypt initialized")
|
|
|
|
db))
|
|
|
|
|
2016-04-14 12:49:50 +03:00
|
|
|
(register-handler :load-commands
|
|
|
|
(fn [db [action]]
|
|
|
|
(log/debug action)
|
|
|
|
(load-commands)
|
|
|
|
db))
|
|
|
|
|
|
|
|
(register-handler :set-commands
|
2016-04-29 16:24:03 +03:00
|
|
|
(fn [db [action commands]]
|
|
|
|
(log/debug action commands)
|
|
|
|
(set-commands db commands)))
|
2016-04-14 12:49:50 +03:00
|
|
|
|
2016-03-23 21:05:42 +02:00
|
|
|
;; -- Protocol --------------------------------------------------------------
|
|
|
|
|
|
|
|
(register-handler :initialize-protocol
|
|
|
|
(fn [db [_]]
|
|
|
|
(init-protocol (make-handler db))
|
|
|
|
db))
|
|
|
|
|
|
|
|
(register-handler :protocol-initialized
|
|
|
|
(fn [db [_ identity]]
|
|
|
|
(-> db
|
|
|
|
(update-identity identity)
|
|
|
|
(set-initialized true))))
|
|
|
|
|
2016-05-06 14:06:58 +03:00
|
|
|
(defn system-message [msg-id content]
|
|
|
|
{:from "system"
|
|
|
|
:msg-id msg-id
|
|
|
|
:content content
|
|
|
|
:content-type text-content-type})
|
|
|
|
|
2016-04-07 14:01:41 +03:00
|
|
|
(defn joined-chat-msg [chat-id from msg-id]
|
2016-04-11 16:45:01 +03:00
|
|
|
(let [contact-name (:name (contacts/contact-by-identity from))]
|
2016-04-07 14:01:41 +03:00
|
|
|
(save-message chat-id {:from "system"
|
2016-04-20 13:12:12 +03:00
|
|
|
:msg-id (str msg-id "_" from)
|
2016-04-07 14:01:41 +03:00
|
|
|
:content (str (or contact-name from) " received chat invitation")
|
|
|
|
:content-type text-content-type})))
|
|
|
|
|
2016-04-11 16:45:01 +03:00
|
|
|
(defn participant-invited-to-group-msg [chat-id identity from msg-id]
|
|
|
|
(let [inviter-name (:name (contacts/contact-by-identity from))
|
2016-04-29 16:24:03 +03:00
|
|
|
invitee-name (if (= identity (api/my-identity))
|
|
|
|
"You"
|
|
|
|
(:name (contacts/contact-by-identity identity)))]
|
2016-04-11 16:45:01 +03:00
|
|
|
(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})))
|
|
|
|
|
2016-04-11 19:44:02 +03:00
|
|
|
(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))]
|
2016-05-06 14:06:58 +03:00
|
|
|
(->> (str (or remover-name from) " removed " (or removed-name identity))
|
|
|
|
(system-message msg-id)
|
|
|
|
(save-message chat-id))))
|
2016-04-11 19:44:02 +03:00
|
|
|
|
2016-04-11 22:57:20 +03:00
|
|
|
(defn you-removed-from-group-msg [chat-id from msg-id]
|
|
|
|
(let [remover-name (:name (contacts/contact-by-identity from))]
|
2016-05-06 14:06:58 +03:00
|
|
|
(->> (str (or remover-name from) " removed you from group chat")
|
|
|
|
(system-message msg-id)
|
|
|
|
(save-message chat-id))))
|
2016-04-11 22:57:20 +03:00
|
|
|
|
2016-04-11 23:12:47 +03:00
|
|
|
(defn participant-left-group-msg [chat-id from msg-id]
|
|
|
|
(let [left-name (:name (contacts/contact-by-identity from))]
|
2016-05-06 14:06:58 +03:00
|
|
|
(->> (str (or left-name from) " left")
|
|
|
|
(system-message msg-id)
|
|
|
|
(save-message chat-id))))
|
2016-04-11 23:12:47 +03:00
|
|
|
|
2016-04-11 19:20:58 +03:00
|
|
|
(defn removed-participant-msg [chat-id identity]
|
|
|
|
(let [contact-name (:name (contacts/contact-by-identity identity))]
|
2016-05-06 14:06:58 +03:00
|
|
|
(->> (str "You've removed " (or contact-name identity))
|
|
|
|
(system-message (random/id))
|
|
|
|
(save-message chat-id))))
|
2016-04-11 19:20:58 +03:00
|
|
|
|
2016-04-11 22:57:20 +03:00
|
|
|
(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}))
|
|
|
|
|
2016-04-07 14:01:41 +03:00
|
|
|
(register-handler :group-chat-invite-acked
|
|
|
|
(fn [db [action from group-id ack-msg-id]]
|
|
|
|
(log/debug action from group-id ack-msg-id)
|
2016-05-10 17:40:21 +03:00
|
|
|
(joined-chat-msg group-id from ack-msg-id)))
|
2016-04-07 14:01:41 +03:00
|
|
|
|
2016-04-11 19:44:02 +03:00
|
|
|
(register-handler :participant-removed-from-group
|
|
|
|
(fn [db [action from group-id identity msg-id]]
|
|
|
|
(log/debug action msg-id from group-id identity)
|
|
|
|
(chat-remove-participants group-id [identity])
|
2016-05-10 17:40:21 +03:00
|
|
|
(participant-removed-from-group-msg group-id identity from msg-id)))
|
2016-04-11 19:44:02 +03:00
|
|
|
|
2016-04-11 22:57:20 +03:00
|
|
|
(register-handler :you-removed-from-group
|
|
|
|
(fn [db [action from group-id msg-id]]
|
|
|
|
(log/debug action msg-id from group-id)
|
|
|
|
(you-removed-from-group-msg group-id from msg-id)
|
2016-05-10 17:40:21 +03:00
|
|
|
(set-chat-active group-id false)))
|
2016-04-11 22:57:20 +03:00
|
|
|
|
2016-04-11 23:12:47 +03:00
|
|
|
(register-handler :participant-left-group
|
|
|
|
(fn [db [action from group-id msg-id]]
|
|
|
|
(log/debug action msg-id from group-id)
|
2016-04-29 16:24:03 +03:00
|
|
|
(if (= (api/my-identity) from)
|
|
|
|
db
|
2016-05-10 17:40:21 +03:00
|
|
|
(participant-left-group-msg group-id from msg-id))))
|
2016-04-11 23:12:47 +03:00
|
|
|
|
2016-04-11 16:45:01 +03:00
|
|
|
(register-handler :participant-invited-to-group
|
|
|
|
(fn [db [action from group-id identity msg-id]]
|
|
|
|
(log/debug action msg-id from group-id identity)
|
2016-05-10 17:40:21 +03:00
|
|
|
(participant-invited-to-group-msg group-id identity from msg-id)))
|
2016-04-11 16:45:01 +03:00
|
|
|
|
2016-03-28 19:00:07 +03:00
|
|
|
(register-handler :acked-msg
|
2016-04-07 14:21:02 +03:00
|
|
|
(fn [db [action from msg-id]]
|
|
|
|
(log/debug action from msg-id)
|
2016-03-28 19:00:07 +03:00
|
|
|
(update-message! {:msg-id msg-id
|
2016-05-10 17:40:21 +03:00
|
|
|
:delivery-status :delivered})))
|
2016-03-28 19:00:07 +03:00
|
|
|
|
|
|
|
(register-handler :msg-delivery-failed
|
2016-04-07 14:21:02 +03:00
|
|
|
(fn [db [action msg-id]]
|
2016-04-11 16:45:01 +03:00
|
|
|
(log/debug action msg-id)
|
2016-03-28 19:00:07 +03:00
|
|
|
(update-message! {:msg-id msg-id
|
2016-05-10 17:40:21 +03:00
|
|
|
:delivery-status :failed})))
|
2016-03-23 21:05:42 +02:00
|
|
|
|
2016-04-11 22:57:20 +03:00
|
|
|
(register-handler :leave-group-chat
|
2016-05-12 12:13:09 +03:00
|
|
|
(fn [db [action]]
|
2016-04-11 22:57:20 +03:00
|
|
|
(log/debug action)
|
2016-05-10 17:40:21 +03:00
|
|
|
(let [chat-id (:current-chat-id db)]
|
2016-04-11 22:57:20 +03:00
|
|
|
(api/leave-group-chat chat-id)
|
|
|
|
(set-chat-active chat-id false)
|
|
|
|
(left-chat-msg chat-id)
|
2016-05-16 15:19:13 +03:00
|
|
|
(delete-chat chat-id)
|
2016-05-16 19:24:17 +03:00
|
|
|
(dispatch [:navigate-back]))))
|
2016-04-03 19:00:40 +03:00
|
|
|
|
2016-03-28 15:14:57 +03:00
|
|
|
;; -- User data --------------------------------------------------------------
|
|
|
|
(register-handler :load-user-phone-number
|
|
|
|
(fn [db [_]]
|
2016-05-13 14:58:58 +03:00
|
|
|
;; todo fetch phone number from db
|
|
|
|
(assoc db :user-phone-number "123")))
|
2016-05-11 13:05:33 +03:00
|
|
|
|
2016-05-06 17:12:24 +03:00
|
|
|
;; -- Chats --------------------------------------------------------------
|
2016-05-10 17:40:21 +03:00
|
|
|
(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)))))
|
2016-04-01 18:05:55 +03:00
|
|
|
|
2016-04-07 14:21:02 +03:00
|
|
|
(register-handler :select-new-participant
|
|
|
|
(fn [db [action identity add?]]
|
|
|
|
(log/debug action identity add?)
|
|
|
|
(update-new-participants-selection db identity add?)))
|
|
|
|
|
2016-04-11 19:20:58 +03:00
|
|
|
(register-handler :remove-selected-participants
|
2016-05-13 18:56:52 +03:00
|
|
|
(fn [db [action]]
|
2016-04-11 19:20:58 +03:00
|
|
|
(log/debug action)
|
2016-05-10 17:40:21 +03:00
|
|
|
(let [identities (vec (:new-participants db))
|
|
|
|
chat-id (:current-chat-id db)]
|
2016-04-11 19:20:58 +03:00
|
|
|
(chat-remove-participants chat-id identities)
|
2016-05-13 14:17:03 +03:00
|
|
|
(dispatch [:navigate-back])
|
2016-04-11 19:20:58 +03:00
|
|
|
(doseq [ident identities]
|
|
|
|
(api/group-remove-participant chat-id ident)
|
2016-05-10 17:40:21 +03:00
|
|
|
(removed-participant-msg chat-id ident)))))
|
2016-04-07 14:21:02 +03:00
|
|
|
|
|
|
|
(register-handler :add-new-participants
|
|
|
|
(fn [db [action navigator]]
|
|
|
|
(log/debug action)
|
2016-05-10 17:40:21 +03:00
|
|
|
(let [identities (vec (:new-participants db))
|
|
|
|
chat-id (:current-chat-id db)]
|
2016-04-07 14:21:02 +03:00
|
|
|
(chat-add-participants chat-id identities)
|
2016-05-13 14:17:03 +03:00
|
|
|
(dispatch [:navigate-back])
|
2016-04-07 14:21:02 +03:00
|
|
|
(doseq [ident identities]
|
|
|
|
(api/group-add-participant chat-id ident))
|
|
|
|
db)))
|
2016-05-17 16:57:45 +03:00
|
|
|
|
|
|
|
(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)))
|
2016-04-07 14:21:02 +03:00
|
|
|
|
2016-05-10 17:40:21 +03:00
|
|
|
(defn update-new-group-selection [db identity add?]
|
|
|
|
(update-in db :new-group (fn [new-group]
|
|
|
|
(if add?
|
|
|
|
(conj new-group identity)
|
|
|
|
(disj new-group identity)))))
|
2016-04-01 18:05:55 +03:00
|
|
|
|
|
|
|
(register-handler :select-for-new-group
|
2016-05-10 17:40:21 +03:00
|
|
|
(fn [db [_ identity add?]]
|
2016-04-01 18:05:55 +03:00
|
|
|
(update-new-group-selection db identity add?)))
|
|
|
|
|
|
|
|
(register-handler :create-new-group
|
2016-05-10 17:40:21 +03:00
|
|
|
(fn [db [action group-name]]
|
2016-04-01 18:05:55 +03:00
|
|
|
(log/debug action)
|
2016-05-10 17:40:21 +03:00
|
|
|
(let [identities (vec (:new-group db))
|
2016-04-04 17:03:40 +03:00
|
|
|
group-id (api/start-group-chat identities group-name)
|
|
|
|
db (create-chat db group-id identities true group-name)]
|
2016-05-10 15:25:36 +03:00
|
|
|
(dispatch [:show-chat group-id :replace])
|
2016-04-01 18:05:55 +03:00
|
|
|
db)))
|
|
|
|
|
2016-04-04 17:03:40 +03:00
|
|
|
(register-handler :group-chat-invite-received
|
|
|
|
(fn [db [action from group-id identities group-name]]
|
|
|
|
(log/debug action from group-id identities)
|
2016-04-29 02:06:15 +03:00
|
|
|
(if (chat-exists? group-id)
|
|
|
|
(re-join-group-chat db group-id identities group-name)
|
|
|
|
(create-chat db group-id identities true group-name))))
|