commit
045678ee12
|
@ -8,7 +8,9 @@
|
|||
[reagent "0.5.1" :exclusions [cljsjs/react]]
|
||||
[re-frame "0.6.0"]
|
||||
[prismatic/schema "1.0.4"]
|
||||
[syng-im/protocol "0.1.1"]
|
||||
^{:voom {:repo "https://github.com/status-im/status-lib.git"
|
||||
:branch "master"}}
|
||||
[syng-im/protocol "0.1.1-20160430_080316-gf359cb7"]
|
||||
[natal-shell "0.1.6"]]
|
||||
:plugins [[lein-cljsbuild "1.1.1"]
|
||||
[lein-figwheel "0.5.0-2"]]
|
||||
|
@ -44,4 +46,4 @@
|
|||
:main "env.android.main"
|
||||
:output-dir "target/android"
|
||||
:optimizations :simple}}}}
|
||||
}})
|
||||
}})
|
||||
|
|
|
@ -21,50 +21,39 @@
|
|||
(def back-button-handler (cljs/atom {:nav nil
|
||||
:handler nil}))
|
||||
|
||||
(defn init-back-button-handler! [nav]
|
||||
(let [handler @back-button-handler]
|
||||
(when-not (= nav (:nav handler))
|
||||
(remove-event-listener "hardwareBackPress" (:handler handler))
|
||||
(let [new-listener (fn []
|
||||
(binding [nav/*nav-render* false]
|
||||
(when (< 1 (.-length (.getCurrentRoutes nav)))
|
||||
(nav/nav-pop nav)
|
||||
true)))]
|
||||
(reset! back-button-handler {:nav nav
|
||||
:handler new-listener})
|
||||
(add-event-listener "hardwareBackPress" new-listener)))))
|
||||
(defn init-back-button-handler! []
|
||||
(let [new-listener (fn []
|
||||
;; todo: it might be better always return false from
|
||||
;; this listener and handle application's closing
|
||||
;; in handlers
|
||||
(let [stack (subscribe [:navigation-stack])]
|
||||
(when (< 1 (count stack))
|
||||
(dispatch [:navigate-back])
|
||||
true)))]
|
||||
(add-event-listener "hardwareBackPress" new-listener)))
|
||||
|
||||
(defn app-root []
|
||||
(let [signed-up-atom (subscribe [:signed-up])]
|
||||
(let [signed-up (subscribe [:signed-up])
|
||||
view-id (subscribe [:view-id])]
|
||||
(fn []
|
||||
(let [signed-up @signed-up-atom]
|
||||
[navigator {:initial-route (clj->js {:view-id
|
||||
:chat-list
|
||||
;:chat
|
||||
})
|
||||
:render-scene (fn [route nav]
|
||||
(log/debug "route" route)
|
||||
(when true ;; nav/*nav-render*
|
||||
(if signed-up
|
||||
(let [{:keys [view-id]} (js->clj route :keywordize-keys true)
|
||||
view-id (keyword view-id)]
|
||||
(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}])
|
||||
:chat (r/as-element [chat {:navigator nav}])))
|
||||
(r/as-element [chat {:navigator nav}]))))}]))))
|
||||
(case (if @signed-up @view-id :chat)
|
||||
:add-participants [new-participants]
|
||||
:remove-participants [remove-participants]
|
||||
:chat-list [chats-list]
|
||||
:new-group [new-group]
|
||||
:contact-list [contact-list]
|
||||
:chat [chat]))))
|
||||
|
||||
(defn init []
|
||||
(dispatch-sync [:initialize-db])
|
||||
(dispatch [:initialize-crypt])
|
||||
(dispatch [:initialize-chats])
|
||||
(dispatch [:initialize-protocol])
|
||||
(dispatch [:load-user-phone-number])
|
||||
(dispatch [:load-syng-contacts])
|
||||
;; load commands from remote server (todo: uncomment)
|
||||
;; (dispatch [:load-commands])
|
||||
(dispatch-sync [:init-console-chat])
|
||||
(dispatch [:init-console-chat])
|
||||
(dispatch [:init-chat])
|
||||
(init-back-button-handler!)
|
||||
(.registerComponent app-registry "SyngIm" #(r/reactify-component app-root)))
|
||||
|
|
|
@ -5,8 +5,11 @@
|
|||
text
|
||||
image
|
||||
navigator
|
||||
touchable-highlight]]
|
||||
[syng-im.components.realm :refer [list-view]]
|
||||
touchable-highlight
|
||||
toolbar-android
|
||||
list-view
|
||||
list-item
|
||||
android?]]
|
||||
[syng-im.components.styles :refer [font
|
||||
title-font
|
||||
color-white
|
||||
|
@ -18,11 +21,11 @@
|
|||
text2-color
|
||||
toolbar-background1]]
|
||||
[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]]
|
||||
[syng-im.constants :refer [content-type-status]]
|
||||
[syng-im.utils.listview :refer [to-datasource
|
||||
to-datasource2]]
|
||||
[syng-im.components.invertible-scroll-view :refer [invertible-scroll-view]]
|
||||
[reagent.core :as r]
|
||||
[syng-im.components.chat.chat-message :refer [chat-message]]
|
||||
[syng-im.components.chat.chat-message-new :refer [chat-message-new]]))
|
||||
|
||||
|
@ -78,12 +81,12 @@
|
|||
:backgroundColor color-white}]]))
|
||||
|
||||
(defn typing [member]
|
||||
[view {:style {:width 260
|
||||
:marginTop 10
|
||||
:paddingLeft 8
|
||||
:paddingRight 8
|
||||
:alignItems "flex-start"
|
||||
:alignSelf "flex-start"}}
|
||||
[view {:style {:width 260
|
||||
:marginTop 10
|
||||
:paddingLeft 8
|
||||
:paddingRight 8
|
||||
:alignItems "flex-start"
|
||||
:alignSelf "flex-start"}}
|
||||
[view {:style {:borderRadius 14
|
||||
:padding 12
|
||||
:height 38
|
||||
|
@ -99,6 +102,89 @@
|
|||
(for [member ["Geoff" "Justas"]]
|
||||
^{:key member} [typing member])])
|
||||
|
||||
(defn toolbar-content-chat [group-chat]
|
||||
(let
|
||||
[contacts (subscribe [:chat :contacts])
|
||||
name (subscribe [:chat :name])]
|
||||
(fn [group-chat]
|
||||
[view {:style {:flex 1
|
||||
:flexDirection "row"
|
||||
:backgroundColor "transparent"}}
|
||||
[view {:style {:flex 1
|
||||
:alignItems "flex-start"
|
||||
:justifyContent "center"
|
||||
:marginRight 112}}
|
||||
[text {:style {:marginTop -2.5
|
||||
:color text1-color
|
||||
:fontSize 16
|
||||
:fontFamily font}}
|
||||
(or @name "Chat name")]
|
||||
(if group-chat
|
||||
[view {:style {:flexDirection "row"}}
|
||||
[image {:source {:uri :icon_group}
|
||||
:style {:marginTop 4
|
||||
:width 14
|
||||
:height 9}}]
|
||||
[text {:style {:marginTop -0.5
|
||||
:marginLeft 4
|
||||
:fontFamily font
|
||||
:fontSize 12
|
||||
:color text2-color}}
|
||||
(let [cnt (count @contacts)]
|
||||
(str cnt
|
||||
(if (< 1 cnt)
|
||||
;; TODO https://github.com/r0man/inflections-clj
|
||||
" members"
|
||||
" member")
|
||||
", " cnt " active"))]]
|
||||
[text {:style {:marginTop 1
|
||||
:color text2-color
|
||||
:fontSize 12
|
||||
:fontFamily font}}
|
||||
"Active a minute ago"])]
|
||||
(when-not group-chat
|
||||
[view {:style {:position "absolute"
|
||||
:top 10
|
||||
:right 66}}
|
||||
[chat-photo {}]
|
||||
[contact-online {:online true}]])])))
|
||||
|
||||
(defn message-row [contact-by-identity group-chat]
|
||||
(fn [row _ _]
|
||||
(let [msg (-> row
|
||||
(add-msg-color contact-by-identity)
|
||||
(assoc :group-chat group-chat))]
|
||||
(list-item [chat-message msg]))))
|
||||
|
||||
(def group-caht-actions
|
||||
[{:title "Add Contact to chat"
|
||||
:icon res/add-icon
|
||||
:showWithText true}
|
||||
{:title "Remove Contact from chat"
|
||||
:icon res/trash-icon
|
||||
:showWithText true}
|
||||
{:title "Leave Chat"
|
||||
:icon res/leave-icon
|
||||
:showWithText true}])
|
||||
|
||||
(defn on-action-selected [position]
|
||||
(case position
|
||||
0 (dispatch [:show-add-participants #_navigator])
|
||||
1 (dispatch [:show-remove-participants #_navigator])
|
||||
2 (dispatch [:leave-group-chat #_navigator])))
|
||||
|
||||
(defn overlay [{:keys [on-click-outside]} items]
|
||||
[view {:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0}
|
||||
[touchable-highlight {:on-press on-click-outside
|
||||
:underlay-color :transparent
|
||||
:style {:flex 1}}
|
||||
[view nil]]
|
||||
items])
|
||||
|
||||
(defn action-view [action]
|
||||
[touchable-highlight {:on-press (fn []
|
||||
(dispatch [:set-show-actions false])
|
||||
|
@ -127,157 +213,140 @@
|
|||
:fontFamily font}}
|
||||
subtitle])]]])
|
||||
|
||||
(defn actions-list-view [navigator chat]
|
||||
(when-let [actions (when (and (:group-chat chat)
|
||||
(:is-active chat))
|
||||
[{:title "Add Contact to chat"
|
||||
:icon "icon_menu_group"
|
||||
:icon-style {:width 25
|
||||
:height 19}
|
||||
:handler #(dispatch [:show-add-participants navigator])}
|
||||
{:title "Remove Contact from chat"
|
||||
:subtitle "Alex, John"
|
||||
:icon "icon_search_gray_copy"
|
||||
:icon-style {:width 17
|
||||
:height 17}
|
||||
:handler #(dispatch [:show-remove-participants navigator])}
|
||||
{:title "Leave Chat"
|
||||
:icon "icon_muted"
|
||||
:icon-style {:width 18
|
||||
:height 21}
|
||||
:handler #(dispatch [:leave-group-chat navigator])}
|
||||
{:title "Settings"
|
||||
:subtitle "Not implemented"
|
||||
:icon "icon_settings"
|
||||
:icon-style {:width 20
|
||||
:height 13}
|
||||
:handler (fn [] )}])]
|
||||
[view {:style {:backgroundColor toolbar-background1
|
||||
:elevation 2
|
||||
:position "absolute"
|
||||
:top 56
|
||||
:left 0
|
||||
:right 0}}
|
||||
[view {:style {:marginLeft 16
|
||||
:height 1.5
|
||||
:backgroundColor separator-color}}]
|
||||
[view {:style {:marginVertical 10}}
|
||||
(for [action actions]
|
||||
^{:key action} [action-view action])]]))
|
||||
(defn actions-list-view []
|
||||
(let [{:keys [group-chat active]}
|
||||
(subscribe [:chat-properties [:group-chat :name :contacts :active]])]
|
||||
(when-let [actions (when (and @group-chat @active)
|
||||
[{:title "Add Contact to chat"
|
||||
:icon :icon_menu_group
|
||||
:icon-style {:width 25
|
||||
:height 19}
|
||||
:handler nil #_#(dispatch [:show-add-participants
|
||||
navigator])}
|
||||
{:title "Remove Contact from chat"
|
||||
:subtitle "Alex, John"
|
||||
:icon :icon_search_gray_copy
|
||||
:icon-style {:width 17
|
||||
:height 17}
|
||||
:handler nil #_#(dispatch
|
||||
[:show-remove-participants navigator])}
|
||||
{:title "Leave Chat"
|
||||
:icon :icon_muted
|
||||
:icon-style {:width 18
|
||||
:height 21}
|
||||
:handler nil #_#(dispatch [:leave-group-chat
|
||||
navigator])}
|
||||
{:title "Settings"
|
||||
:subtitle "Not implemented"
|
||||
:icon :icon_settings
|
||||
:icon-style {:width 20
|
||||
:height 13}
|
||||
:handler (fn [])}])]
|
||||
[view {:style {:backgroundColor toolbar-background1
|
||||
:elevation 2
|
||||
:position :absolute
|
||||
:top 56
|
||||
:left 0
|
||||
:right 0}}
|
||||
[view {:style {:marginLeft 16
|
||||
:height 1.5
|
||||
:backgroundColor separator-color}}]
|
||||
[view {:style {:marginVertical 10}}
|
||||
(for [action actions]
|
||||
^{:key action} [action-view action])]])))
|
||||
|
||||
(defn overlay [{:keys [on-click-outside]} items]
|
||||
[view {:position "absolute"
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0}
|
||||
[touchable-highlight {:on-press on-click-outside
|
||||
:underlay-color :transparent
|
||||
:style {:flex 1}}
|
||||
[view nil]]
|
||||
items])
|
||||
(defn actions-view []
|
||||
[overlay {:on-click-outside #(dispatch [:set-show-actions false])}
|
||||
[actions-list-view]])
|
||||
|
||||
(defn actions-view [navigator chat]
|
||||
[overlay {:on-click-outside (fn []
|
||||
(dispatch [:set-show-actions false]))}
|
||||
[actions-list-view navigator chat]])
|
||||
(defn toolbar []
|
||||
(let [{:keys [group-chat name contacts]}
|
||||
(subscribe [:chat-properties [:group-chat :name :contacts]])
|
||||
show-actions (subscribe [:show-actions])]
|
||||
(fn []
|
||||
[view {:style {:flexDirection "row"
|
||||
:height 56
|
||||
:backgroundColor toolbar-background1
|
||||
:elevation 2}}
|
||||
(when (not @show-actions)
|
||||
[touchable-highlight {:on-press #(dispatch [:navigate-back])
|
||||
:underlay-color :transparent}
|
||||
[view {:width 56
|
||||
:height 56}
|
||||
[image {:source {:uri "icon_back"}
|
||||
:style {:marginTop 21
|
||||
:marginLeft 23
|
||||
:width 8
|
||||
:height 14}}]]])
|
||||
[view {:style {:flex 1
|
||||
:marginLeft (if @show-actions 16 0)
|
||||
:alignItems "flex-start"
|
||||
:justifyContent "center"}}
|
||||
[text {:style {:marginTop -2.5
|
||||
:color text1-color
|
||||
:fontSize 16
|
||||
:fontFamily font}}
|
||||
(or @name "Chat name")]
|
||||
(if @group-chat
|
||||
[view {:style {:flexDirection :row}}
|
||||
[image {:source {:uri :icon_group}
|
||||
:style {:marginTop 4
|
||||
:width 14
|
||||
:height 9}}]
|
||||
[text {:style {:marginTop -0.5
|
||||
:marginLeft 4
|
||||
:fontFamily font
|
||||
:fontSize 12
|
||||
:color text2-color}}
|
||||
(let [cnt (count @contacts)]
|
||||
(str cnt
|
||||
(if (< 1 cnt)
|
||||
" members"
|
||||
" member")
|
||||
", " cnt " active"))]]
|
||||
[text {:style {:marginTop 1
|
||||
:color text2-color
|
||||
:fontSize 12
|
||||
:fontFamily font}}
|
||||
"Active a minute ago"])]
|
||||
(if @show-actions
|
||||
[touchable-highlight
|
||||
{:on-press #(dispatch [:set-show-actions false])
|
||||
:underlay-color :transparent}
|
||||
[view {:style {:width 56
|
||||
:height 56}}
|
||||
[image {:source {:uri :icon_up}
|
||||
:style {:marginTop 23
|
||||
:marginLeft 21
|
||||
:width 14
|
||||
:height 8}}]]]
|
||||
[touchable-highlight
|
||||
{:on-press #(dispatch [:set-show-actions true])
|
||||
:underlay-color :transparent}
|
||||
[view {:style {:width 56
|
||||
:height 56}}
|
||||
[chat-photo {}]
|
||||
[contact-online {:online true}]]])])))
|
||||
|
||||
(defn toolbar [navigator chat show-actions]
|
||||
[view {:style {:flexDirection "row"
|
||||
:height 56
|
||||
:backgroundColor toolbar-background1
|
||||
:elevation 2}}
|
||||
(when (not show-actions)
|
||||
[touchable-highlight {:on-press (fn []
|
||||
(nav-pop navigator))
|
||||
:underlay-color :transparent}
|
||||
[view {:width 56
|
||||
:height 56}
|
||||
[image {:source {:uri "icon_back"}
|
||||
:style {:marginTop 21
|
||||
:marginLeft 23
|
||||
:width 8
|
||||
:height 14}}]]])
|
||||
[view {:style {:flex 1
|
||||
:marginLeft (if show-actions 16 0)
|
||||
:alignItems "flex-start"
|
||||
:justifyContent "center"}}
|
||||
[text {:style {:marginTop -2.5
|
||||
:color text1-color
|
||||
:fontSize 16
|
||||
:fontFamily font}}
|
||||
(or (chat :name)
|
||||
"Chat name")]
|
||||
(if (:group-chat chat)
|
||||
[view {:style {:flexDirection "row"}}
|
||||
[image {:source {:uri "icon_group"}
|
||||
:style {:marginTop 4
|
||||
:width 14
|
||||
:height 9}}]
|
||||
[text {:style {:marginTop -0.5
|
||||
:marginLeft 4
|
||||
:fontFamily font
|
||||
:fontSize 12
|
||||
:color text2-color}}
|
||||
(str (count (:contacts chat))
|
||||
(if (< 1 (count (:contacts chat)))
|
||||
" members"
|
||||
" member")
|
||||
", " (count (:contacts chat)) " active")]]
|
||||
[text {:style {:marginTop 1
|
||||
:color text2-color
|
||||
:fontSize 12
|
||||
:fontFamily font}}
|
||||
"Active a minute ago"])]
|
||||
(if show-actions
|
||||
[touchable-highlight {:on-press (fn []
|
||||
(dispatch [:set-show-actions false]))
|
||||
:underlay-color :transparent}
|
||||
[view {:style {:width 56
|
||||
:height 56}}
|
||||
[image {:source {:uri "icon_up"}
|
||||
:style {:marginTop 23
|
||||
:marginLeft 21
|
||||
:width 14
|
||||
:height 8}}]]]
|
||||
[touchable-highlight {:on-press (fn []
|
||||
(dispatch [:set-show-actions true]))
|
||||
:underlay-color :transparent}
|
||||
[view {:style {:width 56
|
||||
:height 56}}
|
||||
[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])
|
||||
:dataSource (to-datasource2 @messages)}]))))
|
||||
|
||||
(defn chat [{:keys [navigator]}]
|
||||
(let [messages (subscribe [:get-chat-messages])
|
||||
chat (subscribe [:get-current-chat])
|
||||
(defn chat []
|
||||
(let [is-active (subscribe [:chat :is-active])
|
||||
group-chat (subscribe [:chat :group-chat])
|
||||
show-actions-atom (subscribe [:show-actions])]
|
||||
(fn []
|
||||
(let [msgs @messages
|
||||
;_ (log/debug "messages=" msgs)
|
||||
;; temp
|
||||
typing (:group-chat @chat)
|
||||
;; end temp
|
||||
datasource (to-realm-datasource msgs)
|
||||
contacts (:contacts @chat)
|
||||
contact-by-identity (contacts-by-identity contacts)]
|
||||
[view {:style {:flex 1
|
||||
:backgroundColor chat-background}}
|
||||
[toolbar navigator @chat @show-actions-atom]
|
||||
(let [last-msg-id (:last-msg-id @chat)]
|
||||
[list-view {:dataSource datasource
|
||||
:enableEmptySections true
|
||||
:renderScrollComponent (fn [props]
|
||||
(invertible-scroll-view (js->clj props)))
|
||||
:renderRow (fn [row section-id row-id]
|
||||
(let [msg (-> (js->clj row :keywordize-keys true)
|
||||
(add-msg-color contact-by-identity)
|
||||
(assoc :group-chat (:group-chat @chat))
|
||||
(assoc :typing typing))]
|
||||
(r/as-element [chat-message msg last-msg-id])))}])
|
||||
(when (:group-chat @chat)
|
||||
[typing-all])
|
||||
(when (:is-active @chat)
|
||||
[chat-message-new])
|
||||
(when @show-actions-atom
|
||||
[actions-view navigator @chat])]))))
|
||||
[view {:style {:flex 1
|
||||
:backgroundColor chat-background}}
|
||||
[toolbar]
|
||||
[messages-view @group-chat]
|
||||
(when @group-chat [typing-all])
|
||||
(when is-active [chat-message-new])
|
||||
(when @show-actions-atom [actions-view])])))
|
||||
|
|
|
@ -43,13 +43,12 @@
|
|||
[view {:style {:backgroundColor color-light-blue-transparent
|
||||
:height 24
|
||||
:borderRadius 50
|
||||
:alignSelf "center"
|
||||
:alignSelf :center
|
||||
:marginTop 20
|
||||
:marginBottom 20
|
||||
:paddingTop 5
|
||||
:paddingHorizontal 12}}
|
||||
[text {:style (merge style-sub-text
|
||||
{:textAlign "center"})}
|
||||
[text {:style (assoc style-sub-text :textAlign :center)}
|
||||
date]]])
|
||||
|
||||
(defn contact-photo [{:keys [photo-path]}]
|
||||
|
@ -63,7 +62,7 @@
|
|||
|
||||
(defn contact-online [{:keys [online]}]
|
||||
(when online
|
||||
[view {:position "absolute"
|
||||
[view {:position :absolute
|
||||
:top 44
|
||||
:left 44
|
||||
:width 24
|
||||
|
@ -72,14 +71,14 @@
|
|||
:backgroundColor online-color
|
||||
:borderWidth 2
|
||||
:borderColor color-white}
|
||||
[view {:position "absolute"
|
||||
[view {:position :absolute
|
||||
:top 8
|
||||
:left 5
|
||||
:width 4
|
||||
:height 4
|
||||
:borderRadius 50
|
||||
:backgroundColor color-white}]
|
||||
[view {:position "absolute"
|
||||
[view {:position :absolute
|
||||
:top 8
|
||||
:left 11
|
||||
:width 4
|
||||
|
@ -88,11 +87,11 @@
|
|||
:backgroundColor color-white}]]))
|
||||
|
||||
|
||||
(defn message-content-status [from content]
|
||||
[view {:style {:flex 1
|
||||
:alignSelf "center"
|
||||
:alignItems "center"
|
||||
:width 249}}
|
||||
(defn message-content-status [{:keys [from content]}]
|
||||
[view {:style {:flex 1
|
||||
:alignSelf :center
|
||||
:alignItems :center
|
||||
:width 249}}
|
||||
[view {:style {:marginTop 20}}
|
||||
[contact-photo {}]
|
||||
[contact-online {:online true}]]
|
||||
|
@ -105,13 +104,13 @@
|
|||
:fontFamily font
|
||||
:fontSize 14
|
||||
:lineHeight 20
|
||||
:textAlign "center"
|
||||
:textAlign :center
|
||||
:color text2-color}}
|
||||
content]])
|
||||
|
||||
(defn message-content-audio [{:keys [content-type content-type]}]
|
||||
[view {:style {:flexDirection "row"
|
||||
:alignItems "center"}}
|
||||
(defn message-content-audio [_]
|
||||
[view {:style {:flexDirection :row
|
||||
:alignItems :center}}
|
||||
[view {:style {:width 33
|
||||
:height 33
|
||||
:borderRadius 50
|
||||
|
@ -124,18 +123,18 @@
|
|||
:width 120
|
||||
:height 26
|
||||
:elevation 1}}
|
||||
[view {:style {:position "absolute"
|
||||
[view {:style {:position :absolute
|
||||
:top 4
|
||||
:width 120
|
||||
:height 2
|
||||
:backgroundColor "#EC7262"}}]
|
||||
[view {:style {:position "absolute"
|
||||
[view {:style {:position :absolute
|
||||
:left 0
|
||||
:top 0
|
||||
:width 2
|
||||
:height 10
|
||||
:backgroundColor "#4A5258"}}]
|
||||
[text {:style {:position "absolute"
|
||||
[text {:style {:position :absolute
|
||||
:left 1
|
||||
:top 11
|
||||
:fontFamily font
|
||||
|
@ -150,25 +149,26 @@
|
|||
(let [commands-atom (subscribe [:get-commands])]
|
||||
(fn [content]
|
||||
(let [commands @commands-atom
|
||||
{:keys [command content]} (parse-command-msg-content commands content)]
|
||||
[view {:style {:flexDirection "column"}}
|
||||
[view {:style {:flexDirection "row"
|
||||
{:keys [command content]}
|
||||
(parse-command-msg-content commands content)]
|
||||
[view {:style {:flexDirection :column}}
|
||||
[view {:style {:flexDirection :row
|
||||
:marginRight 32}}
|
||||
[view {:style {:backgroundColor (:color command)
|
||||
:height 24
|
||||
:borderRadius 50
|
||||
:paddingTop 3
|
||||
:paddingHorizontal 12}}
|
||||
[text {:style {:fontSize 12
|
||||
:fontFamily font
|
||||
:color color-white}}
|
||||
[text {:style {:fontSize 12
|
||||
:fontFamily font
|
||||
:color color-white}}
|
||||
(:text command)]]]
|
||||
[image {:source (:icon command)
|
||||
:style {:position "absolute"
|
||||
:top 4
|
||||
:right 0
|
||||
:width 12
|
||||
:height 13}}]
|
||||
:style {:position :absolute
|
||||
:top 4
|
||||
:right 0
|
||||
:width 12
|
||||
:height 13}}]
|
||||
[text {:style (merge style-message-text
|
||||
{:marginTop 8
|
||||
:marginHorizontal 0})}
|
||||
|
@ -180,18 +180,18 @@
|
|||
(defn set-chat-command [msg-id command]
|
||||
(dispatch [:set-response-chat-command msg-id (:command command)]))
|
||||
|
||||
(defn message-content-command-request [msg-id from content outgoing group-chat]
|
||||
|
||||
(defn message-content-command-request
|
||||
[{:keys [msg-id content outgoing group-chat from]}]
|
||||
(let [commands-atom (subscribe [:get-commands])]
|
||||
(fn [msg-id from content outgoing group-chat]
|
||||
(fn [{:keys [msg-id content outgoing group-chat from]}]
|
||||
(let [commands @commands-atom
|
||||
{:keys [command content]} (parse-command-request-msg-content commands content)]
|
||||
[touchable-highlight {:onPress (fn []
|
||||
(set-chat-command msg-id command))
|
||||
[touchable-highlight {:onPress #(set-chat-command msg-id command)
|
||||
:underlay-color :transparent}
|
||||
[view {:style {:paddingRight 16}}
|
||||
[view {:style (merge {:borderRadius 14
|
||||
:padding 12
|
||||
:paddingRight 28
|
||||
:backgroundColor color-white})}
|
||||
(when (and group-chat (not outgoing))
|
||||
[text {:style (merge style-sub-text
|
||||
|
@ -199,7 +199,7 @@
|
|||
from])
|
||||
[text {:style style-message-text}
|
||||
content]]
|
||||
[view {:style {:position "absolute"
|
||||
[view {:style {:position :absolute
|
||||
:top 12
|
||||
:right 0
|
||||
:width 32
|
||||
|
@ -207,14 +207,14 @@
|
|||
:borderRadius 50
|
||||
:backgroundColor (:color command)}}
|
||||
[image {:source (:request-icon command)
|
||||
:style {:position "absolute"
|
||||
:style {:position :absolute
|
||||
:top 9
|
||||
:left 10
|
||||
:width 12
|
||||
:height 13}}]]
|
||||
(when (:request-text command)
|
||||
[view {:style {:marginTop 4
|
||||
:height 14}}
|
||||
[view {:style {:marginTop 4
|
||||
:height 14}}
|
||||
[text {:style style-sub-text}
|
||||
(:request-text command)]])]]))))
|
||||
|
||||
|
@ -227,41 +227,102 @@
|
|||
{:color color-white}))}
|
||||
content])
|
||||
|
||||
(defn message-content [{:keys [msg-id from content-type content outgoing group-chat selected]}]
|
||||
(if (= content-type content-type-command-request)
|
||||
[message-content-command-request msg-id from content outgoing group-chat]
|
||||
[view {:style (merge {:borderRadius 14
|
||||
:padding 12
|
||||
:backgroundColor color-white}
|
||||
(when (= content-type content-type-command)
|
||||
{:paddingTop 10
|
||||
:paddingBottom 14})
|
||||
(if outgoing
|
||||
(when (and group-chat (= content-type text-content-type))
|
||||
{:backgroundColor color-blue})
|
||||
(when selected
|
||||
{:backgroundColor selected-message-color})))}
|
||||
(when (and group-chat (not outgoing))
|
||||
[text {:style (merge style-sub-text
|
||||
{:marginBottom 2})}
|
||||
from])
|
||||
(cond
|
||||
(or (= content-type text-content-type)
|
||||
(= content-type content-type-status))
|
||||
[message-content-plain content outgoing group-chat]
|
||||
(= content-type content-type-command)
|
||||
[message-content-command content]
|
||||
:else [message-content-audio {:content content
|
||||
:content-type content-type}])]))
|
||||
|
||||
#_(defn message-content [{:keys [msg-id from content-type content outgoing
|
||||
group-chat selected]}]
|
||||
(if (= content-type content-type-command-request)
|
||||
[message-content-command-request msg-id from content outgoing group-chat]
|
||||
[view {:style (merge {:borderRadius 14
|
||||
:padding 12
|
||||
:backgroundColor color-white}
|
||||
(when (= content-type content-type-command)
|
||||
{:paddingTop 10
|
||||
:paddingBottom 14})
|
||||
(if outgoing
|
||||
(when (and group-chat (= content-type text-content-type))
|
||||
{:backgroundColor color-blue})
|
||||
(when selected
|
||||
{:backgroundColor selected-message-color})))}
|
||||
(when (and group-chat (not outgoing))
|
||||
[text {:style (merge style-sub-text
|
||||
{:marginBottom 2})}
|
||||
from])
|
||||
(cond
|
||||
(or (= content-type text-content-type)
|
||||
(= content-type content-type-status))
|
||||
[message-content-plain content outgoing group-chat]
|
||||
(= content-type content-type-command)
|
||||
[message-content-command content]
|
||||
:else [message-content-audio {:content content
|
||||
:content-type content-type}])]))
|
||||
|
||||
(defn message-view
|
||||
[{:keys [content-type outgoing background-color group-chat selected]} content]
|
||||
[view {:style (merge {:borderRadius 14
|
||||
:padding 12
|
||||
:backgroundColor color-white}
|
||||
(when (= content-type content-type-command)
|
||||
{:paddingTop 10
|
||||
:paddingBottom 14})
|
||||
(if outgoing
|
||||
(when (and group-chat (= content-type text-content-type))
|
||||
{:backgroundColor color-blue})
|
||||
(when selected
|
||||
{:backgroundColor selected-message-color})))}
|
||||
#_(when (and group-chat (not outgoing))
|
||||
[text {:style {:marginTop 0
|
||||
:fontSize 12
|
||||
:fontFamily font}}
|
||||
"Justas"])
|
||||
content])
|
||||
|
||||
(defmulti message-content (fn [_ message]
|
||||
(message :content-type)))
|
||||
|
||||
(defmethod message-content content-type-command-request
|
||||
[wrapper message]
|
||||
[wrapper message [message-content-command-request message]])
|
||||
|
||||
(defn text-message
|
||||
[{:keys [content outgoing group-chat] :as message}]
|
||||
[message-view message
|
||||
[text {:style (merge style-message-text
|
||||
{:marginTop (if (and group-chat (not outgoing))
|
||||
4
|
||||
0)}
|
||||
(when (and outgoing group-chat)
|
||||
{:color color-white}))}
|
||||
content]])
|
||||
|
||||
(defmethod message-content text-content-type
|
||||
[wrapper message]
|
||||
[wrapper message [text-message message]])
|
||||
|
||||
(defmethod message-content content-type-status
|
||||
[_ message]
|
||||
[message-content-status message])
|
||||
|
||||
(defmethod message-content content-type-command
|
||||
[wrapper {:keys [content] :as message}]
|
||||
[wrapper message
|
||||
[message-view message [message-content-command content]]])
|
||||
|
||||
(defmethod message-content :default
|
||||
[wrapper {:keys [content-type content] :as message}]
|
||||
[wrapper message
|
||||
[message-view message
|
||||
[message-content-audio {:content content
|
||||
:content-type content-type}]]])
|
||||
|
||||
(defn message-delivery-status [{:keys [delivery-status]}]
|
||||
[view {:style {:flexDirection "row"
|
||||
[view {:style {:flexDirection :row
|
||||
:marginTop 2}}
|
||||
|
||||
[image {:source (case delivery-status
|
||||
:delivered {:uri "icon_ok_small"}
|
||||
:seen {:uri "icon_ok_small"}
|
||||
:seen-by-everyone {:uri "icon_ok_small"}
|
||||
:failed res/delivery-failed-icon)
|
||||
:delivered {:uri :icon_ok_small}
|
||||
:seen {:uri :icon_ok_small}
|
||||
:seen-by-everyone {:uri :icon_ok_small}
|
||||
:failed res/delivery-failed-icon)
|
||||
:style {:marginTop 6
|
||||
:width 9
|
||||
:height 7}}]
|
||||
|
@ -284,11 +345,12 @@
|
|||
:width 24
|
||||
:height 24}}]])
|
||||
|
||||
(defn incoming-group-message-body [{:keys [msg-id from content content-type outgoing
|
||||
delivery-status selected new-day same-author
|
||||
same-direction last-msg typing]}]
|
||||
|
||||
(defn incoming-group-message-body
|
||||
[{:keys [selected new-day same-author same-direction last-msg typing]}
|
||||
content]
|
||||
(let [delivery-status :seen-by-everyone]
|
||||
[view {:style {:flexDirection "column"}}
|
||||
[view {:style {:flexDirection :column}}
|
||||
(when selected
|
||||
[text {:style {:marginTop 18
|
||||
:marginLeft 40
|
||||
|
@ -296,13 +358,13 @@
|
|||
:fontSize 12
|
||||
:color text2-color}}
|
||||
"Mar 7th, 15:22"])
|
||||
[view {:style (merge {:flexDirection "row"
|
||||
:alignSelf "flex-start"
|
||||
[view {:style (merge {:flexDirection :row
|
||||
:alignSelf :flex-start
|
||||
:marginTop (cond
|
||||
new-day 0
|
||||
same-author 4
|
||||
new-day 0
|
||||
same-author 4
|
||||
same-direction 20
|
||||
:else 10)
|
||||
:else 10)
|
||||
:paddingRight 8
|
||||
:paddingLeft 8}
|
||||
(when (and last-msg (not typing))
|
||||
|
@ -310,71 +372,50 @@
|
|||
[view {:style {:width 24}}
|
||||
(when (not same-author)
|
||||
[member-photo {}])]
|
||||
[view {:style {:flexDirection "column"
|
||||
[view {:style {:flexDirection :column
|
||||
:width 260
|
||||
:paddingLeft 8
|
||||
:alignItems "flex-start"}}
|
||||
[message-content {:msg-id msg-id
|
||||
:from from
|
||||
:content-type content-type
|
||||
:content content
|
||||
:outgoing outgoing
|
||||
:group-chat true
|
||||
:selected selected}]
|
||||
:alignItems :flex-start}}
|
||||
content
|
||||
;; TODO show for last or selected
|
||||
(when (and selected delivery-status)
|
||||
[message-delivery-status {:delivery-status delivery-status}])]]]))
|
||||
|
||||
(defn message-body [{:keys [msg-id content content-type outgoing delivery-status
|
||||
group-chat new-day same-author same-direction last-msg typing]}]
|
||||
(let [delivery-status :seen]
|
||||
[view {:style (merge {:flexDirection "column"
|
||||
(defn message-body
|
||||
[{:keys [outgoing new-day same-author same-direction last-msg typing]}
|
||||
content]
|
||||
(let [delivery-status :seen
|
||||
align (if outgoing :flex-end :flex-start)]
|
||||
[view {:style (merge {:flexDirection :column
|
||||
:width 260
|
||||
:paddingTop (cond
|
||||
new-day 0
|
||||
same-author 4
|
||||
new-day 0
|
||||
same-author 4
|
||||
same-direction 20
|
||||
:else 10)
|
||||
:else 10)
|
||||
:paddingRight 8
|
||||
:paddingLeft 8}
|
||||
(if outgoing
|
||||
{:alignSelf "flex-end"
|
||||
:alignItems "flex-end"}
|
||||
{:alignItems "flex-start"
|
||||
:alignSelf "flex-start"})
|
||||
:paddingLeft 8
|
||||
:alignSelf align
|
||||
:alignItems align}
|
||||
(when (and last-msg (not typing))
|
||||
{:paddingBottom 20}))}
|
||||
[message-content {:msg-id msg-id
|
||||
:content-type content-type
|
||||
:content content
|
||||
:outgoing outgoing
|
||||
:group-chat group-chat}]
|
||||
content
|
||||
(when (and outgoing delivery-status)
|
||||
[message-delivery-status {:delivery-status delivery-status}])]))
|
||||
|
||||
(defn chat-message [{:keys [msg-id from content content-type outgoing delivery-status
|
||||
date new-day group-chat selected same-author same-direction
|
||||
last-msg typing] :as msg}
|
||||
last-msg-id]
|
||||
(defn chat-message
|
||||
[{:keys [msg-id outgoing delivery-status date new-day group-chat]
|
||||
:as message}
|
||||
last-msg-id]
|
||||
[view {}
|
||||
(when new-day
|
||||
[message-date {:date date}])
|
||||
(let [msg-data {:msg-id msg-id
|
||||
:from from
|
||||
:content content
|
||||
:content-type content-type
|
||||
:outgoing outgoing
|
||||
:delivery-status (keyword delivery-status)
|
||||
:group-chat group-chat
|
||||
:selected selected
|
||||
:new-day new-day
|
||||
:same-author same-author
|
||||
:same-direction same-direction
|
||||
:last-msg (= last-msg-id msg-id)
|
||||
:typing typing}]
|
||||
(let [msg-data
|
||||
(merge message {:delivery-status (keyword delivery-status)
|
||||
:last-msg (= last-msg-id msg-id)})]
|
||||
[view {}
|
||||
(when (= content-type content-type-status)
|
||||
[message-content-status from content])
|
||||
(if (and group-chat (not outgoing))
|
||||
[incoming-group-message-body msg-data]
|
||||
[message-body msg-data])])])
|
||||
[message-content
|
||||
(if (and group-chat (not outgoing))
|
||||
incoming-group-message-body
|
||||
message-body)
|
||||
msg-data]])])
|
||||
|
|
|
@ -12,31 +12,27 @@
|
|||
text1-color
|
||||
text2-color]]
|
||||
[syng-im.utils.utils :refer [log toast http-post]]
|
||||
[syng-im.utils.logging :as log]
|
||||
[syng-im.resources :as res]
|
||||
[reagent.core :as r]))
|
||||
[syng-im.resources :as res]))
|
||||
|
||||
(defn cancel-command-input []
|
||||
(dispatch [:set-chat-command nil]))
|
||||
(dispatch [:cancel-command]))
|
||||
|
||||
(defn set-input-message [message]
|
||||
(dispatch [:set-chat-command-content message]))
|
||||
|
||||
(defn send-command [chat-id command text]
|
||||
(dispatch [:stage-command chat-id command text])
|
||||
(defn send-command []
|
||||
(dispatch [:stage-command])
|
||||
(cancel-command-input))
|
||||
|
||||
(defn simple-command-input-view [command input-options]
|
||||
(let [chat-id-atom (subscribe [:get-current-chat-id])
|
||||
message-atom (subscribe [:get-chat-command-content])]
|
||||
(let [message-atom (subscribe [:get-chat-command-content])]
|
||||
(fn [command input-options]
|
||||
(let [chat-id @chat-id-atom
|
||||
message @message-atom]
|
||||
[view {:style {:flexDirection "row"
|
||||
:height 56
|
||||
:backgroundColor color-white
|
||||
:elevation 4}}
|
||||
[view {:style {:flexDirection "column"
|
||||
(let [message @message-atom]
|
||||
[view {:style {:flexDirection :row
|
||||
:height 56
|
||||
:backgroundColor color-white
|
||||
:elevation 4}}
|
||||
[view {:style {:flexDirection :column
|
||||
:marginTop 16
|
||||
:marginBottom 16
|
||||
:marginLeft 16
|
||||
|
@ -50,7 +46,7 @@
|
|||
:fontFamily font
|
||||
:color color-white}}
|
||||
(:text command)]]
|
||||
[text-input (merge {:underlineColorAndroid "transparent"
|
||||
[text-input (merge {:underlineColorAndroid :transparent
|
||||
:style {:flex 1
|
||||
:marginLeft 8
|
||||
:marginTop 7
|
||||
|
@ -60,36 +56,33 @@
|
|||
:autoFocus true
|
||||
:placeholder "Type"
|
||||
:placeholderTextColor text2-color
|
||||
:onChangeText (fn [new-text]
|
||||
(set-input-message new-text))
|
||||
:onSubmitEditing (fn [e]
|
||||
(send-command chat-id command message))}
|
||||
:onChangeText set-input-message
|
||||
:onSubmitEditing send-command}
|
||||
input-options)
|
||||
message]
|
||||
(if (pos? (count message))
|
||||
[touchable-highlight {:on-press (fn []
|
||||
(send-command chat-id command message))
|
||||
:underlay-color :transparent}
|
||||
[touchable-highlight
|
||||
{:on-press send-command
|
||||
:underlay-color :transparent}
|
||||
[view {:style {:marginTop 10
|
||||
:marginRight 10
|
||||
:width 36
|
||||
:height 36
|
||||
:borderRadius 50
|
||||
:backgroundColor color-blue}}
|
||||
[image {:source {:uri "icon_send"}
|
||||
:style {:marginTop 10.5
|
||||
:marginLeft 12
|
||||
:width 15
|
||||
:height 15}}]]]
|
||||
[touchable-highlight {:on-press (fn []
|
||||
(cancel-command-input))
|
||||
[image {:source {:uri :icon_send}
|
||||
:style {:marginTop 10.5
|
||||
:marginLeft 12
|
||||
:width 15
|
||||
:height 15}}]]]
|
||||
[touchable-highlight {:on-press cancel-command-input
|
||||
:underlay-color :transparent}
|
||||
[view {:style {:marginTop 10
|
||||
:marginRight 10
|
||||
:width 36
|
||||
:height 36}}
|
||||
[view {:style {:marginTop 10
|
||||
:marginRight 10
|
||||
:width 36
|
||||
:height 36}}
|
||||
[image {:source res/icon-close-gray
|
||||
:style {:marginTop 10.5
|
||||
:marginLeft 12
|
||||
:width 12
|
||||
:height 12}}]]])]))))
|
||||
:style {:marginTop 10.5
|
||||
:marginLeft 12
|
||||
:width 12
|
||||
:height 12}}]]])]))))
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
[syng-im.resources :as res]
|
||||
[reagent.core :as r]))
|
||||
|
||||
(defn cancel-command-input [chat-id staged-command]
|
||||
(dispatch [:unstage-command chat-id staged-command]))
|
||||
(defn cancel-command-input [staged-command]
|
||||
(dispatch [:unstage-command staged-command]))
|
||||
|
||||
(defn simple-command-staged-view [staged-command]
|
||||
(let [chat-id-atom (subscribe [:get-current-chat-id])]
|
||||
|
@ -43,11 +43,11 @@
|
|||
:fontFamily font
|
||||
:color color-white}}
|
||||
(:text command)]]
|
||||
[touchable-highlight {:style {:position "absolute"
|
||||
:top 7
|
||||
:right 4}
|
||||
:onPress (fn []
|
||||
(cancel-command-input chat-id staged-command))
|
||||
[touchable-highlight {:style {:position "absolute"
|
||||
:top 7
|
||||
:right 4}
|
||||
:onPress #(cancel-command-input
|
||||
staged-command)
|
||||
:underlay-color :transparent}
|
||||
[image {:source res/icon-close-gray
|
||||
:style {:width 10
|
||||
|
|
|
@ -4,17 +4,13 @@
|
|||
view
|
||||
image
|
||||
touchable-highlight
|
||||
text-input
|
||||
dismiss-keyboard]]
|
||||
text-input]]
|
||||
[syng-im.components.styles :refer [font
|
||||
text2-color
|
||||
color-white
|
||||
color-blue]]
|
||||
[syng-im.components.chat.suggestions :refer [suggestions-view]]
|
||||
[syng-im.utils.utils :refer [log toast http-post]]
|
||||
[syng-im.utils.logging :as log]
|
||||
[syng-im.resources :as res]
|
||||
[reagent.core :as r]))
|
||||
[syng-im.utils.utils :refer [log toast http-post]]))
|
||||
|
||||
(defn set-input-message [message]
|
||||
(dispatch [:set-chat-input-text message]))
|
||||
|
@ -22,32 +18,30 @@
|
|||
(defn send [chat input-message]
|
||||
(let [{:keys [group-chat chat-id]} chat]
|
||||
(if group-chat
|
||||
(dispatch [:send-group-chat-msg chat-id
|
||||
input-message])
|
||||
(dispatch [:send-chat-msg chat-id
|
||||
input-message])))
|
||||
(set-input-message nil)
|
||||
(dismiss-keyboard))
|
||||
;; todo how much are different both events? is there real reason
|
||||
;; for differentiation here?
|
||||
(dispatch [:send-group-chat-msg chat-id input-message])
|
||||
(dispatch [:send-chat-msg]))))
|
||||
|
||||
(defn plain-message-input-view []
|
||||
(let [chat (subscribe [:get-current-chat])
|
||||
input-message-atom (subscribe [:get-chat-input-text])
|
||||
(let [chat (subscribe [:get-current-chat])
|
||||
input-message-atom (subscribe [:get-chat-input-text])
|
||||
staged-commands-atom (subscribe [:get-chat-staged-commands])]
|
||||
(fn []
|
||||
(let [input-message @input-message-atom]
|
||||
[view {:style {:flexDirection "column"}}
|
||||
[view {:style {:flexDirection :column}}
|
||||
[suggestions-view]
|
||||
[view {:style {:flexDirection "row"
|
||||
:height 56
|
||||
:backgroundColor color-white}}
|
||||
[image {:source {:uri "icon_list"}
|
||||
[view {:style {:flexDirection :row
|
||||
:height 56
|
||||
:backgroundColor color-white}}
|
||||
[image {:source {:uri :icon_list}
|
||||
:style {:marginTop 22
|
||||
:marginRight 6
|
||||
:marginBottom 6
|
||||
:marginLeft 21
|
||||
:width 13
|
||||
:height 12}}]
|
||||
[text-input {:underlineColorAndroid "transparent"
|
||||
[text-input {:underlineColorAndroid :transparent
|
||||
:style {:flex 1
|
||||
:marginLeft 16
|
||||
:marginTop -2
|
||||
|
@ -55,23 +49,20 @@
|
|||
:fontSize 14
|
||||
:fontFamily font
|
||||
:color text2-color}
|
||||
:autoFocus (< 0 (count @staged-commands-atom))
|
||||
:autoFocus (pos? (count @staged-commands-atom))
|
||||
:placeholder "Type"
|
||||
:placeholderTextColor text2-color
|
||||
:onChangeText (fn [new-text]
|
||||
(set-input-message new-text))
|
||||
:onSubmitEditing (fn [e]
|
||||
(send @chat input-message))}
|
||||
:onChangeText set-input-message
|
||||
:onSubmitEditing #(send @chat input-message)}
|
||||
input-message]
|
||||
[image {:source {:uri "icon_smile"}
|
||||
[image {:source {:uri :icon_smile}
|
||||
:style {:marginTop 18
|
||||
:marginRight 18
|
||||
:width 20
|
||||
:height 20}}]
|
||||
(when (or (pos? (count input-message))
|
||||
(pos? (count @staged-commands-atom)))
|
||||
[touchable-highlight {:on-press (fn []
|
||||
(send @chat input-message))
|
||||
[touchable-highlight {:on-press #(send @chat input-message)
|
||||
:underlay-color :transparent}
|
||||
[view {:style {:marginTop 10
|
||||
:marginRight 10
|
||||
|
@ -79,8 +70,8 @@
|
|||
:height 36
|
||||
:borderRadius 50
|
||||
:backgroundColor color-blue}}
|
||||
[image {:source {:uri "icon_send"}
|
||||
:style {:marginTop 10.5
|
||||
:marginLeft 12
|
||||
:width 15
|
||||
:height 15}}]]])]]))))
|
||||
[image {:source {:uri :icon_send}
|
||||
:style {:marginTop 10.5
|
||||
:marginLeft 12
|
||||
:width 15
|
||||
:height 15}}]]])]]))))
|
||||
|
|
|
@ -53,8 +53,8 @@
|
|||
[action-button {:buttonColor color-blue}
|
||||
[action-button-item {:title "New Chat"
|
||||
:buttonColor "#9b59b6"
|
||||
:onPress (fn []
|
||||
(dispatch [:show-contacts navigator]))}
|
||||
:onPress #(dispatch [:navigate-to
|
||||
:contact-list])}
|
||||
[icon {:name "android-create"
|
||||
:style {:fontSize 20
|
||||
:height 22
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
(defn list-item [component]
|
||||
(r/as-element component))
|
||||
|
||||
(def dismiss-keyboard (js/require "dismissKeyboard"))
|
||||
(def dismiss-keyboard! (js/require "dismissKeyboard"))
|
||||
|
||||
(comment
|
||||
(.-width (.get (.. js/React -Dimensions) "window"))
|
||||
|
|
|
@ -4,24 +4,29 @@
|
|||
;; schema of app-db
|
||||
(def schema {:greeting s/Str})
|
||||
|
||||
(def default-view :chat-list)
|
||||
|
||||
;; initial state of app-db
|
||||
(def app-db {:greeting "Hello Clojure in iOS and Android!"
|
||||
:identity-password "replace-me-with-user-entered-password"
|
||||
:identity "me"
|
||||
:contacts []
|
||||
:chat {:current-chat-id "0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd"
|
||||
:command nil
|
||||
:current-chat-id "console"
|
||||
:chat {:command nil
|
||||
:last-message nil}
|
||||
:chats {}
|
||||
:chats-updated-signal 0
|
||||
:show-actions false
|
||||
:new-group #{}
|
||||
:new-participants #{}
|
||||
:signed-up false})
|
||||
:signed-up false
|
||||
:view-id default-view
|
||||
:navigation-stack (list default-view)})
|
||||
|
||||
|
||||
(def protocol-initialized-path [:protocol-initialized])
|
||||
(def identity-password-path [:identity-password])
|
||||
(def current-chat-id-path [:chat :current-chat-id])
|
||||
(def current-chat-id-path [:current-chat-id])
|
||||
(def updated-chats-signal-path [:chats-updated-signal])
|
||||
(defn updated-chat-signal-path [chat-id]
|
||||
[:chats chat-id :chat-updated-signal])
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns syng-im.handlers
|
||||
(:require
|
||||
[re-frame.core :refer [register-handler after dispatch]]
|
||||
[re-frame.core :refer [register-handler after dispatch debug enrich]]
|
||||
[schema.core :as s :include-macros true]
|
||||
[syng-im.db :as db :refer [app-db schema]]
|
||||
[syng-im.protocol.api :refer [init-protocol]]
|
||||
|
@ -11,7 +11,8 @@
|
|||
[syng-im.models.contacts :as contacts]
|
||||
[syng-im.models.messages :refer [save-message
|
||||
update-message!
|
||||
message-by-id]]
|
||||
message-by-id
|
||||
get-messages]]
|
||||
[syng-im.models.commands :as commands :refer [set-chat-command
|
||||
set-response-chat-command
|
||||
set-chat-command-content
|
||||
|
@ -28,13 +29,13 @@
|
|||
apply-staged-commands
|
||||
check-suggestion]]
|
||||
[syng-im.handlers.sign-up :as sign-up-service]
|
||||
|
||||
[syng-im.models.chats :refer [chat-exists?
|
||||
create-chat
|
||||
chat-add-participants
|
||||
chat-remove-participants
|
||||
set-chat-active
|
||||
re-join-group-chat]]
|
||||
re-join-group-chat
|
||||
chat-by-id2] :as chats]
|
||||
[syng-im.models.chat :refer [signal-chat-updated
|
||||
set-current-chat-id
|
||||
current-chat-id
|
||||
|
@ -53,7 +54,9 @@
|
|||
nav-replace
|
||||
nav-pop]]
|
||||
[syng-im.utils.crypt :refer [gen-random-bytes]]
|
||||
[syng-im.utils.random :as random]))
|
||||
[syng-im.utils.random :as random]
|
||||
[clojure.string :as str]
|
||||
[syng-im.components.react :as r]))
|
||||
|
||||
;; -- Middleware ------------------------------------------------------------
|
||||
;;
|
||||
|
@ -72,8 +75,7 @@
|
|||
;; -- Common --------------------------------------------------------------
|
||||
|
||||
(register-handler :initialize-db
|
||||
(fn [_ _]
|
||||
app-db))
|
||||
(fn [_ _] app-db))
|
||||
|
||||
(register-handler :set-loading
|
||||
(fn [db [_ value]]
|
||||
|
@ -100,14 +102,6 @@
|
|||
(log/debug "crypt initialized")
|
||||
db))
|
||||
|
||||
(register-handler :navigate-to
|
||||
(fn [db [action navigator route nav-type]]
|
||||
(log/debug action route)
|
||||
(case nav-type
|
||||
:push (nav-push navigator route)
|
||||
:replace (nav-replace navigator route))
|
||||
db))
|
||||
|
||||
(register-handler :load-commands
|
||||
(fn [db [action]]
|
||||
(log/debug action)
|
||||
|
@ -137,13 +131,52 @@
|
|||
(update-identity identity)
|
||||
(set-initialized true))))
|
||||
|
||||
(defn gen-messages [n]
|
||||
(mapv (fn [_]
|
||||
(let [id (random-uuid)]
|
||||
{:msg-id id
|
||||
:content (str id
|
||||
"ooops sdfg dsfg"
|
||||
"s dfg\ndsfg dfg\ndsfgdsfgdsfg")
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"})) (range n)))
|
||||
|
||||
(defn store-message!
|
||||
[db [_ {chat-id :from
|
||||
outgoing :outgoing
|
||||
:as msg}]]
|
||||
(let [previous-message (first (get-in db [:chats chat-id :messages]))
|
||||
msg (merge msg
|
||||
{:same-author (if previous-message
|
||||
(= (:from previous-message) outgoing)
|
||||
true)
|
||||
:same-direction (if previous-message
|
||||
(= (:outgoing previous-message) outgoing)
|
||||
true)})]
|
||||
(save-message chat-id msg)))
|
||||
|
||||
(defn add-message-to-db
|
||||
[db chat-id {:keys [from outgoing] :as message}]
|
||||
(let [messages [:chats chat-id :messages]
|
||||
previous-message (first (get-in db [:chats chat-id :messages]))
|
||||
message (merge message
|
||||
{:same-author (if previous-message
|
||||
(= (:from previous-message) from)
|
||||
true)
|
||||
:same-direction (if previous-message
|
||||
(= (:outgoing previous-message) outgoing)
|
||||
true)})]
|
||||
(update-in db messages conj message)))
|
||||
|
||||
(defn receive-message
|
||||
[db [_ {chat-id :from :as msg}]]
|
||||
(add-message-to-db db chat-id msg))
|
||||
|
||||
(register-handler :received-msg
|
||||
(fn [db [action {chat-id :from
|
||||
msg-id :msg-id :as msg}]]
|
||||
(log/debug action "msg" msg)
|
||||
(let [db (create-chat db chat-id [chat-id] false)]
|
||||
(save-message chat-id msg)
|
||||
(signal-chat-updated db chat-id))))
|
||||
(-> receive-message
|
||||
((after store-message!))))
|
||||
|
||||
(register-handler :group-received-msg
|
||||
(fn [db [action {chat-id :group-id :as msg}]]
|
||||
|
@ -151,6 +184,12 @@
|
|||
(save-message chat-id msg)
|
||||
(signal-chat-updated db chat-id)))
|
||||
|
||||
(defn system-message [msg-id content]
|
||||
{:from "system"
|
||||
:msg-id msg-id
|
||||
:content content
|
||||
:content-type text-content-type})
|
||||
|
||||
(defn joined-chat-msg [chat-id from msg-id]
|
||||
(let [contact-name (:name (contacts/contact-by-identity from))]
|
||||
(save-message chat-id {:from "system"
|
||||
|
@ -171,31 +210,27 @@
|
|||
(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))]
|
||||
(save-message chat-id {:from "system"
|
||||
:msg-id msg-id
|
||||
:content (str (or remover-name from) " removed " (or removed-name identity))
|
||||
:content-type text-content-type})))
|
||||
(->> (str (or remover-name from) " removed " (or removed-name identity))
|
||||
(system-message msg-id)
|
||||
(save-message chat-id))))
|
||||
|
||||
(defn you-removed-from-group-msg [chat-id from msg-id]
|
||||
(let [remover-name (:name (contacts/contact-by-identity from))]
|
||||
(save-message chat-id {:from "system"
|
||||
:msg-id msg-id
|
||||
:content (str (or remover-name from) " removed you from group chat")
|
||||
:content-type text-content-type})))
|
||||
(->> (str (or remover-name from) " removed you from group chat")
|
||||
(system-message msg-id)
|
||||
(save-message chat-id))))
|
||||
|
||||
(defn participant-left-group-msg [chat-id from msg-id]
|
||||
(let [left-name (:name (contacts/contact-by-identity from))]
|
||||
(save-message chat-id {:from "system"
|
||||
:msg-id msg-id
|
||||
:content (str (or left-name from) " left")
|
||||
:content-type text-content-type})))
|
||||
(->> (str (or left-name from) " left")
|
||||
(system-message msg-id)
|
||||
(save-message chat-id))))
|
||||
|
||||
(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})))
|
||||
(->> (str "You've removed " (or contact-name identity))
|
||||
(system-message (random/id))
|
||||
(save-message chat-id))))
|
||||
|
||||
(defn left-chat-msg [chat-id]
|
||||
(save-message chat-id {:from "system"
|
||||
|
@ -252,56 +287,110 @@
|
|||
(let [{:keys [chat-id]} (message-by-id msg-id)]
|
||||
(signal-chat-updated db chat-id))))
|
||||
|
||||
(defn send-staged-commands [db chat-id]
|
||||
(let [staged-commands (get-in db (db/chat-staged-commands-path chat-id))]
|
||||
(dorun
|
||||
(map
|
||||
(fn [staged-command]
|
||||
(let [command-key (get-in staged-command [:command :command])
|
||||
content (commands/format-command-msg-content command-key
|
||||
(:content staged-command))
|
||||
msg (if (= chat-id "console")
|
||||
(sign-up-service/send-console-command db command-key content)
|
||||
;; TODO handle command, now sends as plain message
|
||||
(let [{msg-id :msg-id
|
||||
{from :from
|
||||
to :to} :msg} (api/send-user-msg {:to chat-id
|
||||
:content content})]
|
||||
{:msg-id msg-id
|
||||
:from from
|
||||
:to to
|
||||
:content content
|
||||
:content-type content-type-command
|
||||
:outgoing true}))]
|
||||
(save-message chat-id msg)))
|
||||
staged-commands))
|
||||
(defn console? [s]
|
||||
(= "console" s))
|
||||
|
||||
(def not-console?
|
||||
(complement console?))
|
||||
|
||||
(defn prepare-message
|
||||
[{:keys [identity current-chat-id] :as db} _]
|
||||
(let [text (get-in db [:chats current-chat-id :input-text])
|
||||
{:keys [command]} (check-suggestion db (str text " "))]
|
||||
(if command
|
||||
(set-chat-command db command)
|
||||
(assoc db :new-message (when-not (str/blank? text)
|
||||
{:msg-id (random/id)
|
||||
:chat-id current-chat-id
|
||||
:content text
|
||||
:to current-chat-id
|
||||
:from identity
|
||||
:content-type text-content-type
|
||||
:outgoing true
|
||||
;; todo should be refactored
|
||||
:same-author false
|
||||
:same-direction false})))))
|
||||
|
||||
(defn prepare-command [identity chat-id staged-command]
|
||||
(let [command-key (get-in staged-command [:command :command])
|
||||
content {:command (name command-key)
|
||||
:content (:content staged-command)}]
|
||||
{:msg-id (random/id)
|
||||
:from identity
|
||||
:to chat-id
|
||||
:content content
|
||||
:content-type content-type-command
|
||||
:outgoing true
|
||||
:handler (:handler staged-command)
|
||||
:same-author false
|
||||
:same-direction false}))
|
||||
|
||||
(defn prepare-staged-commans
|
||||
[{:keys [current-chat-id identity] :as db} _]
|
||||
(let [staged-commands (get-in db [:chats current-chat-id :staged-commands])]
|
||||
(->> staged-commands
|
||||
(map #(prepare-command identity current-chat-id %))
|
||||
(assoc db :new-commands))))
|
||||
|
||||
(defn add-message
|
||||
[{:keys [new-message current-chat-id] :as db}]
|
||||
(if new-message
|
||||
(add-message-to-db db current-chat-id new-message)
|
||||
db))
|
||||
|
||||
(defn add-commands
|
||||
[{:keys [new-commands current-chat-id] :as db}]
|
||||
(reduce
|
||||
#(add-message-to-db %1 current-chat-id %2)
|
||||
db
|
||||
new-commands))
|
||||
|
||||
(defn clear-input
|
||||
[{:keys [current-chat-id new-message] :as db} _]
|
||||
(if new-message
|
||||
(assoc-in db [:chats current-chat-id :input-text] nil)
|
||||
db))
|
||||
|
||||
(defn clear-staged-commands
|
||||
[{:keys [current-chat-id] :as db} _]
|
||||
(assoc-in db [:chats current-chat-id :staged-commands] []))
|
||||
|
||||
(defn send-message!
|
||||
[{:keys [new-message current-chat-id]} _]
|
||||
(when (and new-message (not-console? current-chat-id))
|
||||
(api/send-user-msg {:to current-chat-id
|
||||
:content (:content new-message)})))
|
||||
|
||||
(defn save-message-to-realm!
|
||||
[{:keys [new-message current-chat-id]} _]
|
||||
(when new-message
|
||||
(save-message current-chat-id new-message)))
|
||||
|
||||
(defn save-commands-to-realm!
|
||||
[{:keys [new-commands current-chat-id]} _]
|
||||
(doseq [new-command new-commands]
|
||||
(save-message current-chat-id (dissoc new-command :handler))))
|
||||
|
||||
(defn handle-commands
|
||||
[{:keys [new-commands]}]
|
||||
(println new-commands)
|
||||
(doseq [{{content :content} :content
|
||||
handler :handler} new-commands]
|
||||
(when handler
|
||||
(handler content))))
|
||||
|
||||
(register-handler :send-chat-msg
|
||||
(fn [db [action chat-id text]]
|
||||
(log/debug action "chat-id" chat-id "text" text)
|
||||
(if-let [command (get-command db text)]
|
||||
(do (dispatch [:set-chat-command (:command command)])
|
||||
db)
|
||||
(let [msg (when (pos? (count text))
|
||||
(if (= chat-id "console")
|
||||
(sign-up-service/send-console-msg text)
|
||||
(let [{msg-id :msg-id
|
||||
{from :from
|
||||
to :to} :msg} (api/send-user-msg {:to chat-id
|
||||
:content text})]
|
||||
{:msg-id msg-id
|
||||
:from from
|
||||
:to to
|
||||
:content text
|
||||
:content-type text-content-type
|
||||
:outgoing true})))]
|
||||
(when msg
|
||||
(save-message chat-id msg))
|
||||
(-> db
|
||||
(send-staged-commands chat-id)
|
||||
(apply-staged-commands)
|
||||
(signal-chat-updated chat-id))))))
|
||||
(-> prepare-message
|
||||
((enrich prepare-staged-commans))
|
||||
((enrich add-message))
|
||||
((enrich add-commands))
|
||||
((enrich clear-input))
|
||||
((enrich clear-staged-commands))
|
||||
((after (fn [_ _] (r/dismiss-keyboard!))))
|
||||
((after send-message!))
|
||||
((after save-message-to-realm!))
|
||||
((after save-commands-to-realm!))
|
||||
((after handle-commands))))
|
||||
|
||||
(register-handler :leave-group-chat
|
||||
(fn [db [action navigator]]
|
||||
|
@ -312,28 +401,6 @@
|
|||
(left-chat-msg chat-id)
|
||||
(signal-chat-updated db chat-id))))
|
||||
|
||||
(register-handler :send-chat-command
|
||||
(fn [db [action chat-id command content]]
|
||||
(log/debug action "chat-id" chat-id "command" command "content" content)
|
||||
(let [db (set-chat-input-text db nil)
|
||||
msg (if (= chat-id "console")
|
||||
(sign-up-service/send-console-command db command content)
|
||||
;; TODO handle command, now sends as plain message
|
||||
(let [{msg-id :msg-id
|
||||
{from :from
|
||||
to :to} :msg} (api/send-user-msg {:to chat-id
|
||||
:content content})]
|
||||
{:msg-id msg-id
|
||||
:from from
|
||||
:to to
|
||||
:content content
|
||||
:content-type text-content-type
|
||||
:outgoing true}))]
|
||||
(save-message chat-id msg)
|
||||
(-> db
|
||||
(handle-command command content)
|
||||
(signal-chat-updated chat-id)))))
|
||||
|
||||
(register-handler :send-group-chat-msg
|
||||
(fn [db [action chat-id text]]
|
||||
(log/debug action "chat-id" chat-id "text" text)
|
||||
|
@ -363,12 +430,13 @@
|
|||
;; -- Sign up --------------------------------------------------------------
|
||||
|
||||
(register-handler :sign-up
|
||||
(fn [db [_ phone-number handler]]
|
||||
(server/sign-up db phone-number handler)))
|
||||
(-> (fn [db [_ phone-number]]
|
||||
(assoc db :user-phone-number phone-number))
|
||||
((after (fn [& _] (sign-up-service/on-sign-up-response))))))
|
||||
|
||||
(register-handler :sign-up-confirm
|
||||
(fn [db [_ confirmation-code handler]]
|
||||
(server/sign-up-confirm confirmation-code handler)
|
||||
(fn [db [_ confirmation-code]]
|
||||
(sign-up-service/on-send-code-response confirmation-code)
|
||||
db))
|
||||
|
||||
(register-handler :sync-contacts
|
||||
|
@ -401,29 +469,33 @@
|
|||
|
||||
;; -- Chat --------------------------------------------------------------
|
||||
|
||||
(defn update-text [db [_ text]]
|
||||
(set-chat-input-text db text))
|
||||
|
||||
(defn update-command [db [_ text]]
|
||||
(let [{:keys [command]} (check-suggestion db text)]
|
||||
(set-chat-command db command)))
|
||||
|
||||
(register-handler :set-chat-input-text
|
||||
(fn [db [_ text]]
|
||||
(let [{:keys [command]} (check-suggestion db text)]
|
||||
(-> db
|
||||
(set-chat-input-text text)
|
||||
(set-chat-command command)))))
|
||||
((enrich update-command) update-text))
|
||||
|
||||
(register-handler :set-chat-command
|
||||
(fn [db [_ command-key]]
|
||||
;; todo what is going on there?!
|
||||
(set-chat-command db command-key)))
|
||||
|
||||
(register-handler :stage-command
|
||||
(fn [db [action chat-id command content]]
|
||||
(log/debug action "chat-id" chat-id "command" command "content" content)
|
||||
(fn [{:keys [current-chat-id] :as db} _]
|
||||
(let [db (set-chat-input-text db nil)
|
||||
{:keys [command content]}
|
||||
(get-in db [:chats current-chat-id :command-input])
|
||||
command-info {:command command
|
||||
:content content
|
||||
:handler (get-command-handler db (:command command) content)}]
|
||||
:handler (:handler command)}]
|
||||
(stage-command db command-info))))
|
||||
|
||||
(register-handler :unstage-command
|
||||
(fn [db [action chat-id staged-command]]
|
||||
(log/debug action "chat-id" chat-id "staged-command" staged-command)
|
||||
(fn [db [_ staged-command]]
|
||||
(let []
|
||||
(unstage-command db staged-command))))
|
||||
|
||||
|
@ -441,7 +513,6 @@
|
|||
|
||||
(register-handler :show-contacts
|
||||
(fn [db [action navigator]]
|
||||
(log/debug action)
|
||||
(nav-push navigator {:view-id :contact-list})
|
||||
db))
|
||||
|
||||
|
@ -512,6 +583,76 @@
|
|||
(re-join-group-chat db group-id identities group-name)
|
||||
(create-chat db group-id identities true group-name))))
|
||||
|
||||
(comment
|
||||
(dispatch [:set-signed-up true])
|
||||
)
|
||||
(register-handler :navigate-to
|
||||
(fn [db [_ view-id]]
|
||||
(-> db
|
||||
(assoc :view-id view-id)
|
||||
(update :navigation-stack conj view-id))))
|
||||
|
||||
(register-handler :navigate-back
|
||||
(fn [{:keys [navigation-stack] :as db} _]
|
||||
(log/debug :navigate-back)
|
||||
(if (>= 1 (count navigation-stack))
|
||||
db
|
||||
(let [[view-id :as navigation-stack'] (pop navigation-stack)]
|
||||
(-> db
|
||||
(assoc :view-id view-id)
|
||||
(assoc :navigation-stack navigation-stack'))))))
|
||||
|
||||
(register-handler :load-more-messages
|
||||
(fn [db _]
|
||||
db
|
||||
;; TODO implement
|
||||
#_(let [chat-id (get-in db [:chat :current-chat-id])
|
||||
messages [:chats chat-id :messages]
|
||||
new-messages (gen-messages 10)]
|
||||
(update-in db messages concat new-messages))))
|
||||
|
||||
(defn load-messages!
|
||||
[db _]
|
||||
db
|
||||
(->> (current-chat-id db)
|
||||
get-messages
|
||||
(assoc db :messages)))
|
||||
|
||||
(defn init-chat
|
||||
[{:keys [messages] :as db} _]
|
||||
(let [id (current-chat-id db)]
|
||||
(assoc-in db [:chats id :messages] messages)))
|
||||
|
||||
(register-handler :init-chat
|
||||
(-> load-messages!
|
||||
((enrich init-chat))
|
||||
debug))
|
||||
|
||||
(defn initialize-chats
|
||||
[{:keys [loaded-chats] :as db} _]
|
||||
(let [chats (->> loaded-chats
|
||||
(map (fn [{:keys [chat-id] :as chat}]
|
||||
[chat-id chat]))
|
||||
(into {}))]
|
||||
(-> db
|
||||
(assoc :chats chats)
|
||||
(dissoc :loaded-chats))))
|
||||
|
||||
(defn load-chats!
|
||||
[db _]
|
||||
(assoc db :loaded-chats (chats/chats-list)))
|
||||
|
||||
(register-handler :initialize-chats
|
||||
((enrich initialize-chats) load-chats!))
|
||||
|
||||
(defn safe-trim [s]
|
||||
(when (string? s)
|
||||
(str/trim s)))
|
||||
|
||||
(register-handler :cancel-command
|
||||
(fn [{:keys [current-chat-id] :as db} _]
|
||||
(-> db
|
||||
(assoc-in [:chats current-chat-id :command-input] {})
|
||||
(update-in [:chats current-chat-id :input-text] safe-trim))))
|
||||
|
||||
(register-handler :save-password
|
||||
(fn [db [_ password]]
|
||||
(sign-up-service/save-password password)
|
||||
(assoc db :password-saved true)))
|
||||
|
|
|
@ -2,16 +2,15 @@
|
|||
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||
[syng-im.persistence.simple-kv-store :as kv]
|
||||
[syng-im.protocol.state.storage :as s]
|
||||
[syng-im.db :as db]
|
||||
[syng-im.models.chat :refer [set-current-chat-id]]
|
||||
[syng-im.models.commands :as commands]
|
||||
[syng-im.models.chats :as c]
|
||||
[syng-im.utils.utils :refer [log on-error http-post toast]]
|
||||
[syng-im.utils.logging :as log]
|
||||
[syng-im.utils.random :as random]
|
||||
[syng-im.utils.phone-number :refer [format-phone-number]]
|
||||
[syng-im.constants :refer [text-content-type
|
||||
content-type-command
|
||||
content-type-command-request]]))
|
||||
content-type-command-request
|
||||
content-type-status]]))
|
||||
|
||||
(defn send-console-msg [text]
|
||||
{:msg-id (random/id)
|
||||
|
@ -29,174 +28,173 @@
|
|||
;; -- Send confirmation code and synchronize contacts---------------------------
|
||||
(defn on-sync-contacts []
|
||||
(dispatch [:received-msg
|
||||
{:msg-id (random/id)
|
||||
:content (str "Your contacts have been synchronized")
|
||||
{:msg-id (random/id)
|
||||
:content (str "Your contacts have been synchronized")
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
(dispatch [:set-signed-up true]))
|
||||
|
||||
(defn sync-contacts []
|
||||
(dispatch [:sync-contacts on-sync-contacts]))
|
||||
|
||||
(defn on-send-code-response [msg-id body]
|
||||
(if (:confirmed body)
|
||||
(do (dispatch [:set-chat-command-request msg-id nil])
|
||||
(dispatch [:received-msg
|
||||
{:msg-id (random/id)
|
||||
:content "Confirmed"
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
(sync-contacts))
|
||||
(dispatch [:received-msg
|
||||
{:msg-id (random/id)
|
||||
:content "Wrong code"
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])))
|
||||
(defn on-send-code-response [body]
|
||||
(dispatch [:received-msg
|
||||
{:msg-id (random/id)
|
||||
;; todo replace by real check
|
||||
:content (if (= "1111" body)
|
||||
"Confirmed"
|
||||
"Wrong code")
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}]))
|
||||
|
||||
(defn send-code [msg-id code]
|
||||
(dispatch [:sign-up-confirm code (partial on-send-code-response msg-id)]))
|
||||
|
||||
(defn- handle-confirmation-code [msg-id command-key content]
|
||||
(when (= command-key :confirmation-code)
|
||||
(send-code msg-id content)))
|
||||
; todo fn name is not too smart, but...
|
||||
(defn command-content
|
||||
[command content]
|
||||
{:command (name command)
|
||||
:content content})
|
||||
|
||||
;; -- Send phone number ----------------------------------------
|
||||
(defn on-sign-up-response []
|
||||
(let [msg-id (random/id)]
|
||||
(dispatch [:received-msg
|
||||
{:msg-id msg-id
|
||||
:content (commands/format-command-request-msg-content
|
||||
:confirmation-code
|
||||
(str "Thanks! We've sent you a text message with a confirmation "
|
||||
"code. Please provide that code to confirm your phone number"))
|
||||
{:msg-id msg-id
|
||||
:content (command-content
|
||||
:confirmation-code
|
||||
(str "Thanks! We've sent you a text message with a confirmation "
|
||||
"code. Please provide that code to confirm your phone number"))
|
||||
:content-type content-type-command-request
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
(dispatch [:set-chat-command-request msg-id handle-confirmation-code])))
|
||||
|
||||
(defn- handle-phone [msg-id command-key content]
|
||||
(dispatch [:set-chat-command-request msg-id nil])
|
||||
(when (= command-key :phone)
|
||||
(let [phone-number (format-phone-number content)]
|
||||
(dispatch [:sign-up phone-number on-sign-up-response]))))
|
||||
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])))
|
||||
|
||||
;; -- Saving password ----------------------------------------
|
||||
(defn- save-password [password]
|
||||
(defn save-password [password]
|
||||
;; TODO validate and save password
|
||||
(dispatch [:received-msg
|
||||
{:msg-id (random/id)
|
||||
:content (str "OK great! Your password has been saved. Just to let you "
|
||||
"know, you can always change it in the Console, by the way, "
|
||||
"it's me, the Console, nice to meet you!")
|
||||
{:msg-id (random/id)
|
||||
:content (str "OK great! Your password has been saved. Just to let you "
|
||||
"know you can always change it in the Console by the way "
|
||||
"it's me the Console nice to meet you!")
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
(dispatch [:received-msg
|
||||
{:msg-id (random/id)
|
||||
:content (str "I'll generate a passphrase for you so you can restore your "
|
||||
"access or log in from another device")
|
||||
{:msg-id (random/id)
|
||||
:content (str "I'll generate a passphrase for you so you can restore your "
|
||||
"access or log in from another device")
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
(dispatch [:received-msg
|
||||
{:msg-id (random/id)
|
||||
:content "Here's your passphrase:"
|
||||
{:msg-id (random/id)
|
||||
:content "Here's your passphrase:"
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
;; TODO generate passphrase
|
||||
(let [passphrase (str "The brash businessman's braggadocio and public squabbing with "
|
||||
"candidates in the US presidential election")]
|
||||
(dispatch [:received-msg
|
||||
{:msg-id (random/id)
|
||||
:content passphrase
|
||||
{:msg-id (random/id)
|
||||
:content passphrase
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}]))
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}]))
|
||||
(dispatch [:received-msg
|
||||
{:msg-id "8"
|
||||
:content "Make sure you had securely written it down"
|
||||
{:msg-id "8"
|
||||
:content "Make sure you had securely written it down"
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
;; TODO highlight '!phone'
|
||||
(let [msg-id (random/id)]
|
||||
(dispatch [:received-msg
|
||||
{:msg-id msg-id
|
||||
:content (commands/format-command-request-msg-content
|
||||
:phone
|
||||
(str "Your phone number is also required to use the app. Type the "
|
||||
"exclamation mark or hit the icon to open the command list "
|
||||
"and choose the !phone command"))
|
||||
:content-type content-type-command-request
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
(dispatch [:set-chat-command-request msg-id handle-phone])))
|
||||
{:msg-id msg-id
|
||||
:content (command-content
|
||||
:phone
|
||||
(str "Your phone number is also required to use the app. Type the "
|
||||
"exclamation mark or hit the icon to open the command list "
|
||||
"and choose the !phone command"))
|
||||
:content-type content-type-command-request
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])))
|
||||
|
||||
(defn- handle-password [msg-id command-key content]
|
||||
(dispatch [:set-chat-command-request msg-id nil])
|
||||
(when (= command-key :keypair-password)
|
||||
(save-password content)))
|
||||
(def intro-status
|
||||
{:msg-id "intro-status"
|
||||
:content (str "The brash businessman’s braggadocio "
|
||||
"and public exchange with candidates "
|
||||
"in the US presidential election")
|
||||
:delivery-status "seen"
|
||||
:from "console"
|
||||
:chat-id "console"
|
||||
:content-type content-type-status
|
||||
:outgoing false
|
||||
:to "me"})
|
||||
|
||||
(defn intro [db]
|
||||
(dispatch [:received-msg intro-status])
|
||||
(dispatch [:received-msg
|
||||
{:msg-id "intro-message1"
|
||||
:content "Hello there! It's Syng, a Dapp browser in your phone."
|
||||
{:msg-id "intro-message1"
|
||||
:content "Hello there! It's Syng a Dapp browser in your phone."
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
(dispatch [:received-msg
|
||||
{:msg-id "intro-message2"
|
||||
:content (str "Syng uses a highly secure key-pair authentication type "
|
||||
"to provide you a reliable way to access your account")
|
||||
{:msg-id "intro-message2"
|
||||
:content (str "Syng uses a highly secure key-pair authentication type "
|
||||
"to provide you a reliable way to access your account")
|
||||
:content-type text-content-type
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
(let [msg-id "into-message3"]
|
||||
(dispatch [:received-msg
|
||||
{:msg-id msg-id
|
||||
:content (commands/format-command-request-msg-content
|
||||
:keypair-password
|
||||
(str "A key pair has been generated and saved to your device. "
|
||||
"Create a password to secure your key"))
|
||||
{:msg-id msg-id
|
||||
:content (command-content
|
||||
:keypair-password
|
||||
(str "A key pair has been generated and saved to your device. "
|
||||
"Create a password to secure your key"))
|
||||
:content-type content-type-command-request
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}])
|
||||
(dispatch [:set-chat-command-request msg-id handle-password]))
|
||||
;; (dispatch [:set-chat-command :keypair-password])
|
||||
:outgoing false
|
||||
:from "console"
|
||||
:to "me"}]))
|
||||
db)
|
||||
|
||||
;; TODO store command key in a separate field
|
||||
(defn send-console-command [db command-key content]
|
||||
{:msg-id (random/id)
|
||||
:from "me"
|
||||
:to "console"
|
||||
:content content ;; (commands/format-command-msg-content command-key content)
|
||||
:content-type content-type-command
|
||||
:outgoing true})
|
||||
(def console-chat
|
||||
{:chat-id "console"
|
||||
:name "console"
|
||||
:group-chat false
|
||||
:is-active true
|
||||
:timestamp (.getTime (js/Date.))
|
||||
:contacts [{:identity "console"
|
||||
:text-color "#FFFFFF"
|
||||
:background-color "#AB7967"}]})
|
||||
|
||||
(defn init [db]
|
||||
(let [signed-up (s/get kv/kv-store :signed-up)
|
||||
db (if signed-up
|
||||
db
|
||||
(-> db
|
||||
(set-current-chat-id "console")
|
||||
intro))]
|
||||
(assoc db :signed-up signed-up)))
|
||||
(defn create-chat [handler]
|
||||
(fn [db]
|
||||
(let [{:keys [new-chat] :as db'} (handler db)]
|
||||
(when new-chat
|
||||
(c/create-chat new-chat))
|
||||
(dissoc db' :new-chat))))
|
||||
|
||||
(def init
|
||||
(create-chat
|
||||
(fn [{:keys [chats] :as db}]
|
||||
(if (chats "console")
|
||||
db
|
||||
(-> db
|
||||
(assoc-in [:chats "console"] console-chat)
|
||||
(assoc :new-chat console-chat)
|
||||
(set-current-chat-id "console")
|
||||
(intro))))))
|
||||
|
|
|
@ -50,6 +50,9 @@
|
|||
:outgoing false}))
|
||||
|
||||
(defn create-chat
|
||||
([{:keys [last-msg-id] :as chat}]
|
||||
(let [chat (assoc chat :last-msg-id (or last-msg-id ""))]
|
||||
(r/write #(r/create :chats chat))))
|
||||
([db chat-id identities group-chat?]
|
||||
(create-chat db chat-id identities group-chat? nil))
|
||||
([db chat-id identities group-chat? chat-name]
|
||||
|
@ -96,14 +99,26 @@
|
|||
(-> (signal-chats-updated db)
|
||||
(signal-chat-updated group-id)))
|
||||
|
||||
(defn normalize-contacts
|
||||
[chats]
|
||||
(map #(update % :contacts vals) chats))
|
||||
|
||||
(defn chats-list []
|
||||
(r/sorted (r/get-all :chats) :timestamp :desc))
|
||||
(-> (r/get-all :chats)
|
||||
(r/sorted :timestamp :desc)
|
||||
r/collection->map
|
||||
normalize-contacts))
|
||||
|
||||
(defn chat-by-id [chat-id]
|
||||
(-> (r/get-by-field :chats :chat-id chat-id)
|
||||
(r/single-cljs)
|
||||
(r/list-to-array :contacts)))
|
||||
|
||||
(defn chat-by-id2 [chat-id]
|
||||
(-> (r/get-by-field :chats :chat-id chat-id)
|
||||
r/collection->map
|
||||
first))
|
||||
|
||||
(defn chat-add-participants [chat-id identities]
|
||||
(r/write
|
||||
(fn []
|
||||
|
@ -136,42 +151,3 @@
|
|||
(-> (r/get-by-field :chats :chat-id chat-id)
|
||||
(r/single)
|
||||
(aset "is-active" active?)))))
|
||||
|
||||
(comment
|
||||
(active-group-chats)
|
||||
|
||||
|
||||
(-> (r/get-by-field :chats :chat-id "0x04ed4c3797026cddeb7d64a54ca58142e57ea03cda21072358d67455b506db90c56d95033e3d221992f70d01922c3d90bf0697c49e4be118443d03ae4a1cd3c15c")
|
||||
(r/single)
|
||||
(aget "contacts")
|
||||
(.map (fn [object index collection]
|
||||
object)))
|
||||
|
||||
(-> (chat-by-id "0x04ed4c3797026cddeb7d64a54ca58142e57ea03cda21072358d67455b506db90c56d95033e3d221992f70d01922c3d90bf0697c49e4be118443d03ae4a1cd3c15c")
|
||||
:contacts
|
||||
vals
|
||||
vec)
|
||||
|
||||
|
||||
(-> (aget (aget (chats-list) 0) "contacts")
|
||||
(r/cljs-list))
|
||||
|
||||
(r/write (fn [] (r/delete (chats-list))))
|
||||
|
||||
(swap! re-frame.db/app-db signal-chats-updated)
|
||||
|
||||
(create-chat "0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd"
|
||||
["0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd"])
|
||||
|
||||
(+ 1 1)
|
||||
|
||||
|
||||
|
||||
(swap! re-frame.db/app-db (fn [db]
|
||||
(create-chat db "A group chat")))
|
||||
|
||||
|
||||
(-> (chats-list)
|
||||
(.find (fn [object index collection]
|
||||
(= "console1" (aget object "chat-id")))))
|
||||
)
|
||||
|
|
|
@ -4,63 +4,63 @@
|
|||
[cljs.core.async :as async :refer [chan put! <! >!]]
|
||||
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
||||
[syng-im.db :as db]
|
||||
[syng-im.resources :as res]
|
||||
[syng-im.models.chat :refer [current-chat-id]]
|
||||
[syng-im.components.styles :refer [color-blue
|
||||
color-dark-mint]]
|
||||
[syng-im.utils.utils :refer [log toast]]
|
||||
[syng-im.utils.logging :as log]
|
||||
[syng-im.persistence.realm :as realm]))
|
||||
[syng-im.utils.utils :refer [log toast]]))
|
||||
|
||||
;; todo delete
|
||||
(def commands [{:command :money
|
||||
:text "!money"
|
||||
:description "Send money"
|
||||
:color color-dark-mint
|
||||
(def commands [{:command :money
|
||||
:text "!money"
|
||||
:description "Send money"
|
||||
:color color-dark-mint
|
||||
:request-icon {:uri "icon_lock_white"}
|
||||
:icon {:uri "icon_lock_gray"}
|
||||
:suggestion true}
|
||||
{:command :location
|
||||
:text "!location"
|
||||
:icon {:uri "icon_lock_gray"}
|
||||
:suggestion true}
|
||||
{:command :location
|
||||
:text "!location"
|
||||
:description "Send location"
|
||||
:color "#9a5dcf"
|
||||
:suggestion true}
|
||||
{:command :phone
|
||||
:text "!phone"
|
||||
:description "Send phone number"
|
||||
:color "#9a5dcf"
|
||||
:suggestion true}
|
||||
{:command :phone
|
||||
:text "!phone"
|
||||
:description "Send phone number"
|
||||
:color color-dark-mint
|
||||
:request-text "Phone number request"
|
||||
:color color-dark-mint
|
||||
:suggestion true}
|
||||
{:command :confirmation-code
|
||||
:text "!confirmationCode"
|
||||
:description "Send confirmation code"
|
||||
:suggestion true
|
||||
:handler #(dispatch [:sign-up %])}
|
||||
{:command :confirmation-code
|
||||
:text "!confirmationCode"
|
||||
:description "Send confirmation code"
|
||||
:request-text "Confirmation code request"
|
||||
:color color-blue
|
||||
:color color-blue
|
||||
:request-icon {:uri "icon_lock_white"}
|
||||
:icon {:uri "icon_lock_gray"}
|
||||
:suggestion true}
|
||||
{:command :send
|
||||
:text "!send"
|
||||
:icon {:uri "icon_lock_gray"}
|
||||
:suggestion true
|
||||
:handler #(dispatch [:sign-up-confirm %])}
|
||||
{:command :send
|
||||
:text "!send"
|
||||
:description "Send location"
|
||||
:color "#9a5dcf"
|
||||
:suggestion true}
|
||||
{:command :request
|
||||
:text "!request"
|
||||
:color "#9a5dcf"
|
||||
:suggestion true}
|
||||
{:command :request
|
||||
:text "!request"
|
||||
:description "Send request"
|
||||
:color "#48ba30"
|
||||
:suggestion true}
|
||||
{:command :keypair-password
|
||||
:text "!keypairPassword"
|
||||
:description ""
|
||||
:color color-blue
|
||||
:color "#48ba30"
|
||||
:suggestion true}
|
||||
{:command :keypair-password
|
||||
:text "!keypairPassword"
|
||||
:description ""
|
||||
:color color-blue
|
||||
:request-icon {:uri "icon_lock_white"}
|
||||
:icon {:uri "icon_lock_gray"}
|
||||
:suggestion false}
|
||||
{:command :help
|
||||
:text "!help"
|
||||
:icon {:uri "icon_lock_gray"}
|
||||
:suggestion false
|
||||
:handler #(dispatch [:save-password %])}
|
||||
{:command :help
|
||||
:text "!help"
|
||||
:description "Help"
|
||||
:color "#9a5dcf"
|
||||
:suggestion true}])
|
||||
:color "#9a5dcf"
|
||||
:suggestion true}])
|
||||
|
||||
(defn get-commands [db]
|
||||
;; todo: temp. must be '(get db :commands)'
|
||||
|
@ -83,19 +83,20 @@
|
|||
(get-in db (db/chat-command-content-path (current-chat-id db))))
|
||||
|
||||
(defn set-chat-command-content [db content]
|
||||
(assoc-in db (db/chat-command-content-path (get-in db db/current-chat-id-path))
|
||||
(assoc-in db
|
||||
[:chats (get-in db db/current-chat-id-path) :command-input :content]
|
||||
content))
|
||||
|
||||
(defn get-chat-command [db]
|
||||
(get-in db (db/chat-command-path (current-chat-id db))))
|
||||
|
||||
(defn set-response-chat-command [db msg-id command-key]
|
||||
(-> db
|
||||
(set-chat-command-content nil)
|
||||
(assoc-in (db/chat-command-path (current-chat-id db))
|
||||
(get-command db command-key))
|
||||
(assoc-in (db/chat-command-to-msg-id-path (current-chat-id db))
|
||||
msg-id)))
|
||||
(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-chat-command [db command-key]
|
||||
(set-response-chat-command db nil command-key))
|
||||
|
@ -124,31 +125,10 @@
|
|||
|
||||
(defn set-chat-command-request [db msg-id handler]
|
||||
(update-in db (db/chat-command-requests-path (current-chat-id db))
|
||||
(fn [requests]
|
||||
(if requests
|
||||
(assoc requests msg-id handler)
|
||||
{msg-id handler}))))
|
||||
|
||||
|
||||
(defn- map-to-str
|
||||
[m]
|
||||
(join ";" (map #(join "=" %) (stringify-keys m))))
|
||||
|
||||
(defn- str-to-map
|
||||
[s]
|
||||
(keywordize-keys (apply hash-map (split s #"[;=]"))))
|
||||
|
||||
;; TODO store command key in separate field
|
||||
(defn format-command-msg-content [command content]
|
||||
(map-to-str {:command (name command) :content content}))
|
||||
#(assoc % msg-id handler)))
|
||||
|
||||
(defn parse-command-msg-content [commands content]
|
||||
(log/info content)
|
||||
(log/info (update (str-to-map content) :command #(find-command commands (keyword %))))
|
||||
(update (str-to-map content) :command #(find-command commands (keyword %))))
|
||||
|
||||
(defn format-command-request-msg-content [command content]
|
||||
(map-to-str {:command (name command) :content content}))
|
||||
(update content :command #(find-command commands (keyword %))))
|
||||
|
||||
(defn parse-command-request-msg-content [commands content]
|
||||
(update (str-to-map content) :command #(find-command commands (keyword %))))
|
||||
(update content :command #(find-command commands (keyword %))))
|
||||
|
|
|
@ -3,41 +3,57 @@
|
|||
[cljs.reader :refer [read-string]]
|
||||
[syng-im.utils.random :refer [timestamp]]
|
||||
[syng-im.db :as db]
|
||||
[syng-im.utils.logging :as log]))
|
||||
[syng-im.utils.logging :as log]
|
||||
[clojure.string :refer [join split]]
|
||||
[clojure.walk :refer [stringify-keys keywordize-keys]]
|
||||
[syng-im.constants :as c]))
|
||||
|
||||
(defn- map-to-str
|
||||
[m]
|
||||
(join ";" (map #(join "=" %) (stringify-keys m))))
|
||||
|
||||
(defn- str-to-map
|
||||
[s]
|
||||
(keywordize-keys (apply hash-map (split s #"[;=]"))))
|
||||
|
||||
(defn select-chat-last-message [chat]
|
||||
(when-let [last-msg-id (:last-msg-id chat)]
|
||||
(r/single-cljs (r/get-by-field :msgs :msg-id last-msg-id))))
|
||||
|
||||
(defn save-message [chat-id {:keys [from to msg-id content content-type outgoing] :or {outgoing false
|
||||
to nil} :as msg}]
|
||||
(defn save-message
|
||||
[chat-id {:keys [from to msg-id content content-type outgoing
|
||||
same-author same-direction]
|
||||
:or {outgoing false
|
||||
to nil} :as msg}]
|
||||
(log/debug "save-message" chat-id msg)
|
||||
(when-not (r/exists? :msgs :msg-id msg-id)
|
||||
(r/write
|
||||
(fn []
|
||||
(let [chat (r/single-cljs (r/get-by-field :chats :chat-id chat-id))
|
||||
last-message (select-chat-last-message chat)]
|
||||
(r/create :msgs {:chat-id chat-id
|
||||
:msg-id msg-id
|
||||
:from from
|
||||
:to to
|
||||
:content content
|
||||
:content-type content-type
|
||||
:outgoing outgoing
|
||||
:timestamp (timestamp)
|
||||
:delivery-status nil
|
||||
:same-author (if last-message
|
||||
(= (:from last-message) from)
|
||||
true)
|
||||
:same-direction (if last-message
|
||||
(= (:outgoing last-message) outgoing)
|
||||
true)} true)
|
||||
(r/create :chats {:chat-id (:chat-id chat)
|
||||
:last-msg-id msg-id}
|
||||
true))))))
|
||||
(fn []
|
||||
(let [content (if (string? content)
|
||||
content
|
||||
(map-to-str content))]
|
||||
(r/create :msgs {:chat-id chat-id
|
||||
:msg-id msg-id
|
||||
:from from
|
||||
:to to
|
||||
:content content
|
||||
:content-type content-type
|
||||
:outgoing outgoing
|
||||
:timestamp (timestamp)
|
||||
:delivery-status nil
|
||||
:same-author same-author
|
||||
:same-direction same-direction} true))))))
|
||||
|
||||
(defn get-messages [chat-id]
|
||||
(r/sorted (r/get-by-field :msgs :chat-id chat-id) :timestamp :desc))
|
||||
(->> (-> (r/get-by-field :msgs :chat-id chat-id)
|
||||
(r/sorted :timestamp :asc)
|
||||
(r/collection->map))
|
||||
(into '())
|
||||
(map (fn [{:keys [content-type] :as message}]
|
||||
(if (#{c/content-type-command c/content-type-command-request}
|
||||
content-type)
|
||||
(update message :content str-to-map)
|
||||
message)))))
|
||||
|
||||
(defn message-by-id [msg-id]
|
||||
(r/single-cljs (r/get-by-field :msgs :msg-id msg-id)))
|
||||
|
@ -48,27 +64,3 @@
|
|||
(fn []
|
||||
(when (r/exists? :msgs :msg-id msg-id)
|
||||
(r/create :msgs msg true)))))
|
||||
|
||||
(comment
|
||||
|
||||
(update-message! {:msg-id "1459175391577-a2185a35-5c49-5a6b-9c08-6eb5b87ceb7f"
|
||||
:delivery-status "seen2"})
|
||||
|
||||
(r/get-by-field :msgs :msg-id "1459175391577-a2185a35-5c49-5a6b-9c08-6eb5b87ceb7f")
|
||||
|
||||
|
||||
(save-message "0x040028c500ff086ecf1cfbb3c1a7240179cde5b86f9802e6799b9bbe9cdd7ad1b05ae8807fa1f9ed19cc8ce930fc2e878738c59f030a6a2f94b3522dc1378ff154"
|
||||
{:msg-id "153"
|
||||
:content "hello!"
|
||||
:content-type "text/plain"})
|
||||
|
||||
(get-messages* "0x040028c500ff086ecf1cfbb3c1a7240179cde5b86f9802e6799b9bbe9cdd7ad1b05ae8807fa1f9ed19cc8ce930fc2e878738c59f030a6a2f94b3522dc1378ff154")
|
||||
|
||||
(get-messages "0x0479a5ed1f38cadfad1db6cd56c4b659b0ebe052bbe9efa950f6660058519fa4ca6be2dda66afa80de96ab00eb97a2605d5267a1e8f4c2a166ab551f6826608cdd")
|
||||
|
||||
(doseq [msg (get-messages* "0x043df89d36f6e3d8ade18e55ac3e2e39406ebde152f76f2f82d674681d59319ffd9880eebfb4f5f8d5c222ec485b44d6e30ba3a03c96b1c946144fdeba1caccd43")]
|
||||
(r/delete msg))
|
||||
|
||||
@re-frame.db/app-db
|
||||
|
||||
)
|
||||
|
|
|
@ -131,7 +131,6 @@
|
|||
(defn get-list [schema-name]
|
||||
(vals (js->clj (.objects realm (to-string schema-name)) :keywordize-keys true)))
|
||||
|
||||
|
||||
(comment
|
||||
|
||||
)
|
||||
(defn collection->map [collection]
|
||||
(-> (.map collection (fn [object _ _] object))
|
||||
(js->clj :keywordize-keys true)))
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
get-chat-command
|
||||
get-chat-command-content
|
||||
get-chat-command-request
|
||||
parse-command-msg-content
|
||||
parse-command-request-msg-content]]
|
||||
[syng-im.handlers.suggestions :refer [get-suggestions]]))
|
||||
|
||||
|
@ -23,11 +22,8 @@
|
|||
|
||||
(register-sub :get-chat-messages
|
||||
(fn [db _]
|
||||
(let [chat-id (reaction (current-chat-id @db))
|
||||
chat-updated (reaction (chat-updated? @db @chat-id))]
|
||||
(reaction
|
||||
(let [_ @chat-updated]
|
||||
(get-messages @chat-id))))))
|
||||
(let [chat-id (current-chat-id @db)]
|
||||
(reaction (get-in @db [:chats chat-id :messages])))))
|
||||
|
||||
(register-sub :get-current-chat-id
|
||||
(fn [db _]
|
||||
|
@ -76,12 +72,8 @@
|
|||
|
||||
(register-sub :get-current-chat
|
||||
(fn [db _]
|
||||
(let [current-chat-id (reaction (current-chat-id @db))
|
||||
chat-updated (reaction (chat-updated? @db @current-chat-id))]
|
||||
(reaction
|
||||
(let [_ @chat-updated]
|
||||
(when-let [chat-id @current-chat-id]
|
||||
(chat-by-id chat-id)))))))
|
||||
(let [current-chat-id (current-chat-id @db)]
|
||||
(reaction (get-in @db [:chats current-chat-id])))))
|
||||
|
||||
;; -- User data --------------------------------------------------------------
|
||||
|
||||
|
@ -148,3 +140,29 @@
|
|||
:contacts
|
||||
(map :identity))]
|
||||
(contacts-list-include current-participants)))))))
|
||||
|
||||
(register-sub :view-id
|
||||
(fn [db _]
|
||||
(reaction (@db :view-id))))
|
||||
|
||||
(register-sub :chat
|
||||
(fn [db [_ k]]
|
||||
(-> @db
|
||||
(get-in [:chats (current-chat-id @db) k])
|
||||
(reaction))))
|
||||
|
||||
(register-sub :navigation-stack
|
||||
(fn [db _]
|
||||
(:navigation-stack @db)))
|
||||
|
||||
(register-sub :db
|
||||
(fn [db _] (reaction @db)))
|
||||
|
||||
(register-sub :chat-properties
|
||||
(fn [{:keys [current-chat-id] :as db} [_ properties]]
|
||||
(->> properties
|
||||
(map (fn [k]
|
||||
[k (-> @db
|
||||
(get-in [:cgats current-chat-id k])
|
||||
(reaction))]))
|
||||
(into {}))))
|
||||
|
|
|
@ -9,3 +9,11 @@
|
|||
(-> (cljs.core/clj->js {:rowHasChanged not=})
|
||||
(js/RealmReactNative.ListView.DataSource.)
|
||||
(clone-with-rows items)))
|
||||
|
||||
|
||||
(defn clone-with-rows2 [ds rows]
|
||||
(.cloneWithRows ds (reduce (fn [ac el] (.push ac el) ac)
|
||||
(clj->js []) rows)))
|
||||
|
||||
(defn to-datasource2 [items]
|
||||
(clone-with-rows2 (data-source {:rowHasChanged not=}) items))
|
||||
|
|
Loading…
Reference in New Issue