start chat with contact
This commit is contained in:
parent
780b12049e
commit
af0ed4c3a9
|
@ -52,7 +52,7 @@
|
|||
(dispatch [:initialize-chats])
|
||||
(dispatch [:initialize-protocol])
|
||||
(dispatch [:load-user-phone-number])
|
||||
(dispatch [:load-syng-contacts])
|
||||
(dispatch [:load-contacts])
|
||||
;; load commands from remote server (todo: uncomment)
|
||||
;; (dispatch [:load-commands])
|
||||
(dispatch [:init-console-chat])
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(ns syng-im.chat.handlers
|
||||
(:require [re-frame.core :refer [register-handler enrich after debug]]
|
||||
(:require [re-frame.core :refer [register-handler enrich after debug dispatch]]
|
||||
[syng-im.models.commands :as commands]
|
||||
[clojure.string :as str]
|
||||
[syng-im.chat.suggestions :as suggestions]
|
||||
|
@ -10,7 +10,9 @@
|
|||
[syng-im.utils.random :as random]
|
||||
[syng-im.components.react :as r]
|
||||
[syng-im.handlers.sign-up :as sign-up-service]
|
||||
[syng-im.models.chats :as chats]))
|
||||
[syng-im.models.chats :as chats]
|
||||
[syng-im.navigation.handlers :as nav]
|
||||
[syng-im.models.chats :as c]))
|
||||
|
||||
(register-handler :set-show-actions
|
||||
(fn [db [_ show-actions]]
|
||||
|
@ -236,15 +238,16 @@
|
|||
|
||||
|
||||
(defn load-messages!
|
||||
[db _]
|
||||
db
|
||||
(->> (:current-chat-id db)
|
||||
messages/get-messages
|
||||
(assoc db :messages)))
|
||||
([db] (load-messages! db nil))
|
||||
([db _]
|
||||
(->> (:current-chat-id db)
|
||||
messages/get-messages
|
||||
(assoc db :messages))))
|
||||
|
||||
(defn init-chat
|
||||
[{:keys [messages current-chat-id] :as db} _]
|
||||
(assoc-in db [:chats current-chat-id :messages] messages))
|
||||
([db] (init-chat db nil))
|
||||
([{:keys [messages current-chat-id] :as db} _]
|
||||
(assoc-in db [:chats current-chat-id :messages] messages)))
|
||||
|
||||
(register-handler :init-chat
|
||||
(-> load-messages!
|
||||
|
@ -256,9 +259,11 @@
|
|||
(let [chats (->> loaded-chats
|
||||
(map (fn [{:keys [chat-id] :as chat}]
|
||||
[chat-id chat]))
|
||||
(into {}))]
|
||||
(into {}))
|
||||
ids (set (keys chats))]
|
||||
(-> db
|
||||
(assoc :chats chats)
|
||||
(assoc :chats-ids ids)
|
||||
(dissoc :loaded-chats))))
|
||||
|
||||
(defn load-chats!
|
||||
|
@ -268,7 +273,6 @@
|
|||
(register-handler :initialize-chats
|
||||
((enrich initialize-chats) load-chats!))
|
||||
|
||||
|
||||
(defn store-message!
|
||||
[{:keys [new-message]} [_ {chat-id :from}]]
|
||||
(messages/save-message chat-id new-message))
|
||||
|
@ -288,3 +292,51 @@
|
|||
(fn [db [_ {chat-id :group-id :as msg}]]
|
||||
(messages/save-message chat-id msg)
|
||||
db))
|
||||
|
||||
(defn load-chat!
|
||||
[{:keys [chats current-chat-id] :as db}]
|
||||
(when-not (chats current-chat-id)
|
||||
(c/create-chat {}))
|
||||
db)
|
||||
|
||||
(defmethod nav/preload-data! :chat
|
||||
[{:keys [current-chat-id] :as db} [_ _ id]]
|
||||
(-> db
|
||||
(assoc :current-chat-id (or id current-chat-id))
|
||||
load-messages!
|
||||
init-chat))
|
||||
|
||||
(defn prepare-chat
|
||||
[{:keys [contacts] :as db} [_ contcat-id]]
|
||||
(let [name (get-in contacts [contcat-id :name])
|
||||
chat {:chat-id contcat-id
|
||||
:name name
|
||||
:group-chat false
|
||||
:is-active true
|
||||
:timestamp (.getTime (js/Date.))
|
||||
;; todo how to choose color?
|
||||
;; todo do we need to have some color for not group chat?
|
||||
:contacts [{:identity contcat-id
|
||||
:text-color :#FFFFFF
|
||||
:background-color :#AB7967}]}]
|
||||
(assoc db :new-chat chat)))
|
||||
|
||||
(defn add-chat [{:keys [new-chat] :as db} [_ chat-id]]
|
||||
(-> db
|
||||
(update :chats assoc chat-id new-chat)
|
||||
(update :chats-ids conj chat-id)))
|
||||
|
||||
(defn save-chat!
|
||||
[{:keys [new-chat]} _]
|
||||
(chats/create-chat new-chat))
|
||||
|
||||
(defn open-chat!
|
||||
[_ [_ chat-id]]
|
||||
(dispatch [:navigate-to :chat chat-id]))
|
||||
|
||||
(register-handler :start-chat
|
||||
(-> prepare-chat
|
||||
((enrich add-chat))
|
||||
((after save-chat!))
|
||||
((after open-chat!))
|
||||
debug))
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
(ns syng-im.chat.screen
|
||||
(:require-macros [syng-im.utils.views :refer [defview]])
|
||||
(:require [clojure.string :as s]
|
||||
[re-frame.core :refer [subscribe dispatch]]
|
||||
[syng-im.components.react :refer [view
|
||||
|
@ -8,7 +9,7 @@
|
|||
touchable-highlight
|
||||
list-view
|
||||
list-item]]
|
||||
[syng-im.chat.styles.chat :as st]
|
||||
[syng-im.chat.styles.screen :as st]
|
||||
[syng-im.resources :as res]
|
||||
[syng-im.utils.listview :refer [to-datasource]]
|
||||
[syng-im.components.invertible-scroll-view :refer [invertible-scroll-view]]
|
||||
|
@ -91,7 +92,7 @@
|
|||
|
||||
(defn actions-list-view []
|
||||
(let [{:keys [group-chat active]}
|
||||
(subscribe [:chat-properties [:group-chat :name :contacts :active]])]
|
||||
(subscribe [:chat-properties [:group-chat :active]])]
|
||||
(when-let [actions (when (and @group-chat @active)
|
||||
[{:title "Add Contact to chat"
|
||||
:icon :menu_group
|
||||
|
@ -160,25 +161,23 @@
|
|||
[chat-photo {}]
|
||||
[contact-online {:online true}]]])])))
|
||||
|
||||
(defn messages-view [group-chat]
|
||||
(let [messages (subscribe [:chat :messages])
|
||||
contacts (subscribe [:chat :contacts])]
|
||||
(fn [group-chat]
|
||||
(let [contacts' (contacts-by-identity @contacts)]
|
||||
[list-view {:renderRow (message-row contacts' group-chat)
|
||||
:renderScrollComponent #(invertible-scroll-view (js->clj %))
|
||||
:onEndReached #(dispatch [:load-more-messages])
|
||||
:enableEmptySections true
|
||||
:dataSource (to-datasource @messages)}]))))
|
||||
(defview messages-view [group-chat]
|
||||
[messages [:chat :messages]
|
||||
contacts [:chat :contacts]]
|
||||
(let [contacts' (contacts-by-identity contacts)]
|
||||
[list-view {:renderRow (message-row contacts' group-chat)
|
||||
:renderScrollComponent #(invertible-scroll-view (js->clj %))
|
||||
:onEndReached #(dispatch [:load-more-messages])
|
||||
:enableEmptySections true
|
||||
:dataSource (to-datasource messages)}]))
|
||||
|
||||
(defn chat []
|
||||
(let [is-active (subscribe [:chat :is-active])
|
||||
group-chat (subscribe [:chat :group-chat])
|
||||
show-actions-atom (subscribe [:show-actions])]
|
||||
(fn []
|
||||
[view st/chat-view
|
||||
[toolbar]
|
||||
[messages-view @group-chat]
|
||||
(when @group-chat [typing-all])
|
||||
(when is-active [chat-message-new])
|
||||
(when @show-actions-atom [actions-view])])))
|
||||
(defview chat []
|
||||
[is-active [:chat :is-active]
|
||||
group-chat [:chat :group-chat]
|
||||
show-actions-atom [:show-actions]]
|
||||
[view st/chat-view
|
||||
[toolbar]
|
||||
[messages-view group-chat]
|
||||
(when group-chat [typing-all])
|
||||
(when is-active [chat-message-new])
|
||||
(when show-actions-atom [actions-view])])
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
(ns syng-im.chat.styles.chat
|
||||
(ns syng-im.chat.styles.screen
|
||||
(:require [syng-im.components.styles :refer [font
|
||||
title-font
|
||||
color-white
|
|
@ -76,3 +76,7 @@
|
|||
(fn [db _]
|
||||
(let [current-chat-id (:current-chat-id @db)]
|
||||
(reaction (get-in @db [:chats current-chat-id])))))
|
||||
|
||||
(register-sub :get-chat
|
||||
(fn [db [_ chat-id]]
|
||||
(reaction (get-in @db [:chats chat-id]))))
|
||||
|
|
|
@ -12,15 +12,18 @@
|
|||
(contacts/save-contacts [contact]))
|
||||
|
||||
(register-handler :add-contact
|
||||
(-> (fn [db [_ contact]]
|
||||
(update db :contacts conj contact))
|
||||
(-> (fn [db [_ {:keys [whisper-identity] :as contact}]]
|
||||
(update db :contacts assoc whisper-identity contact))
|
||||
((after save-contact))))
|
||||
|
||||
(defn load-contacts! [db _]
|
||||
(let [contacts (contacts/get-contacts)]
|
||||
(let [contacts (->> (contacts/get-contacts)
|
||||
(map (fn [{:keys [whisper-identity] :as contact}]
|
||||
[whisper-identity contact]))
|
||||
(into {}))]
|
||||
(assoc db :contacts contacts)))
|
||||
|
||||
(register-handler :load-syng-contacts load-contacts!)
|
||||
(register-handler :load-contacts load-contacts!)
|
||||
|
||||
;; TODO see https://github.com/rt2zz/react-native-contacts/issues/45
|
||||
(def react-native-contacts (js/require "react-native-contacts"))
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
(ns syng-im.contacts.screen
|
||||
(:require-macros
|
||||
[natal-shell.data-source :refer [data-source clone-with-rows]]
|
||||
[natal-shell.core :refer [with-error-view]])
|
||||
(:require-macros [syng-im.utils.views :refer [defview]])
|
||||
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||
[syng-im.components.react :refer [view text
|
||||
image
|
||||
|
@ -17,9 +15,6 @@
|
|||
(defn render-row [row _ _]
|
||||
(list-item [contact-view row]))
|
||||
|
||||
(defn get-data-source [contacts]
|
||||
(clone-with-rows (data-source {:rowHasChanged not=}) contacts))
|
||||
|
||||
(defn contact-list-toolbar []
|
||||
[toolbar {:title "Contacts"
|
||||
:background-color toolbar-background2
|
||||
|
@ -27,14 +22,14 @@
|
|||
:style st/search-icon}
|
||||
:handler (fn [])}}])
|
||||
|
||||
(defn contact-list []
|
||||
(let [contacts (subscribe [:get :contacts])]
|
||||
(fn []
|
||||
(let [contacts-ds (lw/to-datasource @contacts)]
|
||||
[view st/contacts-list-container
|
||||
[contact-list-toolbar]
|
||||
(when contacts-ds
|
||||
[list-view {:dataSource contacts-ds
|
||||
:enableEmptySections true
|
||||
:renderRow render-row
|
||||
:style st/contacts-list}])]))))
|
||||
(defview contact-list []
|
||||
[contacts [:get-contacts]]
|
||||
[view st/contacts-list-container
|
||||
[contact-list-toolbar]
|
||||
;; todo what if there is no contacts, should we show some information
|
||||
;; about this?
|
||||
(when contacts
|
||||
[list-view {:dataSource (lw/to-datasource contacts)
|
||||
:enableEmptySections true
|
||||
:renderRow render-row
|
||||
:style st/contacts-list}])])
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
(ns syng-im.contacts.subs
|
||||
(:require-macros [reagent.ratom :refer [reaction]])
|
||||
(:require [re-frame.core :refer [register-sub]]))
|
||||
|
||||
(register-sub :get-contacts
|
||||
(fn [db _]
|
||||
(let [contacts (reaction (:contacts @db))]
|
||||
(reaction (vals @contacts)))))
|
||||
|
|
|
@ -1,8 +1,16 @@
|
|||
(ns syng-im.contacts.views.contact
|
||||
(:require-macros [syng-im.utils.views :refer [defview]])
|
||||
(:require [syng-im.components.react :refer [view touchable-highlight]]
|
||||
[re-frame.core :refer [dispatch]]
|
||||
[re-frame.core :refer [dispatch subscribe]]
|
||||
[syng-im.contacts.views.contact-inner :refer [contact-inner-view]]))
|
||||
|
||||
(defn contact-view [contact]
|
||||
[touchable-highlight {:onPress #(dispatch [:navigate-to :chat])}
|
||||
(defn on-press [chat whisper-identity]
|
||||
(if chat
|
||||
#(dispatch [:navigate-to :chat whisper-identity])
|
||||
#(dispatch [:start-chat whisper-identity])))
|
||||
|
||||
(defview contact-view [{:keys [whisper-identity] :as contact}]
|
||||
[chat [:get-chat whisper-identity]]
|
||||
[touchable-highlight
|
||||
{:onPress (on-press chat whisper-identity)}
|
||||
[view {} [contact-inner-view contact]]])
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
(def app-db {:identity-password "replace-me-with-user-entered-password"
|
||||
:identity "me"
|
||||
:contacts []
|
||||
:contacts-ids #{}
|
||||
:current-chat-id "console"
|
||||
:chat {:command nil
|
||||
:last-message nil}
|
||||
|
@ -39,4 +40,3 @@
|
|||
[:chats chat-id :command-requests])
|
||||
(defn chat-command-request-path [chat-id msg-id]
|
||||
[:chats chat-id :command-requests msg-id])
|
||||
(def updated-current-tag-signal-path [:current-tag-updated-signal])
|
||||
|
|
|
@ -75,52 +75,56 @@
|
|||
(defn find-command [commands command-key]
|
||||
(first (filter #(= command-key (:command %)) commands)))
|
||||
|
||||
(defn get-chat-command-content [db]
|
||||
(get-in db (db/chat-command-content-path (:current-chat-id db))))
|
||||
(defn get-chat-command-content
|
||||
[{:keys [current-chat-id] :as db}]
|
||||
(get-in db (db/chat-command-content-path current-chat-id)))
|
||||
|
||||
(defn set-chat-command-content [db content]
|
||||
(assoc-in db
|
||||
[:chats (:current-chat-id db) :command-input :content]
|
||||
content))
|
||||
(defn set-chat-command-content
|
||||
[{:keys [current-chat-id] :as db} content]
|
||||
(assoc-in db [:chats current-chat-id :command-input :content] content))
|
||||
|
||||
(defn get-chat-command [db]
|
||||
(get-in db (db/chat-command-path (:current-chat-id db))))
|
||||
(defn get-chat-command
|
||||
[{:keys [current-chat-id] :as db}]
|
||||
(get-in db (db/chat-command-path current-chat-id)))
|
||||
|
||||
(defn set-response-chat-command [db msg-id command-key]
|
||||
(let [chat-id (:current-chat-id db)]
|
||||
(-> db
|
||||
(assoc-in [:chats chat-id :command-input :content] nil)
|
||||
(assoc-in [:chats chat-id :command-input :command]
|
||||
(get-command db command-key))
|
||||
(assoc-in [:chats chat-id :command-input :to-msg-id] msg-id))))
|
||||
(defn set-response-chat-command
|
||||
[{:keys [current-chat-id] :as db} msg-id command-key]
|
||||
(update-in db [:chats current-chat-id :command-input] merge
|
||||
{:content nil
|
||||
:command (get-command db command-key)
|
||||
:to-msg-id msg-id}))
|
||||
|
||||
(defn set-chat-command [db command-key]
|
||||
(set-response-chat-command db nil command-key))
|
||||
|
||||
(defn get-chat-command-to-msg-id [db]
|
||||
(get-in db (db/chat-command-to-msg-id-path (:current-chat-id db))))
|
||||
(defn get-chat-command-to-msg-id
|
||||
[{:keys [current-chat-id] :as db}]
|
||||
(get-in db (db/chat-command-to-msg-id-path current-chat-id)))
|
||||
|
||||
(defn stage-command [db command-info]
|
||||
(update-in db (db/chat-staged-commands-path (:current-chat-id db))
|
||||
(fn [staged-commands]
|
||||
(if staged-commands
|
||||
(conj staged-commands command-info)
|
||||
[command-info]))))
|
||||
(defn stage-command
|
||||
[{:keys [current-chat-id] :as db} command-info]
|
||||
(update-in db (db/chat-staged-commands-path current-chat-id)
|
||||
#(if %
|
||||
(conj % command-info)
|
||||
[command-info])))
|
||||
|
||||
(defn unstage-command [db staged-command]
|
||||
(update-in db (db/chat-staged-commands-path (:current-chat-id db))
|
||||
(fn [staged-commands]
|
||||
(filterv #(not= % staged-command) staged-commands))))
|
||||
|
||||
(defn clear-staged-commands [db]
|
||||
(assoc-in db (db/chat-staged-commands-path (:current-chat-id db)) []))
|
||||
(defn clear-staged-commands
|
||||
[{:keys [current-chat-id] :as db}]
|
||||
(assoc-in db (db/chat-staged-commands-path current-chat-id) []))
|
||||
|
||||
(defn get-chat-command-request [db]
|
||||
(get-in db (db/chat-command-request-path (:current-chat-id db)
|
||||
(defn get-chat-command-request
|
||||
[{:keys [current-chat-id] :as db}]
|
||||
(get-in db (db/chat-command-request-path current-chat-id
|
||||
(get-chat-command-to-msg-id db))))
|
||||
|
||||
(defn set-chat-command-request [db msg-id handler]
|
||||
(update-in db (db/chat-command-requests-path (:current-chat-id db))
|
||||
(defn set-chat-command-request
|
||||
[{:keys [current-chat-id] :as db} msg-id handler]
|
||||
(update-in db (db/chat-command-requests-path current-chat-id)
|
||||
#(assoc % msg-id handler)))
|
||||
|
||||
(defn parse-command-msg-content [commands content]
|
||||
|
|
|
@ -4,29 +4,27 @@
|
|||
[syng-im.components.react :refer [view list-view list-item]]
|
||||
[syng-im.components.toolbar :refer [toolbar]]
|
||||
[syng-im.utils.listview :refer [to-datasource]]
|
||||
[syng-im.participants.views.contact
|
||||
:refer [participant-contact]]
|
||||
[syng-im.participants.views.contact :refer [participant-contact]]
|
||||
[reagent.core :as r]
|
||||
[syng-im.participants.styles :as st]))
|
||||
|
||||
(defn new-participants-toolbar [navigator]
|
||||
(defn new-participants-toolbar []
|
||||
[toolbar
|
||||
{:navigator navigator
|
||||
:title "Add Participants"
|
||||
{:title "Add Participants"
|
||||
:action {:image {:source res/v ;; {:uri "icon_search"}
|
||||
:style st/new-participant-image}
|
||||
:handler #(dispatch [:add-new-participants navigator])}}])
|
||||
:handler #(dispatch [:add-new-participants])}}])
|
||||
|
||||
(defn new-participants-row
|
||||
[row _ _]
|
||||
(list-item [participant-contact row]))
|
||||
|
||||
(defn new-participants [{:keys [navigator]}]
|
||||
(defn new-participants []
|
||||
(let [contacts (subscribe [:all-new-contacts])]
|
||||
(fn []
|
||||
(let [contacts-ds (to-datasource @contacts)]
|
||||
[view st/participants-container
|
||||
[new-participants-toolbar navigator]
|
||||
[new-participants-toolbar]
|
||||
[list-view {:dataSource contacts-ds
|
||||
:renderRow new-participants-row
|
||||
:style st/participants-list}]]))))
|
||||
|
|
|
@ -23,11 +23,6 @@
|
|||
(fn [db _]
|
||||
(reaction (:signed-up @db))))
|
||||
|
||||
(register-sub
|
||||
:get-contacts
|
||||
(fn [db _]
|
||||
(reaction (:contacts @db))))
|
||||
|
||||
(register-sub :all-contacts
|
||||
(fn [db _]
|
||||
(let [contacts (reaction (:contacts @db))]
|
||||
|
@ -44,7 +39,7 @@
|
|||
(map :identity)
|
||||
set)]
|
||||
(fn #(current-participants (:whisper-identity %))
|
||||
@contacts))))))
|
||||
(vals @contacts)))))))
|
||||
|
||||
(register-sub :all-new-contacts
|
||||
(fn [db _]
|
||||
|
|
Loading…
Reference in New Issue