diff --git a/src/syng_im/components/chat.cljs b/src/syng_im/components/chat.cljs index 43dde33f03..9b9ad18ae8 100644 --- a/src/syng_im/components/chat.cljs +++ b/src/syng_im/components/chat.cljs @@ -4,22 +4,14 @@ [syng-im.components.react :refer [view text image + icon navigator touchable-highlight toolbar-android list-view list-item android?]] - [syng-im.components.styles :refer [font - title-font - color-white - chat-background - online-color - selected-message-color - separator-color - text1-color - text2-color - toolbar-background1]] + [syng-im.components.chat-styles :as st] [syng-im.utils.logging :as log] [syng-im.resources :as res] [syng-im.constants :refer [content-type-status]] @@ -29,7 +21,6 @@ [syng-im.components.chat.chat-message :refer [chat-message]] [syng-im.components.chat.chat-message-new :refer [chat-message-new]])) - (defn contacts-by-identity [contacts] (->> contacts (map (fn [{:keys [identity] :as contact}] @@ -50,123 +41,33 @@ [image {:source (if (s/blank? photo-path) res/user-no-photo {:uri photo-path}) - :style {:borderRadius 50 - :width 36 - :height 36}}]]) + :style st/chat-photo}]]) (defn contact-online [{:keys [online]}] (when online - [view {:position "absolute" - :top 30 - :left 30 - :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}]])) + [view st/online-view + [view st/online-dot-left] + [view st/online-dot-right]])) (defn typing [member] - [view {:style {:width 260 - :marginTop 10 - :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}} + [view st/typing-view + [view st/typing-background + [text {:style st/typing-text} (str member " is typing")]]]) (defn typing-all [] - [view {:style {:marginBottom 20}} + [view st/typing-all (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 _ _] + (fn [row _ idx] (let [msg (-> row (add-msg-color contact-by-identity) - (assoc :group-chat group-chat))] + (assoc :group-chat group-chat) + (assoc :last-msg (zero? (js/parseInt idx))))] (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]) @@ -174,43 +75,24 @@ 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 st/actions-overlay + [touchable-highlight {:on-press on-click-outside + :style st/overlay-highlight} [view nil]] items]) -(defn action-view [action] +(defn action-view [{:keys [icon-style handler title subtitle] + icon-name :icon}] [touchable-highlight {:on-press (fn [] (dispatch [:set-show-actions false]) - ((:handler action))) - :underlay-color :transparent} - [view {:style {:flexDirection "row" - :height 56}} - [view {:width 56 - :height 56 - :alignItems "center" - :justifyContent "center"} - [image {:source {:uri (:icon action)} - :style (:icon-style action)}]] - [view {:style {:flex 1 - :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}} + (handler))} + [view st/action-icon-row + [view st/action-icon-view + [icon icon-name icon-style]] + [view st/action-view + [text {:style st/action-title} title] + (when-let [subtitle subtitle] + [text {:style st/action-subtitle} subtitle])]]]) (defn actions-list-view [] @@ -218,27 +100,27 @@ (subscribe [:chat-properties [:group-chat :chat-id]])] (when-let [actions (if @group-chat [{:title "Add Contact to chat" - :icon :icon_menu_group + :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 :search_gray_copy :icon-style {:width 17 :height 17} :handler nil #_#(dispatch [:show-remove-participants navigator])} {:title "Leave Chat" - :icon :icon_muted + :icon :muted :icon-style {:width 18 :height 21} :handler nil #_#(dispatch [:leave-group-chat navigator])} {:title "Settings" :subtitle "Not implemented" - :icon :icon_settings + :icon :settings :icon-style {:width 20 :height 13} :handler (fn [])}] @@ -247,16 +129,9 @@ :icon-style {:width 25 :height 19} :handler #(dispatch [:show-profile @chat-id])}])] - [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}} + [view st/actions-wrapper + [view st/actions-separator] + [view st/actions-view (for [action actions] ^{:key action} [action-view action])]]))) @@ -269,67 +144,33 @@ (subscribe [:chat-properties [:group-chat :name :contacts]]) show-actions (subscribe [:show-actions])] (fn [] - [view {:style {:flexDirection "row" - :height 56 - :backgroundColor toolbar-background1 - :elevation 2}} + [view st/toolbar-view (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}} + [touchable-highlight {:on-press #(dispatch [:navigate-back])} + [view st/icon-view + [icon :back st/back-icon]]]) + [view (st/chat-name-view @show-actions) + [text {:style st/chat-name-text} (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}} + [view {:flexDirection :row} + [icon :group st/group-icon] + [text {:style st/members} (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"])] + [text {:style st/last-activity} "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}}]]] + {:on-press #(dispatch [:set-show-actions false])} + [view st/icon-view + [icon :up st/up-icon]]] [touchable-highlight - {:on-press #(dispatch [:set-show-actions true]) - :underlay-color :transparent} - [view {:style {:width 56 - :height 56}} + {:on-press #(dispatch [:set-show-actions true])} + [view st/icon-view [chat-photo {}] [contact-online {:online true}]]])]))) @@ -348,8 +189,7 @@ group-chat (subscribe [:chat :group-chat]) show-actions-atom (subscribe [:show-actions])] (fn [] - [view {:style {:flex 1 - :backgroundColor chat-background}} + [view st/chat-view [toolbar] [messages-view @group-chat] (when @group-chat [typing-all]) diff --git a/src/syng_im/components/chat/chat_message.cljs b/src/syng_im/components/chat/chat_message.cljs index 726e55e249..cbf794972b 100644 --- a/src/syng_im/components/chat/chat_message.cljs +++ b/src/syng_im/components/chat/chat_message.cljs @@ -1,149 +1,54 @@ (ns syng-im.components.chat.chat-message (:require [clojure.string :as s] - [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.components.react :refer [android? - view + [re-frame.core :refer [subscribe dispatch]] + [syng-im.components.react :refer [view text image - touchable-highlight - navigator]] - [syng-im.components.styles :refer [font - color-light-blue-transparent - color-white - color-black - color-blue - selected-message-color - online-color - text1-color - text2-color]] + touchable-highlight]] + [syng-im.components.chat.chat-message-styles :as st] [syng-im.models.commands :refer [parse-command-msg-content - parse-command-request-msg-content]] - [syng-im.utils.logging :as log] - [syng-im.navigation :refer [nav-pop]] + parse-command-request]] [syng-im.resources :as res] [syng-im.constants :refer [text-content-type content-type-status content-type-command content-type-command-request]])) -(def style-message-text {:fontSize 14 - :fontFamily font - :lineHeight 21 - :color text1-color}) - -(def style-sub-text {:top -2 - :fontFamily font - :fontSize 12 - :color text2-color - :lineHeight 14 - :height 16}) - (defn message-date [{:keys [date]}] [view {} - [view {:style {:backgroundColor color-light-blue-transparent - :height 24 - :borderRadius 50 - :alignSelf :center - :marginTop 20 - :marginBottom 20 - :paddingTop 5 - :paddingHorizontal 12}} - [text {:style (assoc style-sub-text :textAlign :center)} - date]]]) + [view st/message-date-container + [text {:style st/message-date-text} date]]]) (defn contact-photo [{:keys [photo-path]}] - [view {:borderRadius 50} + [view st/contact-photo-container [image {:source (if (s/blank? photo-path) res/user-no-photo {:uri photo-path}) - :style {:borderRadius 50 - :width 64 - :height 64}}]]) + :style st/contact-photo}]]) (defn contact-online [{:keys [online]}] (when online - [view {:position :absolute - :top 44 - :left 44 - :width 24 - :height 24 - :borderRadius 50 - :backgroundColor online-color - :borderWidth 2 - :borderColor color-white} - [view {:position :absolute - :top 8 - :left 5 - :width 4 - :height 4 - :borderRadius 50 - :backgroundColor color-white}] - [view {:position :absolute - :top 8 - :left 11 - :width 4 - :height 4 - :borderRadius 50 - :backgroundColor color-white}]])) - + [view st/online-container + [view st/online-dot-left] + [view st/online-dot-right]])) (defn message-content-status [{:keys [from content]}] - [view {:style {:flex 1 - :alignSelf :center - :alignItems :center - :width 249}} - [view {:style {:marginTop 20}} + [view st/status-container + [view st/status-image-view [contact-photo {}] [contact-online {:online true}]] - [text {:style {:marginTop 20 - :fontSize 18 - :fontFamily font - :color text1-color}} - from] - [text {:style {:marginTop 10 - :fontFamily font - :fontSize 14 - :lineHeight 20 - :textAlign :center - :color text2-color}} - content]]) + [text {:style st/status-from} from] + [text {:style st/status-text} content]]) (defn message-content-audio [_] - [view {:style {:flexDirection :row - :alignItems :center}} - [view {:style {:width 33 - :height 33 - :borderRadius 50 - :elevation 1}} + [view st/audio-container + [view st/play-view [image {:source res/play - :style {:width 33 - :height 33}}]] - [view {:style {:marginTop 10 - :marginLeft 10 - :width 120 - :height 26 - :elevation 1}} - [view {:style {:position :absolute - :top 4 - :width 120 - :height 2 - :backgroundColor "#EC7262"}}] - [view {:style {:position :absolute - :left 0 - :top 0 - :width 2 - :height 10 - :backgroundColor "#4A5258"}}] - [text {:style {:position :absolute - :left 1 - :top 11 - :fontFamily font - :fontSize 11 - :color "#4A5258" - :letterSpacing 1 - :lineHeight 15}} - "03:39"]]]) - + :style st/play-image}]] + [view st/track-container + [view st/track] + [view st/track-mark] + [text {:style st/track-duration-text} "03:39"]]]) (defn message-content-command [content] (let [commands-atom (subscribe [:get-commands])] @@ -151,27 +56,14 @@ (let [commands @commands-atom {: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}} + [view st/content-command-view + [view st/command-container + [view (st/command-view command) + [text {:style st/command-name} (:text command)]]] [image {:source (:icon command) - :style {:position :absolute - :top 4 - :right 0 - :width 12 - :height 13}}] - [text {:style (merge style-message-text - {:marginTop 8 - :marginHorizontal 0})} + :style st/command-image}] + [text {:style st/command-text} ;; TODO isn't smart (if (= (:command command) :keypair-password) "******" @@ -180,99 +72,33 @@ (defn set-chat-command [msg-id command] (dispatch [:set-response-chat-command msg-id (:command command)])) - (defn message-content-command-request - [{:keys [msg-id content outgoing group-chat from]}] + [{:keys [msg-id content from incoming-group]}] (let [commands-atom (subscribe [:get-commands])] - (fn [{:keys [msg-id content outgoing group-chat from]}] + (fn [{:keys [msg-id content from incoming-group]}] (let [commands @commands-atom - {:keys [command content]} (parse-command-request-msg-content commands content)] - [touchable-highlight {:onPress #(set-chat-command msg-id command) - :underlay-color :transparent} - [view {:style {:paddingRight 16}} - [view {:style (merge {:borderRadius 14 - :padding 12 - :backgroundColor color-white})} - (when (and group-chat (not outgoing)) - [text {:style (merge style-sub-text - {:marginBottom 2})} + {:keys [command content]} (parse-command-request commands content)] + [touchable-highlight {:onPress #(set-chat-command msg-id command)} + [view st/comand-request-view + [view st/command-request-message-view + (when incoming-group + [text {:style st/command-request-from-text} from]) - [text {:style style-message-text} + [text {:style st/style-message-text} content]] - [view {:style {:position :absolute - :top 12 - :right 0 - :width 32 - :height 32 - :borderRadius 50 - :backgroundColor (:color command)}} + [view (st/command-request-image-view command) [image {:source (:request-icon command) - :style {:position :absolute - :top 9 - :left 10 - :width 12 - :height 13}}]] + :style st/command-request-image}]] (when (:request-text command) - [view {:style {:marginTop 4 - :height 14}} - [text {:style style-sub-text} + [view st/command-request-text-view + [text {:style st/style-sub-text} (:request-text command)]])]])))) -(defn message-content-plain [content outgoing group-chat] - [text {:style (merge style-message-text - {:marginTop (if (and group-chat (not outgoing)) - 4 - 0)} - (when (and outgoing group-chat) - {: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-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}} + [message content] + [view (st/message-view message) + #_(when incoming-group + [text {:style message-author-text} "Justas"]) content]) @@ -284,14 +110,9 @@ [wrapper message [message-content-command-request message]]) (defn text-message - [{:keys [content outgoing group-chat] :as message}] + [{:keys [content] :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}))} + [text {:style (st/text-message message)} content]]) (defmethod message-content text-content-type @@ -315,21 +136,14 @@ :content-type content-type}]]]) (defn message-delivery-status [{:keys [delivery-status]}] - [view {:style {:flexDirection :row - :marginTop 2}} - + [view st/delivery-view [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) - :style {:marginTop 6 - :width 9 - :height 7}}] - [text {:style {:fontFamily font - :fontSize 12 - :color text2-color - :marginLeft 5}} + :style st/delivery-image}] + [text {:style st/delivery-text} (case delivery-status :delivered "Delivered" :seen "Seen" @@ -337,85 +151,46 @@ :failed "Failed")]]) (defn member-photo [{:keys [photo-path]}] - [view {:borderRadius 50} + [view st/photo-view [image {:source (if (s/blank? photo-path) res/user-no-photo {:uri photo-path}) - :style {:borderRadius 50 - :width 24 - :height 24}}]]) - + :style st/photo}]]) (defn incoming-group-message-body - [{:keys [selected new-day same-author same-direction last-msg typing]} - content] + [{:keys [selected same-author] :as message} content] (let [delivery-status :seen-by-everyone] - [view {:style {:flexDirection :column}} + [view st/group-message-wrapper (when selected - [text {:style {:marginTop 18 - :marginLeft 40 - :fontFamily font - :fontSize 12 - :color text2-color}} + [text {:style st/selected-message} "Mar 7th, 15:22"]) - [view {:style (merge {:flexDirection :row - :alignSelf :flex-start - :marginTop (cond - new-day 0 - same-author 4 - same-direction 20 - :else 10) - :paddingRight 8 - :paddingLeft 8} - (when (and last-msg (not typing)) - {:paddingBottom 20}))} - [view {:style {:width 24}} - (when (not same-author) - [member-photo {}])] - [view {:style {:flexDirection :column - :width 260 - :paddingLeft 8 - :alignItems :flex-start}} + [view (st/incoming-group-message-body-st message) + [view st/message-author + (when (not same-author) [member-photo {}])] + [view st/group-message-view content ;; TODO show for last or selected (when (and selected delivery-status) [message-delivery-status {:delivery-status delivery-status}])]]])) (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 - same-direction 20 - :else 10) - :paddingRight 8 - :paddingLeft 8 - :alignSelf align - :alignItems align} - (when (and last-msg (not typing)) - {:paddingBottom 20}))} + [{:keys [outgoing] :as message} content] + (let [delivery-status :seen] + [view (st/message-body message) content (when (and outgoing delivery-status) [message-delivery-status {:delivery-status delivery-status}])])) (defn chat-message - [{:keys [msg-id outgoing delivery-status date new-day group-chat] - :as message} - last-msg-id] + [{:keys [outgoing delivery-status date new-day group-chat] + :as message}] [view {} - (when new-day - [message-date {:date date}]) - (let [msg-data - (merge message {:delivery-status (keyword delivery-status) - :last-msg (= last-msg-id msg-id)})] - [view {} + (when new-day [message-date {:date date}]) + [view {} + (let [incoming-group (and group-chat (not outgoing))] [message-content - (if (and group-chat (not outgoing)) + (if incoming-group incoming-group-message-body message-body) - msg-data]])]) + (merge message {:delivery-status (keyword delivery-status) + :incoming-group incoming-group})])]]) diff --git a/src/syng_im/components/chat/chat_message_new.cljs b/src/syng_im/components/chat/chat_message_new.cljs index a50662ee4e..545d0052b7 100644 --- a/src/syng_im/components/chat/chat_message_new.cljs +++ b/src/syng_im/components/chat/chat_message_new.cljs @@ -1,23 +1,15 @@ (ns syng-im.components.chat.chat-message-new (:require - [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.components.react :refer [android? - view - image - text - text-input]] - [syng-im.components.styles :refer [color-white]] - [syng-im.components.chat.plain-message-input :refer [plain-message-input-view]] - [syng-im.components.chat.input.simple-command :refer [simple-command-input-view]] - [syng-im.components.chat.input.phone :refer [phone-input-view]] - [syng-im.components.chat.input.password :refer [password-input-view]] - [syng-im.components.chat.input.confirmation-code :refer [confirmation-code-input-view]] - [syng-im.components.chat.input.money :refer [money-input-view]] - [syng-im.components.chat.input.simple-command-staged :refer [simple-command-staged-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])) + [re-frame.core :refer [subscribe]] + [syng-im.components.react :refer [view]] + [syng-im.components.chat.plain-message-input :refer [plain-message-input-view]] + [syng-im.components.chat.input.simple-command :refer [simple-command-input-view]] + [syng-im.components.chat.input.phone :refer [phone-input-view]] + [syng-im.components.chat.input.password :refer [password-input-view]] + [syng-im.components.chat.input.confirmation-code :refer [confirmation-code-input-view]] + [syng-im.components.chat.input.money :refer [money-input-view]] + [syng-im.components.chat.input.simple-command-staged :refer [simple-command-staged-view]] + [syng-im.components.chat.chat-message-styles :as st])) (defn staged-command-view [stage-command] [simple-command-staged-view stage-command]) @@ -40,13 +32,12 @@ [default-command-input-view command])) (defn chat-message-new [] - (let [command-atom (subscribe [:get-chat-command]) + (let [command-atom (subscribe [:get-chat-command]) staged-commands-atom (subscribe [:get-chat-staged-commands])] (fn [] - (let [command @command-atom + (let [command @command-atom staged-commands @staged-commands-atom] - [view {:style {:backgroundColor color-white - :elevation 4}} + [view st/new-message-container (when (and staged-commands (pos? (count staged-commands))) [staged-commands-view staged-commands]) (if command diff --git a/src/syng_im/components/chat/chat_message_styles.cljs b/src/syng_im/components/chat/chat_message_styles.cljs new file mode 100644 index 0000000000..c336fbb8d5 --- /dev/null +++ b/src/syng_im/components/chat/chat_message_styles.cljs @@ -0,0 +1,329 @@ +(ns syng-im.components.chat.chat-message-styles + (:require [syng-im.components.styles :refer [font + color-light-blue-transparent + color-white + color-black + color-blue + selected-message-color + online-color + text1-color + text2-color]] + [syng-im.constants :refer [text-content-type + content-type-command]])) + +(def style-message-text + {:fontSize 14 + :fontFamily font + :lineHeight 21 + :color text1-color}) + +(def style-sub-text + {:top -2 + :fontFamily font + :fontSize 12 + :color text2-color + :lineHeight 14 + :height 16}) + +(defn message-padding-top + [{:keys [new-day same-author same-direction]}] + (cond + new-day 0 + same-author 4 + same-direction 20 + :else 10)) + +(defn last-message-padding + [{:keys [last-msg typing]}] + (when (and last-msg (not typing)) + {:paddingBottom 20})) + +(def message-body-base + {:paddingRight 8 + :paddingLeft 8}) + +(defn message-body + [{:keys [outgoing] :as message}] + (let [align (if outgoing :flex-end :flex-start)] + (merge message-body-base + {:flexDirection :column + :width 260 + :paddingTop (message-padding-top message) + :alignSelf align + :alignItems align} + (last-message-padding message)))) + +(defn incoming-group-message-body-st + [message] + (merge message-body-base + {:flexDirection :row + :alignSelf :flex-start + :marginTop (message-padding-top message) + :paddingRight 8 + :paddingLeft 8} + (last-message-padding message))) + +(def selected-message + {:marginTop 18 + :marginLeft 40 + :fontFamily font + :fontSize 12 + :color text2-color}) + +(def group-message-wrapper + {:flexDirection :column}) + +(def group-message-view + {:flexDirection :column + :width 260 + :paddingLeft 8 + :alignItems :flex-start}) + +(def message-author {:width 24}) + +(def photo-view {:borderRadius 50}) +(def photo + {:borderRadius 50 + :width 24 + :height 24}) + +(def delivery-view + {:flexDirection :row + :marginTop 2}) + +(def delivery-image + {:marginTop 6 + :width 9 + :height 7}) + +(def delivery-text + {:fontFamily font + :fontSize 12 + :color text2-color + :marginLeft 5}) + +(defn text-message + [{:keys [outgoing group-chat incoming-group]}] + (merge style-message-text + {:marginTop (if incoming-group + 4 + 0)} + (when (and outgoing group-chat) + {:color color-white}))) + +(defn message-view + [{:keys [content-type outgoing group-chat selected]}] + (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})))) + +(def comand-request-view + {:paddingRight 16}) + +(def command-request-message-view + {:borderRadius 14 + :padding 12 + :backgroundColor color-white}) + +(def command-request-from-text + (merge style-sub-text {:marginBottom 2})) + +(defn command-request-image-view + [command] + {:position :absolute + :top 12 + :right 0 + :width 32 + :height 32 + :borderRadius 50 + :backgroundColor (:color command)}) + +(def command-request-image + {:position :absolute + :top 9 + :left 10 + :width 12 + :height 13}) + +(def command-request-text-view + {:marginTop 4 + :height 14}) + + +(def content-command-view + {:flexDirection :column}) + +(def command-container + {:flexDirection :row + :marginRight 32}) + +(defn command-view [command] + {:backgroundColor (:color command) + :height 24 + :borderRadius 50 + :paddingTop 3 + :paddingHorizontal 12}) + +(def command-name + {:fontSize 12 + :fontFamily font + :color color-white}) + +(def command-image + {:position :absolute + :top 4 + :right 0 + :width 12 + :height 13}) + +(def command-text + (merge style-message-text + {:marginTop 8 + :marginHorizontal 0})) + +(def message-author-text + {:marginTop 0 + :fontSize 12 + :fontFamily font}) + +(def audio-container + {:flexDirection :row + :alignItems :center}) + +(def play-view + {:width 33 + :height 33 + :borderRadius 50 + :elevation 1}) + +(def play-image + {:width 33 + :height 33}) + +(def track-container + {:marginTop 10 + :marginLeft 10 + :width 120 + :height 26 + :elevation 1}) + +(def track + {:position :absolute + :top 4 + :width 120 + :height 2 + :backgroundColor :#EC7262}) + +(def track-mark + {:position :absolute + :left 0 + :top 0 + :width 2 + :height 10 + :backgroundColor :#4A5258}) + +(def track-duration-text + {:position :absolute + :left 1 + :top 11 + :fontFamily font + :fontSize 11 + :color :#4A5258 + :letterSpacing 1 + :lineHeight 15}) + +(def status-container + {:flex 1 + :alignSelf :center + :alignItems :center + :width 249}) + +(def status-image-view + {:marginTop 20}) + +(def status-from + {:marginTop 20 + :fontSize 18 + :fontFamily font + :color text1-color}) + +(def status-text + {:marginTop 10 + :fontFamily font + :fontSize 14 + :lineHeight 20 + :textAlign :center + :color text2-color}) + +(def online-container + {:position :absolute + :top 44 + :left 44 + :width 24 + :height 24 + :borderRadius 50 + :backgroundColor online-color + :borderWidth 2 + :borderColor color-white}) + +(def online-dot + {:position :absolute + :top 8 + :width 4 + :height 4 + :borderRadius 50 + :backgroundColor color-white}) + +(def online-dot-left + (assoc online-dot :left 5)) + +(def online-dot-right + (assoc online-dot :left 11)) + +(def contact-photo-container + {:borderRadius 50}) + +(def contact-photo + {:borderRadius 50 + :width 64 + :height 64}) + +(def message-date-container + {:backgroundColor color-light-blue-transparent + :height 24 + :borderRadius 50 + :alignSelf :center + :marginTop 20 + :marginBottom 20 + :paddingTop 5 + :paddingHorizontal 12}) + +(def message-date-text + (assoc style-sub-text :textAlign :center)) + +(def new-message-container + {:backgroundColor color-white + :elevation 4}) + +(def participants-container + {:flex 1 + :backgroundColor :white}) + +(def participants-list + {:backgroundColor :white}) + +(def new-participant-image + {:width 20 + :height 18}) + +(def remove-participants-image + {:width 22 + :height 30}) diff --git a/src/syng_im/components/chat/input/confirmation_code.cljs b/src/syng_im/components/chat/input/confirmation_code.cljs index a1f1fca549..7ba41043d6 100644 --- a/src/syng_im/components/chat/input/confirmation_code.cljs +++ b/src/syng_im/components/chat/input/confirmation_code.cljs @@ -1,9 +1,7 @@ (ns syng-im.components.chat.input.confirmation-code (:require - [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.components.chat.input.simple-command :refer [simple-command-input-view]] - [syng-im.utils.utils :refer [log toast http-post]] - [syng-im.utils.logging :as log])) + [syng-im.components.chat.input.simple-command + :refer [simple-command-input-view]])) (defn confirmation-code-input-view [command] - [simple-command-input-view command {:keyboardType "numeric"}]) + [simple-command-input-view command {:keyboardType :numeric}]) diff --git a/src/syng_im/components/chat/input/input_styles.cljs b/src/syng_im/components/chat/input/input_styles.cljs new file mode 100644 index 0000000000..7127145794 --- /dev/null +++ b/src/syng_im/components/chat/input/input_styles.cljs @@ -0,0 +1,123 @@ +(ns syng-im.components.chat.input.input-styles + (:require [syng-im.components.styles :refer [font + color-white + color-blue + text1-color + text2-color + chat-background + color-black]])) + +(def money-input + {:flex 1 + :marginLeft 8 + :lineHeight 42 + :fontSize 32 + :fontFamily font + :color :black}) + +(def command-input-and-suggestions-container + {:flexDirection :column}) + +(def command-input-container + {:flexDirection :row + :height 56 + :backgroundColor color-white + :elevation 4}) + +(defn command-text-container + [{:keys [color]}] + {:flexDirection :column + :marginTop 16 + :marginBottom 16 + :marginLeft 16 + :marginRight 0 + :backgroundColor color + :height 24 + :borderRadius 50}) + +(def command-text + {:marginTop 3 + :marginHorizontal 12 + :fontSize 12 + :fontFamily font + :color color-white}) + +(def command-input + {:flex 1 + :marginLeft 8 + :marginTop 7 + :fontSize 14 + :fontFamily font + :color text1-color}) + +(def send-container + {:marginTop 10 + :marginRight 10 + :width 36 + :height 36 + :borderRadius 50 + :backgroundColor color-blue}) + +(def send-icon + {:marginTop 10.5 + :marginLeft 12 + :width 15 + :height 15}) + +(def cancel-container + {:marginTop 10 + :marginRight 10 + :width 36 + :height 36}) + +(def cancel-icon + {:marginTop 10.5 + :marginLeft 12 + :width 12 + :height 12}) + +(def staged-command-container + {:flex 1 + :alignItems :flex-start + :flexDirection :column + :backgroundColor color-white}) + +(def staged-command-background + {:flexDirection :column + :margin 16 + :padding 12 + :backgroundColor chat-background + :borderRadius 14}) + +(def staged-command-info-container + {:flexDirection :row}) + +(defn staged-command-text-container + [{:keys [color]}] + {:backgroundColor color + :height 24 + :borderRadius 50 + :marginRight 32 + :paddingTop 3 + :paddingHorizontal 12}) + +(def staged-command-text + {:fontSize 12 + :fontFamily font + :color color-white}) + +(def staged-command-cancel + {:position :absolute + :top 7 + :right 4}) + +(def staged-command-cancel-icon + {:width 10 + :height 10}) + +(def staged-command-content + {:marginTop 5 + :marginHorizontal 0 + :fontSize 14 + :fontFamily font + :color color-black}) diff --git a/src/syng_im/components/chat/input/money.cljs b/src/syng_im/components/chat/input/money.cljs index eb879188cb..be53c5dbc2 100644 --- a/src/syng_im/components/chat/input/money.cljs +++ b/src/syng_im/components/chat/input/money.cljs @@ -1,16 +1,10 @@ (ns syng-im.components.chat.input.money (:require - [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.components.styles :refer [font]] - [syng-im.components.chat.input.simple-command :refer [simple-command-input-view]] - [syng-im.utils.utils :refer [log toast http-post]] - [syng-im.utils.logging :as log])) + [syng-im.components.chat.input.simple-command + :refer [simple-command-input-view]] + [syng-im.components.chat.input.input-styles :as st])) (defn money-input-view [command] - [simple-command-input-view command {:keyboardType "numeric" - :style {:flex 1 - :marginLeft 8 - :lineHeight 42 - :fontSize 32 - :fontFamily font - :color "black"}}]) + [simple-command-input-view command + {:keyboardType :numeric + :style st/money-input}]) diff --git a/src/syng_im/components/chat/input/password.cljs b/src/syng_im/components/chat/input/password.cljs index e27c5f8112..8385fa2c1c 100644 --- a/src/syng_im/components/chat/input/password.cljs +++ b/src/syng_im/components/chat/input/password.cljs @@ -1,9 +1,7 @@ (ns syng-im.components.chat.input.password (:require - [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.components.chat.input.simple-command :refer [simple-command-input-view]] - [syng-im.utils.utils :refer [log toast http-post]] - [syng-im.utils.logging :as log])) + [syng-im.components.chat.input.simple-command + :refer [simple-command-input-view]])) (defn password-input-view [command] [simple-command-input-view command {:secureTextEntry true}]) diff --git a/src/syng_im/components/chat/input/phone.cljs b/src/syng_im/components/chat/input/phone.cljs index 5c35704c4e..92f78ba88c 100644 --- a/src/syng_im/components/chat/input/phone.cljs +++ b/src/syng_im/components/chat/input/phone.cljs @@ -1,12 +1,10 @@ (ns syng-im.components.chat.input.phone (:require - [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.components.chat.input.simple-command :refer [simple-command-input-view]] - [syng-im.utils.phone-number :refer [valid-mobile-number?]] - [syng-im.utils.utils :refer [log toast http-post]] - [syng-im.utils.logging :as log])) + [syng-im.components.chat.input.simple-command + :refer [simple-command-input-view]] + [syng-im.utils.phone-number :refer [valid-mobile-number?]])) (defn phone-input-view [command] - [simple-command-input-view command {:keyboardType "phone-pad"} + [simple-command-input-view command {:keyboardType :phone-pad} :validator (fn [message] (valid-mobile-number? message))]) diff --git a/src/syng_im/components/chat/input/simple_command.cljs b/src/syng_im/components/chat/input/simple_command.cljs index 3c8d5765ab..29bebce112 100644 --- a/src/syng_im/components/chat/input/simple_command.cljs +++ b/src/syng_im/components/chat/input/simple_command.cljs @@ -1,19 +1,14 @@ (ns syng-im.components.chat.input.simple-command (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.components.react :refer [android? - view + [syng-im.components.react :refer [view image + icon text text-input touchable-highlight]] + [syng-im.resources :as res] [syng-im.components.chat.content-suggestions :refer [content-suggestions-view]] - [syng-im.components.styles :refer [font - color-white - color-blue - text1-color - text2-color]] - [syng-im.utils.utils :refer [log toast http-post]] - [syng-im.resources :as res])) + [syng-im.components.chat.input.input-styles :as st])) (defn cancel-command-input [] (dispatch [:cancel-command])) @@ -34,65 +29,23 @@ (let [message-atom (subscribe [:get-chat-command-content])] (fn [command input-options & {:keys [validator]}] (let [message @message-atom] - [view {:style {:flexDirection :column}} + [view st/command-input-and-suggestions-container [content-suggestions-view] - [view {:style {:flexDirection :row - :height 56 - :backgroundColor color-white - :elevation 4}} - [view {:style {:flexDirection :column - :marginTop 16 - :marginBottom 16 - :marginLeft 16 - :marginRight 0 - :backgroundColor (:color command) - :height 24 - :borderRadius 50}} - [text {:style {:marginTop 3 - :marginHorizontal 12 - :fontSize 12 - :fontFamily font - :color color-white}} - (:text command)]] - [text-input (merge {:underlineColorAndroid :transparent - :style {:flex 1 - :marginLeft 8 - :marginTop 7 - :fontSize 14 - :fontFamily font - :color text1-color} - :autoFocus true - :placeholder "Type" - :placeholderTextColor text2-color - :onChangeText set-input-message - :onSubmitEditing (fn [] - (when (valid? message validator) - (send-command)))} + [view st/command-input-container + [view (st/command-text-container command) + [text {:style st/command-text} (:text command)]] + [text-input (merge {:style st/command-input + :autoFocus true + :onChangeText set-input-message + :onSubmitEditing (fn [] + (when (valid? message validator) + (send-command)))} input-options) message] (if (valid? message validator) - [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 cancel-command-input - :underlay-color :transparent} - [view {:style {:marginTop 10 - :marginRight 10 - :width 36 - :height 36}} + [touchable-highlight {:on-press send-command} + [view st/send-container [icon :send st/send-icon]]] + [touchable-highlight {:on-press cancel-command-input} + [view st/cancel-container [image {:source res/icon-close-gray - :style {:marginTop 10.5 - :marginLeft 12 - :width 12 - :height 12}}]]])]])))) + :style st/cancel-icon}]]])]])))) diff --git a/src/syng_im/components/chat/input/simple_command_staged.cljs b/src/syng_im/components/chat/input/simple_command_staged.cljs index ba2f0f5a10..a2e0b571ee 100644 --- a/src/syng_im/components/chat/input/simple_command_staged.cljs +++ b/src/syng_im/components/chat/input/simple_command_staged.cljs @@ -1,63 +1,28 @@ (ns syng-im.components.chat.input.simple-command-staged - (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.components.react :refer [android? - view + (:require [re-frame.core :refer [subscribe dispatch]] + [syng-im.components.react :refer [view image text - text-input touchable-highlight]] - [syng-im.components.styles :refer [font - color-black - color-white - chat-background]] - [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.components.chat.input.input-styles :as st])) (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])] - (fn [staged-command] - (let [chat-id @chat-id-atom - command (:command staged-command)] - [view {:style {:flex 1 - :alignItems "flex-start" - :flexDirection "column" - :backgroundColor color-white}} - [view {:style {:flexDirection "column" - :margin 16 - :padding 12 - :backgroundColor chat-background - :borderRadius 14}} - [view {:style {:flexDirection "row"}} - [view {:style {:backgroundColor (:color command) - :height 24 - :borderRadius 50 - :marginRight 32 - :paddingTop 3 - :paddingHorizontal 12}} - [text {:style {:fontSize 12 - :fontFamily font - :color color-white}} - (:text 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 - :height 10}}]]] - [text {:style {:marginTop 5 - :marginHorizontal 0 - :fontSize 14 - :fontFamily font - :color color-black}} - ;; TODO isn't smart - (if (= (:command command) :keypair-password) - "******" - (:content staged-command))]]])))) + (let [command (:command staged-command)] + [view st/staged-command-container + [view st/staged-command-background + [view st/staged-command-info-container + [view (st/staged-command-text-container command) + [text {:style st/staged-command-text} (:text command)]] + [touchable-highlight {:style st/staged-command-cancel + :onPress #(cancel-command-input staged-command)} + [image {:source res/icon-close-gray + :style st/staged-command-cancel-icon}]]] + [text {:style st/staged-command-content} + ;; TODO isn't smart + (if (= (:command command) :keypair-password) + "******" + (:content staged-command))]]])) diff --git a/src/syng_im/components/chat/new_participants.cljs b/src/syng_im/components/chat/new_participants.cljs index 49c1f6c511..91beecf10a 100644 --- a/src/syng_im/components/chat/new_participants.cljs +++ b/src/syng_im/components/chat/new_participants.cljs @@ -1,41 +1,35 @@ (ns syng-im.components.chat.new-participants - (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] + (:require [re-frame.core :refer [subscribe dispatch]] [syng-im.resources :as res] - [syng-im.components.react :refer [view android? text-input text image - touchable-highlight]] + [syng-im.components.react :refer [view]] [syng-im.components.realm :refer [list-view]] - [syng-im.components.styles :refer [font - title-font - color-white - color-black - color-blue - text1-color - text2-color - toolbar-background1]] [syng-im.components.toolbar :refer [toolbar]] [syng-im.utils.listview :refer [to-realm-datasource]] - [syng-im.components.chats.new-participant-contact :refer [new-participant-contact]] + [syng-im.components.chats.new-participant-contact + :refer [new-participant-contact]] [reagent.core :as r] - [syng-im.navigation :refer [nav-pop]])) + [syng-im.components.chat.chat-message-styles :as st])) (defn new-participants-toolbar [navigator] - [toolbar {:navigator navigator - :title "Add Participants" - :action {:image {:source res/v ;; {:uri "icon_search"} - :style {:width 20 - :height 18}} - :handler (fn [] - (dispatch [:add-new-participants navigator]))}}]) + [toolbar + {:navigator navigator + :title "Add Participants" + :action {:image {:source res/v ;; {:uri "icon_search"} + :style st/new-participant-image} + :handler #(dispatch [:add-new-participants navigator])}}]) + +(defn new-participants-row [navigator] + (fn [row _ _] + (r/as-element + [new-participant-contact (js->clj row :keywordize-keys true) navigator]))) (defn new-participants [{:keys [navigator]}] (let [contacts (subscribe [:all-new-contacts])] (fn [] (let [contacts-ds (to-realm-datasource @contacts)] - [view {:style {:flex 1 - :backgroundColor "white"}} + [view st/participants-container [new-participants-toolbar navigator] [list-view {:dataSource contacts-ds :enableEmptySections true - :renderRow (fn [row section-id row-id] - (r/as-element [new-participant-contact (js->clj row :keywordize-keys true) navigator])) - :style {:backgroundColor "white"}}]])))) + :renderRow (new-participants-row navigator) + :style st/participants-list}]])))) diff --git a/src/syng_im/components/chat/plain_message_input.cljs b/src/syng_im/components/chat/plain_message_input.cljs index 14d5600cce..f90fa057cc 100644 --- a/src/syng_im/components/chat/plain_message_input.cljs +++ b/src/syng_im/components/chat/plain_message_input.cljs @@ -1,16 +1,11 @@ (ns syng-im.components.chat.plain-message-input (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] - [syng-im.components.react :refer [android? - view - image + [syng-im.components.react :refer [view + icon touchable-highlight 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.components.chat.plain-message-input-styles :as st])) (defn set-input-message [message] (dispatch [:set-chat-input-text message])) @@ -29,49 +24,18 @@ staged-commands-atom (subscribe [:get-chat-staged-commands])] (fn [] (let [input-message @input-message-atom] - [view {:style {:flexDirection :column}} + [view st/input-container [suggestions-view] - [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 - :style {:flex 1 - :marginLeft 16 - :marginTop -2 - :padding 0 - :fontSize 14 - :fontFamily font - :color text2-color} - :autoFocus (pos? (count @staged-commands-atom)) - :placeholder "Type" - :placeholderTextColor text2-color - :onChangeText set-input-message - :onSubmitEditing #(send @chat input-message)} + [view st/input-view + [icon :list st/list-icon] + [text-input {:style st/message-input + :autoFocus (pos? (count @staged-commands-atom)) + :onChangeText set-input-message + :onSubmitEditing #(send @chat input-message)} input-message] - [image {:source {:uri :icon_smile} - :style {:marginTop 18 - :marginRight 18 - :width 20 - :height 20}}] + [icon :smile st/smile-icon] (when (or (pos? (count input-message)) (pos? (count @staged-commands-atom))) - [touchable-highlight {:on-press #(send @chat input-message) - :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 #(send @chat input-message)} + [view st/send-container + [icon :send st/send-icon]]])]])))) diff --git a/src/syng_im/components/chat/plain_message_input_styles.cljs b/src/syng_im/components/chat/plain_message_input_styles.cljs new file mode 100644 index 0000000000..01b90f2bf8 --- /dev/null +++ b/src/syng_im/components/chat/plain_message_input_styles.cljs @@ -0,0 +1,50 @@ +(ns syng-im.components.chat.plain-message-input-styles + (:require [syng-im.components.styles :refer [font + text2-color + color-white + color-blue]])) + +(def input-container + {:flexDirection :column}) + +(def input-view + {:flexDirection :row + :height 56 + :backgroundColor color-white}) + +(def list-icon + {:marginTop 22 + :marginRight 6 + :marginBottom 6 + :marginLeft 21 + :width 13 + :height 12}) + +(def message-input + {:flex 1 + :marginLeft 16 + :marginTop -2 + :padding 0 + :fontSize 14 + :fontFamily font + :color text2-color}) + +(def smile-icon + {:marginTop 18 + :marginRight 18 + :width 20 + :height 20}) + +(def send-icon + {:marginTop 10.5 + :marginLeft 12 + :width 15 + :height 15}) + +(def send-container + {:marginTop 10 + :marginRight 10 + :width 36 + :height 36 + :borderRadius 50 + :backgroundColor color-blue}) diff --git a/src/syng_im/components/chat/remove_participants.cljs b/src/syng_im/components/chat/remove_participants.cljs index 59474ea116..d9c5053c2d 100644 --- a/src/syng_im/components/chat/remove_participants.cljs +++ b/src/syng_im/components/chat/remove_participants.cljs @@ -1,41 +1,36 @@ (ns syng-im.components.chat.remove-participants - (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] + (:require [re-frame.core :refer [subscribe dispatch]] [syng-im.resources :as res] [syng-im.components.react :refer [view text-input text image touchable-highlight]] [syng-im.components.realm :refer [list-view]] - [syng-im.components.styles :refer [font - title-font - color-white - color-black - color-blue - text1-color - text2-color - toolbar-background1]] [syng-im.components.toolbar :refer [toolbar]] [syng-im.utils.listview :refer [to-realm-datasource]] - [syng-im.components.chats.new-participant-contact :refer [new-participant-contact]] + [syng-im.components.chats.new-participant-contact + :refer [new-participant-contact]] [reagent.core :as r] - [syng-im.navigation :refer [nav-pop]])) + [syng-im.components.chat.chat-message-styles :as st])) (defn remove-participants-toolbar [navigator] - [toolbar {:navigator navigator - :title "Remove Participants" - :action {:image {:source res/trash-icon ;; {:uri "icon_search"} - :style {:width 22 - :height 30}} - :handler (fn [] - (dispatch [:remove-selected-participants navigator]))}}]) + [toolbar + {:navigator navigator + :title "Remove Participants" + :action {:handler #(dispatch [:remove-selected-participants navigator]) + :image {:source res/trash-icon ;; {:uri "icon_search"} + :style st/remove-participants-image}}}]) + +(defn remove-participants-row [navigator] + (fn [row _ _] + (r/as-element + [new-participant-contact (js->clj row :keywordize-keys true) navigator]))) (defn remove-participants [{:keys [navigator]}] (let [contacts (subscribe [:current-chat-contacts])] (fn [] (let [contacts-ds (to-realm-datasource @contacts)] - [view {:style {:flex 1 - :backgroundColor "white"}} + [view st/participants-container [remove-participants-toolbar navigator] [list-view {:dataSource contacts-ds :enableEmptySections true - :renderRow (fn [row section-id row-id] - (r/as-element [new-participant-contact (js->clj row :keywordize-keys true) navigator])) - :style {:backgroundColor "white"}}]])))) + :renderRow (remove-participants-row navigator) + :style st/participants-list}]])))) diff --git a/src/syng_im/components/chat/suggestions.cljs b/src/syng_im/components/chat/suggestions.cljs index 6729c1a4fa..b1bbd0d75e 100644 --- a/src/syng_im/components/chat/suggestions.cljs +++ b/src/syng_im/components/chat/suggestions.cljs @@ -1,56 +1,29 @@ (ns syng-im.components.chat.suggestions (:require-macros [natal-shell.core :refer [with-error-view]]) - (:require [clojure.string :as cstr] - [reagent.core :as r] - [re-frame.core :refer [subscribe dispatch dispatch-sync]] + (:require [re-frame.core :refer [subscribe dispatch]] [syng-im.components.react :refer [view - image text touchable-highlight list-view list-item]] - [syng-im.components.styles :refer [font - color-white]] [syng-im.utils.listview :refer [to-datasource]] - [syng-im.utils.utils :refer [log toast http-post]] - [syng-im.utils.logging :as log])) + [syng-im.components.chat.suggestions-styles :as st])) (defn set-command-input [command] (dispatch [:set-chat-command command])) (defn suggestion-list-item [suggestion] - [touchable-highlight {:onPress (fn [] - (set-command-input (keyword (:command suggestion)))) - :underlay-color :transparent} - [view {:style {:flexDirection "row" - :marginVertical 1 - :marginHorizontal 0 - :height 40 - :backgroundColor color-white}} - [view {:style {:flexDirection "column" - :position "absolute" - :top 10 - :left 60 - :backgroundColor (:color suggestion) - :borderRadius 10}} - [text {:style {:marginTop -2 - :marginHorizontal 10 - :fontSize 14 - :fontFamily font - :color color-white}} + [touchable-highlight + {:onPress #(set-command-input (keyword (:command suggestion)))} + [view st/suggestion-item-container + [view (st/suggestion-background suggestion) + [text {:style st/suggestion-text} (:text suggestion)]] - [text {:style {:flex 1 - :position "absolute" - :top 7 - :left 190 - :lineHeight 18 - :fontSize 14 - :fontFamily font - :color "black"}} + [text {:style st/suggestion-description} (:description suggestion)]]]) -(defn render-row [row section-id row-id] +(defn render-row [row _ _] (list-item [suggestion-list-item (js->clj row :keywordize-keys true)])) (defn suggestions-view [] @@ -58,12 +31,7 @@ (fn [] (let [suggestions @suggestions-atom] (when (seq suggestions) - [view {:style {:flexDirection "row" - :marginVertical 1 - :marginHorizontal 0 - :height (min 105 (* 42 (count suggestions))) - :backgroundColor color-white - :borderRadius 5}} + [view (st/suggestions-container suggestions) [list-view {:dataSource (to-datasource suggestions) :enableEmptySections true :renderRow render-row diff --git a/src/syng_im/components/chat/suggestions_styles.cljs b/src/syng_im/components/chat/suggestions_styles.cljs new file mode 100644 index 0000000000..80ae964e68 --- /dev/null +++ b/src/syng_im/components/chat/suggestions_styles.cljs @@ -0,0 +1,44 @@ +(ns syng-im.components.chat.suggestions-styles + (:require [syng-im.components.styles :refer [font color-white]])) + +(def suggestion-item-container + {:flexDirection :row + :marginVertical 1 + :marginHorizontal 0 + :height 40 + :backgroundColor color-white}) + +(defn suggestion-background + [{:keys [color]}] + {:flexDirection :column + :position :absolute + :top 10 + :left 60 + :backgroundColor color + :borderRadius 10}) + +(def suggestion-text + {:marginTop -2 + :marginHorizontal 10 + :fontSize 14 + :fontFamily font + :color color-white}) + +(def suggestion-description + {:flex 1 + :position :absolute + :top 7 + :left 190 + :lineHeight 18 + :fontSize 14 + :fontFamily font + :color :black}) + +(defn suggestions-container + [suggestions] + {:flexDirection :row + :marginVertical 1 + :marginHorizontal 0 + :height (min 105 (* 42 (count suggestions))) + :backgroundColor color-white + :borderRadius 5}) diff --git a/src/syng_im/components/chat_styles.cljs b/src/syng_im/components/chat_styles.cljs new file mode 100644 index 0000000000..f66e57ed89 --- /dev/null +++ b/src/syng_im/components/chat_styles.cljs @@ -0,0 +1,169 @@ +(ns syng-im.components.chat-styles + (:require [syng-im.components.styles :refer [font + title-font + color-white + chat-background + online-color + selected-message-color + separator-color + text1-color + text2-color + toolbar-background1]])) + +(def chat-view + {:flex 1 + :backgroundColor chat-background}) + +(def toolbar-view + {:flexDirection :row + :height 56 + :backgroundColor toolbar-background1 + :elevation 2}) + +(def icon-view + {:width 56 + :height 56}) + +(def back-icon + {:marginTop 21 + :marginLeft 23 + :width 8 + :height 14}) + +(defn chat-name-view [show-actions] + {:flex 1 + :marginLeft (if show-actions 16 0) + :alignItems :flex-start + :justifyContent :center}) + +(def chat-name-text + {:marginTop -2.5 + :color text1-color + :fontSize 16 + :fontFamily font}) + +(def group-icon + {:marginTop 4 + :width 14 + :height 9}) + +(def up-icon + {:marginTop 23 + :marginLeft 21 + :width 14 + :height 8}) + +(def members + {:marginTop -0.5 + :marginLeft 4 + :fontFamily font + :fontSize 12 + :color text2-color}) + +(def last-activity + {:marginTop 1 + :color text2-color + :fontSize 12 + :fontFamily font}) + +(def actions-wrapper + {:backgroundColor toolbar-background1 + :elevation 2 + :position :absolute + :top 56 + :left 0 + :right 0}) + +(def actions-separator + {:marginLeft 16 + :height 1.5 + :backgroundColor separator-color}) + +(def actions-view + {:marginVertical 10}) + +(def action-icon-row + {:flexDirection :row + :height 56}) + +(def action-icon-view + (merge icon-view + {:alignItems :center + :justifyContent :center})) + +(def action-view + {:flex 1 + :alignItems :flex-start + :justifyContent :center}) + +(def action-title + {:marginTop -2.5 + :color text1-color + :fontSize 14 + :fontFamily font}) + +(def action-subtitle + {:marginTop 1 + :color text2-color + :fontSize 12 + :fontFamily font}) + +(def online-view + {:position :absolute + :top 30 + :left 30 + :width 20 + :height 20 + :borderRadius 50 + :backgroundColor online-color + :borderWidth 2 + :borderColor color-white}) + +(def online-dot + {:position :absolute + :top 6 + :width 4 + :height 4 + :borderRadius 50 + :backgroundColor color-white}) + +(def online-dot-left (merge online-dot {:left 3})) +(def online-dot-right (merge online-dot {:left 9})) + +(def typing-all + {:marginBottom 20}) + +(def typing-view + {:width 260 + :marginTop 10 + :paddingLeft 8 + :paddingRight 8 + :alignItems :flex-start + :alignSelf :flex-start}) + +(def typing-background + {:borderRadius 14 + :padding 12 + :height 38 + :backgroundColor selected-message-color}) + +(def typing-text + {:marginTop -2 + :fontSize 12 + :fontFamily font + :color text2-color}) + +(def chat-photo + {:borderRadius 50 + :width 36 + :height 36}) + +(def actions-overlay + {:position :absolute + :top 0 + :bottom 0 + :left 0 + :right 0}) + +(def overlay-highlight + {:flex 1}) diff --git a/src/syng_im/components/chats/chat_list_item.cljs b/src/syng_im/components/chats/chat_list_item.cljs index 42d33c5a58..a6cc0dc5a1 100644 --- a/src/syng_im/components/chats/chat_list_item.cljs +++ b/src/syng_im/components/chats/chat_list_item.cljs @@ -10,9 +10,8 @@ [syng-im.resources :as res])) (defn chat-list-item [chat-obj navigator] - [touchable-highlight {:on-press (fn [] - (dispatch [:show-chat (aget chat-obj "chat-id") navigator :push])) - :underlay-color :transparent} + [touchable-highlight + {:on-press #(dispatch [:show-chat (aget chat-obj "chat-id") navigator :push])} ;; TODO add [photo-path delivery-status new-messages-count online] values to chat-obj ;; TODO should chat-obj be clj-map? [view {} [chat-list-item-inner-view (merge (js->clj chat-obj :keywordize-keys true) diff --git a/src/syng_im/components/chats/new_group.cljs b/src/syng_im/components/chats/new_group.cljs index 51fec1a25b..5ec1cb1066 100644 --- a/src/syng_im/components/chats/new_group.cljs +++ b/src/syng_im/components/chats/new_group.cljs @@ -68,8 +68,7 @@ :fontSize 14 :lineHeight 20}} "Members"] - [touchable-highlight {:on-press (fn []) - :underlay-color :transparent} + [touchable-highlight {:on-press (fn [])} [view {:style {:flexDirection "row" :marginBottom 16}} [image {:source {:uri "icon_add_gray"} diff --git a/src/syng_im/components/contact_list/contact.cljs b/src/syng_im/components/contact_list/contact.cljs index beb8dcca88..52bce8b6a7 100644 --- a/src/syng_im/components/contact_list/contact.cljs +++ b/src/syng_im/components/contact_list/contact.cljs @@ -9,7 +9,5 @@ (defn contact-view [{:keys [navigator contact]}] (let [{:keys [whisper-identity]} contact] - [touchable-highlight {:onPress (fn [] - (show-chat navigator whisper-identity)) - :underlay-color :transparent} + [touchable-highlight {:onPress #(show-chat navigator whisper-identity)} [view {} [contact-inner-view contact]]])) diff --git a/src/syng_im/components/react.cljs b/src/syng_im/components/react.cljs index 2af46cdad3..858786c253 100644 --- a/src/syng_im/components/react.cljs +++ b/src/syng_im/components/react.cljs @@ -1,5 +1,6 @@ (ns syng-im.components.react - (:require [reagent.core :as r])) + (:require [reagent.core :as r] + [syng-im.components.styles :as st])) (set! js/window.React (js/require "react-native")) @@ -8,14 +9,30 @@ (def text (r/adapt-react-class (.-Text js/React))) (def view (r/adapt-react-class (.-View js/React))) (def image (r/adapt-react-class (.-Image js/React))) -(def touchable-highlight (r/adapt-react-class (.-TouchableHighlight js/React))) +(def touchable-highlight-class (r/adapt-react-class (.-TouchableHighlight js/React))) +(defn touchable-highlight [props content] + [touchable-highlight-class + (merge {:underlay-color :transparent} props) + content]) (def toolbar-android (r/adapt-react-class (.-ToolbarAndroid js/React))) (def list-view (r/adapt-react-class (.-ListView js/React))) (def scroll-view (r/adapt-react-class (.-ScrollView js/React))) -(def text-input (r/adapt-react-class (.-TextInput js/React))) +(def text-input-class (r/adapt-react-class (.-TextInput js/React))) +(defn text-input [props text] + [text-input-class (merge + {:underlineColorAndroid :transparent + :placeholderTextColor st/text2-color + :placeholder "Type"} + props) + text]) (def drawer-layout-android (r/adapt-react-class (.-DrawerLayoutAndroid js/React))) (def touchable-opacity (r/adapt-react-class (.-TouchableOpacity js/React))) + +(defn icon [n style] + [image {:source {:uri (keyword (str "icon_" (name n)))} + :style style}]) + (def platform (.. js/React -Platform -OS)) (def android? (= platform "android")) diff --git a/src/syng_im/components/toolbar.cljs b/src/syng_im/components/toolbar.cljs index 94155f8a6f..ad34b23efe 100644 --- a/src/syng_im/components/toolbar.cljs +++ b/src/syng_im/components/toolbar.cljs @@ -24,16 +24,13 @@ :height 56 :elevation 2}} (if nav-action - [touchable-highlight {:on-press (:handler nav-action) - :underlay-color :transparent} + [touchable-highlight {:on-press (:handler nav-action)} [view {:width 56 :height 56 :alignItems "center" :justifyContent "center"} [image (:image nav-action)]]] - [touchable-highlight {:on-press (fn [] - (nav-pop navigator)) - :underlay-color :transparent} + [touchable-highlight {:on-press #(nav-pop navigator)} [view {:width 56 :height 56} [image {:source {:uri "icon_back"} @@ -41,16 +38,15 @@ :marginLeft 23 :width 8 :height 14}}]]]) - [view {:style {:flex 1 - :alignItems "center" + [view {:style {:flex 1 + :alignItems "center" :justifyContent "center"}} [text {:style {:marginTop -2.5 :color text1-color :fontSize 16 :fontFamily font}} title]] - [touchable-highlight {:on-press (:handler action) - :underlay-color :transparent} + [touchable-highlight {:on-press (:handler action)} [view {:width 56 :height 56 :alignItems "center" diff --git a/src/syng_im/handlers.cljs b/src/syng_im/handlers.cljs index 7c22147fbe..5cf4db5609 100644 --- a/src/syng_im/handlers.cljs +++ b/src/syng_im/handlers.cljs @@ -144,35 +144,31 @@ :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))) + [{:keys [new-message]} [_ {chat-id :from}]] + (save-message chat-id new-message)) (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)})] + [db chat-id message] + (let [messages [:chats chat-id :messages]] (update-in db messages conj message))) +(defn check-author-direction + [db chat-id {:keys [from outgoing] :as message}] + (let [previous-message (first (get-in db [:chats chat-id :messages]))] + (merge message + {:same-author (if previous-message + (= (:from previous-message) from) + true) + :same-direction (if previous-message + (= (:outgoing previous-message) outgoing) + true)}))) + (defn receive-message - [db [_ {chat-id :from :as msg}]] - (add-message-to-db db chat-id msg)) + [db [_ {chat-id :from :as message}]] + (let [message' (check-author-direction db chat-id message)] + (-> db + (add-message-to-db chat-id message') + (assoc :new-message message')))) (register-handler :received-msg (-> receive-message @@ -295,41 +291,40 @@ (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 " "))] + (let [text (get-in db [:chats current-chat-id :input-text]) + {:keys [command]} (check-suggestion db (str text " ")) + message (check-author-direction + db current-chat-id + {:msg-id (random/id) + :chat-id current-chat-id + :content text + :to current-chat-id + :from identity + :content-type text-content-type + :outgoing true})] (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}))))) + (assoc db :new-message (when-not (str/blank? text) message))))) (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})) + {:msg-id (random/id) + :from identity + :to chat-id + :content content + :content-type content-type-command + :outgoing true + :handler (:handler staged-command)})) (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 %)) + ;todo this is wrong :( + (map #(check-author-direction db current-chat-id %)) (assoc db :new-commands)))) (defn add-message @@ -373,7 +368,6 @@ (defn handle-commands [{:keys [new-commands]}] - (println new-commands) (doseq [{{content :content} :content handler :handler} new-commands] (when handler diff --git a/src/syng_im/models/commands.cljs b/src/syng_im/models/commands.cljs index f5a6a69c4e..ad6ccaccb3 100644 --- a/src/syng_im/models/commands.cljs +++ b/src/syng_im/models/commands.cljs @@ -130,5 +130,5 @@ (defn parse-command-msg-content [commands content] (update content :command #(find-command commands (keyword %)))) -(defn parse-command-request-msg-content [commands content] +(defn parse-command-request [commands content] (update content :command #(find-command commands (keyword %)))) diff --git a/src/syng_im/subs.cljs b/src/syng_im/subs.cljs index 1518aea41b..749795ede3 100644 --- a/src/syng_im/subs.cljs +++ b/src/syng_im/subs.cljs @@ -17,7 +17,7 @@ get-chat-command get-chat-command-content get-chat-command-request - parse-command-request-msg-content]] + parse-command-request]] [syng-im.handlers.suggestions :refer [get-suggestions]] [syng-im.handlers.content-suggestions :refer [get-content-suggestions]])) @@ -111,9 +111,9 @@ (get @db :signed-up)))) (register-sub - :show-actions - (fn [db _] - (reaction (get-in @db db/show-actions-path)))) + :show-actions + (fn [db _] + (reaction (get-in @db db/show-actions-path)))) (register-sub :get-contacts @@ -167,16 +167,16 @@ (register-sub :navigation-stack (fn [db _] - (:navigation-stack @db))) + (reaction (:navigation-stack @db)))) (register-sub :db (fn [db _] (reaction @db))) (register-sub :chat-properties - (fn [{:keys [current-chat-id] :as db} [_ properties]] + (fn [db [_ properties]] (->> properties (map (fn [k] [k (-> @db - (get-in [:cgats current-chat-id k]) + (get-in [:chats (:current-chat-id @db) k]) (reaction))])) (into {}))))