2016-03-25 14:29:38 +03:00
|
|
|
(ns syng-im.components.chat
|
2016-04-18 13:38:38 +03:00
|
|
|
(:require [clojure.string :as s]
|
|
|
|
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
|
2016-03-25 17:22:13 +03:00
|
|
|
[syng-im.components.react :refer [android?
|
|
|
|
view
|
|
|
|
text
|
|
|
|
image
|
|
|
|
navigator
|
2016-05-02 16:56:42 +03:00
|
|
|
touchable-highlight
|
2016-03-28 19:00:07 +03:00
|
|
|
toolbar-android]]
|
|
|
|
[syng-im.components.realm :refer [list-view]]
|
2016-04-18 13:38:38 +03:00
|
|
|
[syng-im.components.styles :refer [font
|
|
|
|
title-font
|
|
|
|
color-white
|
|
|
|
chat-background
|
|
|
|
online-color
|
2016-04-19 15:38:16 +03:00
|
|
|
selected-message-color
|
2016-05-02 16:56:42 +03:00
|
|
|
separator-color
|
2016-04-18 13:38:38 +03:00
|
|
|
text1-color
|
2016-05-03 16:58:37 +03:00
|
|
|
text2-color
|
|
|
|
toolbar-background1]]
|
2016-03-25 17:22:13 +03:00
|
|
|
[syng-im.utils.logging :as log]
|
|
|
|
[syng-im.navigation :refer [nav-pop]]
|
|
|
|
[syng-im.resources :as res]
|
2016-03-28 19:00:07 +03:00
|
|
|
[syng-im.utils.listview :refer [to-realm-datasource]]
|
2016-03-25 17:22:13 +03:00
|
|
|
[syng-im.components.invertible-scroll-view :refer [invertible-scroll-view]]
|
|
|
|
[reagent.core :as r]
|
2016-03-31 16:44:16 +03:00
|
|
|
[syng-im.components.chat.chat-message :refer [chat-message]]
|
|
|
|
[syng-im.components.chat.chat-message-new :refer [chat-message-new]]))
|
2016-03-25 13:36:16 +03:00
|
|
|
|
2016-03-25 14:29:38 +03:00
|
|
|
|
2016-04-06 16:13:31 +03:00
|
|
|
(defn contacts-by-identity [contacts]
|
|
|
|
(->> contacts
|
|
|
|
(map (fn [{:keys [identity] :as contact}]
|
|
|
|
[identity contact]))
|
|
|
|
(into {})))
|
|
|
|
|
|
|
|
(defn add-msg-color [{:keys [from] :as msg} contact-by-identity]
|
2016-04-07 14:01:41 +03:00
|
|
|
(if (= "system" from)
|
|
|
|
(assoc msg :text-color "#4A5258"
|
|
|
|
:background-color "#D3EEEF")
|
|
|
|
(let [{:keys [text-color background-color]} (get contact-by-identity from)]
|
|
|
|
(assoc msg :text-color text-color
|
|
|
|
:background-color background-color))))
|
2016-04-06 16:13:31 +03:00
|
|
|
|
2016-04-18 13:38:38 +03:00
|
|
|
(defn chat-photo [{:keys [photo-path]}]
|
2016-05-02 16:56:42 +03:00
|
|
|
[view {:margin 10
|
|
|
|
:borderRadius 50}
|
2016-04-18 13:38:38 +03:00
|
|
|
[image {:source (if (s/blank? photo-path)
|
|
|
|
res/user-no-photo
|
|
|
|
{:uri photo-path})
|
|
|
|
:style {:borderRadius 50
|
|
|
|
:width 36
|
|
|
|
:height 36}}]])
|
|
|
|
|
|
|
|
(defn contact-online [{:keys [online]}]
|
|
|
|
(when online
|
|
|
|
[view {:position "absolute"
|
2016-05-02 16:56:42 +03:00
|
|
|
:top 30
|
|
|
|
:left 30
|
2016-04-18 13:38:38 +03:00
|
|
|
:width 20
|
|
|
|
:height 20
|
|
|
|
:borderRadius 50
|
|
|
|
:backgroundColor online-color
|
|
|
|
:borderWidth 2
|
|
|
|
:borderColor color-white}
|
|
|
|
[view {:position "absolute"
|
|
|
|
:top 6
|
|
|
|
:left 3
|
|
|
|
:width 4
|
|
|
|
:height 4
|
|
|
|
:borderRadius 50
|
|
|
|
:backgroundColor color-white}]
|
|
|
|
[view {:position "absolute"
|
|
|
|
:top 6
|
|
|
|
:left 9
|
|
|
|
:width 4
|
|
|
|
:height 4
|
|
|
|
:borderRadius 50
|
|
|
|
:backgroundColor color-white}]]))
|
|
|
|
|
2016-04-19 15:38:16 +03:00
|
|
|
(defn typing [member]
|
|
|
|
[view {:style {:width 260
|
2016-04-29 15:43:36 +03:00
|
|
|
:marginTop 10
|
2016-04-19 15:38:16 +03:00
|
|
|
:paddingLeft 8
|
|
|
|
:paddingRight 8
|
|
|
|
:alignItems "flex-start"
|
|
|
|
:alignSelf "flex-start"}}
|
|
|
|
[view {:style {:borderRadius 14
|
|
|
|
:padding 12
|
|
|
|
:height 38
|
|
|
|
:backgroundColor selected-message-color}}
|
|
|
|
[text {:style {:marginTop -2
|
|
|
|
:fontSize 12
|
|
|
|
:fontFamily font
|
|
|
|
:color text2-color}}
|
|
|
|
(str member " is typing")]]])
|
|
|
|
|
|
|
|
(defn typing-all []
|
2016-04-29 15:43:36 +03:00
|
|
|
[view {:style {:marginBottom 20}}
|
2016-04-19 15:38:16 +03:00
|
|
|
(for [member ["Geoff" "Justas"]]
|
|
|
|
^{:key member} [typing member])])
|
|
|
|
|
2016-05-02 16:56:42 +03:00
|
|
|
(defn action-view [action]
|
2016-05-03 16:39:08 +03:00
|
|
|
[touchable-highlight {:on-press (fn []
|
|
|
|
(dispatch [:set-show-actions false])
|
|
|
|
((:handler action)))
|
2016-05-02 16:56:42 +03:00
|
|
|
:underlay-color :transparent}
|
|
|
|
[view {:style {:flexDirection "row"
|
|
|
|
:height 56}}
|
|
|
|
[view {:width 56
|
2016-05-03 16:39:08 +03:00
|
|
|
:height 56
|
|
|
|
:alignItems "center"
|
|
|
|
:justifyContent "center"}
|
2016-05-02 16:56:42 +03:00
|
|
|
[image {:source {:uri (:icon action)}
|
2016-05-03 16:39:08 +03:00
|
|
|
:style (:icon-style action)}]]
|
2016-04-19 15:38:16 +03:00
|
|
|
[view {:style {:flex 1
|
2016-05-02 16:56:42 +03:00
|
|
|
:alignItems "flex-start"
|
|
|
|
:justifyContent "center"}}
|
|
|
|
[text {:style {:marginTop -2.5
|
|
|
|
:color text1-color
|
|
|
|
:fontSize 14
|
|
|
|
:fontFamily font}}
|
|
|
|
(:title action)]
|
|
|
|
(when-let [subtitle (:subtitle action)]
|
|
|
|
[text {:style {:marginTop 1
|
|
|
|
:color text2-color
|
|
|
|
:fontSize 12
|
|
|
|
:fontFamily font}}
|
|
|
|
subtitle])]]])
|
|
|
|
|
2016-05-03 16:39:08 +03:00
|
|
|
(defn actions-list-view [navigator chat]
|
|
|
|
(when-let [actions (when (and (:group-chat chat)
|
|
|
|
(:is-active chat))
|
2016-05-02 16:56:42 +03:00
|
|
|
[{:title "Add Contact to chat"
|
2016-05-03 16:39:08 +03:00
|
|
|
:icon "icon_menu_group"
|
|
|
|
:icon-style {:width 25
|
|
|
|
:height 19}
|
2016-05-02 16:56:42 +03:00
|
|
|
:handler #(dispatch [:show-add-participants navigator])}
|
|
|
|
{:title "Remove Contact from chat"
|
|
|
|
:subtitle "Alex, John"
|
2016-05-03 16:39:08 +03:00
|
|
|
:icon "icon_search_gray_copy"
|
|
|
|
:icon-style {:width 17
|
|
|
|
:height 17}
|
2016-05-02 16:56:42 +03:00
|
|
|
:handler #(dispatch [:show-remove-participants navigator])}
|
|
|
|
{:title "Leave Chat"
|
2016-05-03 16:39:08 +03:00
|
|
|
: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 [] )}])]
|
2016-05-03 16:58:37 +03:00
|
|
|
[view {:style {:backgroundColor toolbar-background1
|
2016-05-03 16:39:08 +03:00
|
|
|
:elevation 2
|
|
|
|
:position "absolute"
|
|
|
|
:top 56
|
|
|
|
:left 0
|
|
|
|
:right 0}}
|
|
|
|
[view {:style {:marginLeft 16
|
|
|
|
:height 1.5
|
2016-05-02 16:56:42 +03:00
|
|
|
:backgroundColor separator-color}}]
|
|
|
|
[view {:style {:marginVertical 10}}
|
|
|
|
(for [action actions]
|
|
|
|
^{:key action} [action-view action])]]))
|
|
|
|
|
2016-05-03 16:39:08 +03:00
|
|
|
(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 [navigator chat]
|
|
|
|
[overlay {:on-click-outside (fn []
|
|
|
|
(dispatch [:set-show-actions false]))}
|
|
|
|
[actions-list-view navigator chat]])
|
|
|
|
|
|
|
|
(defn toolbar [navigator chat show-actions]
|
2016-05-03 16:45:06 +03:00
|
|
|
[view {:style {:flexDirection "row"
|
|
|
|
:height 56
|
2016-05-03 16:58:37 +03:00
|
|
|
:backgroundColor toolbar-background1
|
2016-05-03 16:45:06 +03:00
|
|
|
: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
|
2016-05-03 16:39:08 +03:00
|
|
|
:fontFamily font}}
|
2016-05-03 16:45:06 +03:00
|
|
|
"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}]]])])
|
2016-04-19 15:38:16 +03:00
|
|
|
|
2016-03-25 14:29:38 +03:00
|
|
|
(defn chat [{:keys [navigator]}]
|
2016-04-29 15:43:36 +03:00
|
|
|
(let [messages (subscribe [:get-chat-messages])
|
2016-05-03 16:39:08 +03:00
|
|
|
chat (subscribe [:get-current-chat])
|
|
|
|
show-actions-atom (subscribe [:show-actions])]
|
2016-03-25 13:36:16 +03:00
|
|
|
(fn []
|
2016-04-06 16:13:31 +03:00
|
|
|
(let [msgs @messages
|
2016-04-19 15:38:16 +03:00
|
|
|
;_ (log/debug "messages=" msgs)
|
2016-04-29 15:43:36 +03:00
|
|
|
;; temp
|
|
|
|
typing (:group-chat @chat)
|
2016-04-22 13:51:14 +03:00
|
|
|
;; end temp
|
2016-04-06 16:13:31 +03:00
|
|
|
datasource (to-realm-datasource msgs)
|
|
|
|
contacts (:contacts @chat)
|
|
|
|
contact-by-identity (contacts-by-identity contacts)]
|
2016-03-25 17:22:13 +03:00
|
|
|
[view {:style {:flex 1
|
2016-04-18 13:38:38 +03:00
|
|
|
:backgroundColor chat-background}}
|
2016-05-03 16:39:08 +03:00
|
|
|
[toolbar navigator @chat @show-actions-atom]
|
2016-05-02 13:43:13 +03:00
|
|
|
(let [last-msg-id (:last-msg-id @chat)]
|
2016-04-29 15:43:36 +03:00
|
|
|
[list-view {:dataSource datasource
|
|
|
|
: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))]
|
2016-05-02 13:43:13 +03:00
|
|
|
(r/as-element [chat-message msg last-msg-id])))}])
|
2016-04-19 15:38:16 +03:00
|
|
|
(when (:group-chat @chat)
|
|
|
|
[typing-all])
|
2016-04-11 22:57:20 +03:00
|
|
|
(when (:is-active @chat)
|
2016-05-03 16:39:08 +03:00
|
|
|
[chat-message-new])
|
|
|
|
(when @show-actions-atom
|
|
|
|
[actions-view navigator @chat])]))))
|