Former-commit-id: 936c443a63
This commit is contained in:
michaelr 2016-03-29 23:45:31 +03:00
parent acfed7bc19
commit 12533d9330
14 changed files with 230 additions and 59 deletions

View File

@ -40,7 +40,7 @@ public class MainActivity extends ReactActivity {
// Launch!
new Thread(new Runnable() {
public void run() {
Geth.run("--bootnodes enode://e2f28126720452aa82f7d3083e49e6b3945502cb94d9750a15e27ee310eed6991618199f878e5fbc7dfa0e20f0af9554b41f491dc8f1dbae8f0f2d37a3a613aa@139.162.13.89:30303 --shh --ipcdisable --nodiscover --rpc --rpcapi db,eth,net,web3,shh --fast --datadir=" + dataFolder);
Geth.run("--bootnodes enode://e2f28126720452aa82f7d3083e49e6b3945502cb94d9750a15e27ee310eed6991618199f878e5fbc7dfa0e20f0af9554b41f491dc8f1dbae8f0f2d37a3a613aa@139.162.13.89:30303 --shh --ipcdisable --nodiscover --rpc --rpcapi db,eth,net,web3,shh,admin --fast --datadir=" + dataFolder);
}
}).start();
}

BIN
syng-im/images/chat.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

View File

@ -11,6 +11,7 @@
[syng-im.components.chat :refer [chat]]
[syng-im.components.sign-up :refer [sign-up-view]]
[syng-im.components.sign-up-confirm :refer [sign-up-confirm-view]]
[syng-im.components.chats.chats-list :refer [chats-list]]
[syng-im.utils.logging :as log]
[syng-im.navigation :as nav]))
@ -31,7 +32,7 @@
(add-event-listener "hardwareBackPress" new-listener)))))
(defn app-root []
[navigator {:initial-route (clj->js {:view-id :sign-up})
[navigator {:initial-route (clj->js {:view-id :chat-list})
:render-scene (fn [route nav]
(log/debug "route" route)
(when true ;; nav/*nav-render*
@ -39,13 +40,11 @@
view-id (keyword view-id)]
(init-back-button-handler! nav)
(case view-id
:contact-list (r/as-element [contact-list
{:navigator nav}])
:chat-list (r/as-element [chats-list {:navigator nav}])
:contact-list (r/as-element [contact-list {:navigator nav}])
:chat (r/as-element [chat {:navigator nav}])
:sign-up (r/as-element [sign-up-view
{:navigator nav}])
:sign-up-confirm (r/as-element [sign-up-confirm-view
{:navigator nav}])))))}])
:sign-up (r/as-element [sign-up-view {:navigator nav}])
:sign-up-confirm (r/as-element [sign-up-confirm-view {:navigator nav}])))))}])
(defn init []
(dispatch-sync [:initialize-db])

View File

@ -44,5 +44,5 @@
(invertible-scroll-view nil))
:renderRow (fn [row section-id row-id]
(r/as-element [chat-message (js->clj row :keywordize-keys true)]))
:style {:backgroundColor "black"}}]
:style {:backgroundColor "white"}}]
[chat-message-new]]))))

View File

@ -0,0 +1,26 @@
(ns syng-im.components.chats.chat-list-item
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[syng-im.components.react :refer [view
text
image
touchable-highlight]]
[syng-im.utils.logging :as log]
[syng-im.resources :as res]))
(defn chat-list-item [chat-obj navigator]
[touchable-highlight {:on-press (fn []
(dispatch [:show-chat (aget chat-obj "chat-id") navigator]))}
[view {:style {:flexDirection "row"
:width 260
:marginVertical 5}}
[image {:source res/chat-icon
:style {:borderWidth 2
:borderColor "#FFFFFF"
:width 32
:height 30
:marginRight 5
:marginLeft 5}}]
[text {:style {:fontSize 14
:fontFamily "Avenir-Roman"
:color "#4A5258"}}
(subs (aget chat-obj "name") 0 30)]]])

View File

@ -0,0 +1,43 @@
(ns syng-im.components.chats.chats-list
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[syng-im.components.react :refer [android?
view
text
image
touchable-highlight
navigator
toolbar-android]]
[syng-im.components.realm :refer [list-view]]
[syng-im.utils.logging :as log]
[syng-im.navigation :refer [nav-pop]]
[syng-im.resources :as res]
[syng-im.utils.listview :refer [to-realm-datasource]]
[reagent.core :as r]
[syng-im.components.chats.chat-list-item :refer [chat-list-item]]))
(defn chats-list [{:keys [navigator]}]
(let [chats (subscribe [:get-chats])]
(fn []
(let [chats @chats
_ (log/debug "chats=" chats)
datasource (to-realm-datasource chats)]
[view {:style {:flex 1
:backgroundColor "white"}}
(when android?
;; TODO add IOS version
[toolbar-android {:logo res/logo-icon
:title "Your Chats"
:titleColor "#4A5258"
:subtitle "List of your recent chats"
:subtitleColor "#AAB2B2"
:navIcon res/nav-back-icon
:style {:backgroundColor "white"
:height 56
:elevation 2}
:onIconClicked (fn []
(nav-pop navigator))}])
[list-view {:dataSource datasource
:renderRow (fn [row section-id row-id]
(r/as-element [chat-list-item row navigator]))
:style {:backgroundColor "white"}}]]))))

View File

@ -9,11 +9,13 @@
:identity-password "replace-me-with-user-entered-password"
:contacts []
:chat {:current-chat-id "0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd"}
:chats {}})
:chats {}
:chats-updated-signal 0})
(def protocol-initialized-path [:protocol-initialized])
(def identity-password-path [:identity-password])
(def current-chat-id-path [:chat :current-chat-id])
(defn latest-msg-id-path [chat-id]
[:chats chat-id :arrived-message-id])
(def updated-chats-signal-path [:chats-updated-signal])
(defn updated-chat-signal-path [chat-id]
[:chats chat-id :chat-updated-signal])

View File

@ -12,12 +12,16 @@
[syng-im.models.messages :refer [save-message
update-message!
message-by-id]]
[syng-im.models.chat :refer [signal-chat-updated]]
[syng-im.handlers.server :as server]
[syng-im.handlers.contacts :as contacts-service]
[syng-im.models.chats :refer [create-chat]]
[syng-im.models.chat :refer [signal-chat-updated
set-current-chat-id]]
[syng-im.utils.logging :as log]
[syng-im.protocol.api :as api]
[syng-im.constants :refer [text-content-type]]))
[syng-im.constants :refer [text-content-type]]
[syng-im.navigation :refer [nav-push]]))
;; -- Middleware ------------------------------------------------------------
;;
@ -32,14 +36,13 @@
(def validate-schema-mw
(after (partial check-and-throw schema)))
;; -- Handlers --------------------------------------------------------------
;; -- Common --------------------------------------------------------------
(register-handler :initialize-db
(fn [_ _]
app-db))
;; -- Common --------------------------------------------------------------
(register-handler :set-loading
(fn [db [_ value]]
(assoc db :loading value)))
@ -61,7 +64,9 @@
(fn [db [_ {chat-id :from
msg-id :msg-id :as msg}]]
(save-message chat-id msg)
(signal-chat-updated db chat-id)))
(-> db
(create-chat chat-id [chat-id])
(signal-chat-updated chat-id))))
(register-handler :acked-msg
(fn [db [_ from msg-id]]
@ -77,8 +82,8 @@
(signal-chat-updated db chat-id))))
(register-handler :send-chat-msg
(fn [db [_ chat-id text]]
(log/debug "chat-id" chat-id "text" text)
(fn [db [action chat-id text]]
(log/debug action "chat-id" chat-id "text" text)
(let [{msg-id :msg-id
{from :from
to :to} :msg} (api/send-user-msg {:to chat-id
@ -130,8 +135,10 @@
(fn [db [_ value]]
(contacts/load-syng-contacts db)))
;; -- Something --------------------------------------------------------------
;; -- Chats --------------------------------------------------------------
(register-handler :set-greeting
(fn [db [_ value]]
(assoc db :greeting value)))
(register-handler :show-chat
(fn [db [action chat-id navigator]]
(log/debug action "chat-id" chat-id)
(nav-push navigator {:view-id :chat})
(set-current-chat-id db chat-id)))

View File

@ -8,13 +8,13 @@
(get-in db db/current-chat-id-path))
(defn signal-chat-updated [db chat-id]
(update-in db (db/latest-msg-id-path chat-id) (fn [current]
(update-in db (db/updated-chat-signal-path chat-id) (fn [current]
(if current
(inc current)
0))))
(defn latest-msg-id [db chat-id]
(->> (db/latest-msg-id-path chat-id)
(defn chat-updated? [db chat-id]
(->> (db/updated-chat-signal-path chat-id)
(get-in db)))
(comment

View File

@ -0,0 +1,65 @@
(ns syng-im.models.chats
(:require [syng-im.persistence.realm :as r]
[syng-im.utils.random :refer [timestamp]]
[clojure.string :refer [join blank?]]
[syng-im.db :as db]))
(defn signal-chats-updated [db]
(update-in db db/updated-chats-signal-path (fn [current]
(if current
(inc current)
0))))
(defn chats-updated? [db]
(get-in db db/updated-chats-signal-path))
(defn chat-name-from-contacts [identities]
(let [chat-name (->> identities
(map (fn [identity]
(-> (r/get-by-field :contacts :whisper-identity identity)
(r/single-cljs)
:name)))
(filter identity)
(join ","))]
(when-not (blank? chat-name)
chat-name)))
(defn get-chat-name [chat-id identities]
(or (chat-name-from-contacts identities)
chat-id))
(defn create-chat
([db chat-id identities]
(create-chat db chat-id identities nil))
([db chat-id identities chat-name]
(when-not (r/exists? :chats :chat-id chat-id)
(let [chat-name (or chat-name
(get-chat-name chat-id identities))]
(r/write
(fn []
(let [group-chat? (> (count identities) 1)
contacts (mapv (fn [ident]
{:identity ident}) identities)]
(r/create :chats {:chat-id chat-id
:name chat-name
:group-chat group-chat?
:timestamp (timestamp)
:contacts contacts}))))
(signal-chats-updated db)))))
(defn chats-list []
(-> (r/get-all :chats)
(r/sorted :timestamp :desc)))
(comment
(chats-list)
(r/delete (chats-list))
(swap! re-frame.db/app-db signal-chats-updated)
(create-chat "0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd"
["0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd"])
)

View File

@ -4,14 +4,14 @@
"Flag to suppress navigator re-renders from outside om when pushing/popping."
true)
(defn nav-pop [nav]
(binding [*nav-render* true]
(.pop nav)))
(defn nav-push [nav route]
(binding [*nav-render* false]
(binding [*nav-render* true]
(.push nav (clj->js route))))
(defn nav-replace [nav route]
(binding [*nav-render* false]
(binding [*nav-render* true]
(.replace nav (clj->js route))))
(defn nav-pop [nav]
(binding [*nav-render* false]
(.pop nav)))

View File

@ -6,11 +6,15 @@
(set! js/window.Realm (js/require "realm"))
(def opts {:schema [{:name "Contact"
:properties {:phone-number "string"
(def opts {:schema [{:name :contacts
:primaryKey :whisper-identity
:properties {:phone-number {:type "string"
:optional true}
:whisper-identity "string"
:name "string"
:photo-path "string"}}
:name {:type "string"
:optional true}
:photo-path {:type "string"
:optinal true}}}
{:name :kv-store
:primaryKey :key
:properties {:key "string"
@ -27,7 +31,18 @@
:indexed true}
:outgoing "bool"
:delivery-status {:type "string"
:optional true}}}]})
:optional true}}}
{:name :chat-contact
:properties {:identity "string"}}
{:name :chats
:primaryKey :chat-id
:properties {:chat-id "string"
:name "string"
:group-chat "bool"
:timestamp "int"
:contacts {:type "list"
:objectType "chat-contact"}}}]})
(def realm (js/Realm. (clj->js opts)))
@ -66,6 +81,9 @@
(-> (.objects realm (name schema-name))
(.filtered q))))
(defn get-all [schema-name]
(.objects realm (to-string schema-name)))
(defn sorted [results field-name order]
(.sorted results (to-string field-name) (if (= order :asc)
false
@ -105,5 +123,4 @@
:content "sdfd"
:delivery-status "seen"}) true))
)

View File

@ -7,6 +7,7 @@
(def seen-icon (js/require "./images/seen.png"))
(def delivered-icon (js/require "./images/delivered.png"))
(def delivery-failed-icon (js/require "./images/deliveryfailed.png"))
(def chat-icon (js/require "./images/chat.png"))
(def play (js/require "./images/play.png"))
(def mic (js/require "./images/mic.png"))
(def smile (js/require "./images/smile.png"))

View File

@ -2,29 +2,40 @@
(:require-macros [reagent.ratom :refer [reaction]])
(:require [re-frame.core :refer [register-sub]]
[syng-im.models.chat :refer [current-chat-id
latest-msg-id]]
chat-updated?]]
[syng-im.models.chats :refer [chats-list
chats-updated?]]
[syng-im.models.messages :refer [get-messages]]))
(register-sub :get-greeting (fn [db _]
(reaction
(get @db :greeting))))
;; -- Chat --------------------------------------------------------------
(register-sub :get-chat-messages
(fn [db _]
(let [chat-id (-> (current-chat-id @db)
(reaction))
latest-msg (-> (latest-msg-id @db @chat-id)
chat-updated (-> (chat-updated? @db @chat-id)
(reaction))]
;; latest-msg signals us that a new message has been added
(reaction
(let [_ @latest-msg]
(let [_ @chat-updated]
(get-messages @chat-id))))))
(register-sub :get-current-chat-id (fn [db _]
(register-sub :get-current-chat-id
(fn [db _]
(-> (current-chat-id @db)
(reaction))))
;; -- Chats list --------------------------------------------------------------
(register-sub :get-chats
(fn [db _]
(let [chats-updated (-> (chats-updated? @db)
(reaction))]
(reaction
(let [_ @chats-updated]
(chats-list))))))
;; -- User data --------------------------------------------------------------
(register-sub
:get-user-phone-number
(fn [db _]