diff --git a/src/status_im/chat/handlers.cljs b/src/status_im/chat/handlers.cljs index d0a25712fc..8169e91b67 100644 --- a/src/status_im/chat/handlers.cljs +++ b/src/status_im/chat/handlers.cljs @@ -49,23 +49,28 @@ (assoc-in [:chats current-chat-id :command-input] {}) (update-in [:chats current-chat-id :input-text] safe-trim)))) -(defn animate-cancel-command! [db] - (let [height-anim-value (get-in db [:animations :response-suggestions-height]) - to-value 1] - (anim/add-listener height-anim-value +(defn animate-cancel-command! [{{:keys [response-suggestions-height + message-input-buttons-scale + message-input-offset]} :animations}] + (let [height-to-value 1] + (anim/add-listener response-suggestions-height (fn [val] - (when (<= (- to-value delta) (anim/value val) (+ to-value delta)) - (anim/remove-all-listeners height-anim-value) + (when (<= (- height-to-value delta) (anim/value val) (+ height-to-value delta)) + (anim/remove-all-listeners response-suggestions-height) (dispatch [:cancel-command])))) - (anim/start (anim/spring height-anim-value {:toValue to-value - :speed 10 - :bounciness 1})))) + (anim/start (anim/spring response-suggestions-height {:toValue height-to-value + :velocity 1 + :tension 1 + :friction 5})) + (anim/start (anim/timing message-input-buttons-scale {:toValue 1 + :duration response-input-hiding-duration})) + (anim/start (anim/timing message-input-offset {:toValue 0 + :duration response-input-hiding-duration})))) (register-handler :start-cancel-command (after animate-cancel-command!) (fn [db _] - (let [current-chat-id (:current-chat-id db) - hiding? (get-in db [:animations :response-input-is-hiding?])] + (let [hiding? (get-in db [:animations :response-input-is-hiding?])] (if-not hiding? (assoc-in db [:animations :response-input-is-hiding?] true) db)))) @@ -85,8 +90,8 @@ anim-value (get-in db [:animations :response-suggestions-height])] (anim/start (anim/spring anim-value {:toValue height - :speed 10 - :bounciness 10}))))) + :speed 1 + :bounciness 0.2}))))) (register-handler :set-chat-command-content (after update-response-suggestions-height!) @@ -109,10 +114,33 @@ :handler (:handler command)}] (commands/stage-command db command-info)))) +(register-handler :finish-show-response! + (fn [db _] + (assoc-in db [:animations :commands-input-is-switching?] false))) + +(defn animate-show-response! [{{scale-anim-value :message-input-buttons-scale + offset-anim-value :message-input-offset} :animations}] + (let [to-value 0.1 + delta 0.02] + (anim/add-listener scale-anim-value + (fn [val] + (when (<= (- to-value delta) (anim/value val) (+ to-value delta)) + (anim/remove-all-listeners scale-anim-value) + (dispatch [:finish-show-response!])))) + (anim/start (anim/timing scale-anim-value {:toValue to-value + :duration response-input-hiding-duration})) + (anim/start (anim/timing offset-anim-value {:toValue -40 + :duration response-input-hiding-duration})))) + +(defn set-reponse-chat-command [db [_ to-msg-id command-key]] + (-> db + (commands/set-response-chat-command to-msg-id command-key) + (assoc-in [:animations :commands-input-is-switching?] true))) + (register-handler :set-response-chat-command - (after update-response-suggestions-height!) - (fn [db [_ to-msg-id command-key]] - (commands/set-response-chat-command db to-msg-id command-key))) + (-> set-reponse-chat-command + ((after animate-show-response!)) + ((after update-response-suggestions-height!)))) (defn update-text [db [_ text]] diff --git a/src/status_im/chat/styles/plain_input.cljs b/src/status_im/chat/styles/plain_input.cljs index b8806518dd..dc2883a7f2 100644 --- a/src/status_im/chat/styles/plain_input.cljs +++ b/src/status_im/chat/styles/plain_input.cljs @@ -12,12 +12,20 @@ :height 56 :backgroundColor color-white}) -(def switch-commands-touchable +(def message-input-button-touchable {:width 56 :height 56 :alignItems :center :justifyContent :center}) +(defn message-input-button [scale] + {:transform [{:scale scale}]}) + +(defn message-input-container [offset] + {:flex 1 + :transform [{:translateX offset}] + :marginRight offset}) + (def list-icon {:width 13 :height 12}) @@ -35,9 +43,7 @@ :color text2-color}) (def smile-icon - {:marginTop 18 - :marginRight 18 - :width 20 + {:width 20 :height 20}) (def send-icon diff --git a/src/status_im/chat/styles/response.cljs b/src/status_im/chat/styles/response.cljs index 8849708630..a9293b78c5 100644 --- a/src/status_im/chat/styles/response.cljs +++ b/src/status_im/chat/styles/response.cljs @@ -81,10 +81,11 @@ :height 12}) (def command-input - {:flex 1 - :marginLeft 16 - :marginTop -2 - :padding 0 - :fontSize 14 - :fontFamily font - :color text1-color}) + {:flex 1 + :marginLeft 56 + :marginRight 16 + :marginTop -2 + :padding 0 + :fontSize 14 + :fontFamily font + :color text1-color}) diff --git a/src/status_im/chat/views/plain_input.cljs b/src/status_im/chat/views/plain_input.cljs index ae391edb4f..94b9144f9a 100644 --- a/src/status_im/chat/views/plain_input.cljs +++ b/src/status_im/chat/views/plain_input.cljs @@ -2,6 +2,7 @@ (:require-macros [status-im.utils.views :refer [defview]]) (:require [re-frame.core :refer [subscribe dispatch]] [status-im.components.react :refer [view + animated-view icon touchable-highlight text-input @@ -31,67 +32,92 @@ (when (message-valid? staged-commands message) (send dismiss-keyboard))) -(defn plain-message-input-view [{:keys [input-options validator]}] - (let [input-message (subscribe [:get-chat-input-text]) - command (subscribe [:get-chat-command]) - to-msg-id (subscribe [:get-chat-command-to-msg-id]) - input-command (subscribe [:get-chat-command-content]) - staged-commands (subscribe [:get-chat-staged-commands]) - typing-command? (subscribe [:typing-command?])] - (fn [{:keys [input-options validator]}] - (let [dismiss-keyboard (not (or command @typing-command?)) - command @command - response? (and command @to-msg-id)] - [view st/input-container - (cond - response? [response/request-view] - command [content-suggestions-view] - :else [suggestions-view]) - [view st/input-view - (if command - (when-not response? - [command/command-icon command response?]) - [touchable-highlight {:on-press #(dispatch [:switch-command-suggestions]) - :style st/switch-commands-touchable} - [view nil - (if @typing-command? - [icon :close-gray st/close-icon] - [icon :list st/list-icon])]]) - [text-input (merge {:style (cond - response? st-response/command-input - command st-command/command-input - :else st/message-input) - :autoFocus false - :blurOnSubmit dismiss-keyboard - :onChangeText (fn [text] - ((if command - command/set-input-message - set-input-message) - text)) - :onSubmitEditing (fn [] - (if command - (command/try-send @input-command validator) - (try-send @staged-commands - @input-message - dismiss-keyboard)))} - input-options) - (if command - @input-command - @input-message)] - ;; TODO emoticons: not implemented - (when (not command) - [icon :smile st/smile-icon]) - (if command - (if (command/valid? @input-command validator) - [touchable-highlight {:on-press command/send-command} - [view st/send-container [icon :send st/send-icon]]] - (when-not response? - [touchable-highlight {:on-press command/cancel-command-input} - [view st-command/cancel-container - [icon :close-gray st-command/cancel-icon]]])) - (when (message-valid? @staged-commands @input-message) - [touchable-highlight {:on-press #(try-send @staged-commands - @input-message - dismiss-keyboard)} - [view st/send-container - [icon :send st/send-icon]]]))]])))) +(defview commands-button [animation?] + [typing-command? [:typing-command?] + buttons-scale [:get-in [:animations :message-input-buttons-scale]]] + [touchable-highlight {:disabled animation? + :on-press #(dispatch [:switch-command-suggestions]) + :style st/message-input-button-touchable} + [animated-view {:style (st/message-input-button buttons-scale)} + (if typing-command? + [icon :close-gray st/close-icon] + [icon :list st/list-icon])]]) + +(defview smile-button [animation?] + [buttons-scale [:get-in [:animations :message-input-buttons-scale]]] + [touchable-highlight {:disabled animation? + :on-press #(dispatch [:switch-command-suggestions]) + :style st/message-input-button-touchable} + [animated-view {:style (st/message-input-button buttons-scale)} + [icon :smile st/smile-icon]]]) + +(defview message-input-container [input] + [message-input-offset [:get-in [:animations :message-input-offset]]] + [animated-view {:style (st/message-input-container message-input-offset)} + input]) + +(defview plain-message-input-view [{:keys [input-options validator]}] + [input-message [:get-chat-input-text] + command [:get-chat-command] + to-msg-id [:get-chat-command-to-msg-id] + input-command [:get-chat-command-content] + staged-commands [:get-chat-staged-commands] + typing-command? [:typing-command?] + response-input-is-hiding? [:get-in [:animations :response-input-is-hiding?]] + commands-button-is-switching? [:get-in [:animations :commands-input-is-switching?]]] + (let [dismiss-keyboard (not (or command typing-command?)) + response? (and command to-msg-id) + message-input? (or (not command) response-input-is-hiding? commands-button-is-switching?) + animation? (or response-input-is-hiding? commands-button-is-switching?)] + [view st/input-container + (cond + response? [response/request-view] + command [content-suggestions-view] + :else [suggestions-view]) + [view st/input-view + (if message-input? + [commands-button animation?] + (when (and command (not response?)) + [command/command-icon command response?])) + [message-input-container + [text-input (merge {:style (cond + message-input? st/message-input + response? st-response/command-input + command st-command/command-input) + :autoFocus false + :blurOnSubmit dismiss-keyboard + :onChangeText (fn [text] + ((if message-input? + set-input-message + command/set-input-message) + text)) + :editable (not animation?) + :onSubmitEditing #(if message-input? + (try-send staged-commands + input-message + dismiss-keyboard) + (command/try-send input-command validator))} + input-options) + (if message-input? + input-message + input-command)]] + ;; TODO emoticons: not implemented + (when message-input? + [smile-button animation?]) + (if message-input? + (when (message-valid? staged-commands input-message) + [touchable-highlight {:disabled animation? + :on-press #(try-send staged-commands + input-message + dismiss-keyboard)} + [view st/send-container + [icon :send st/send-icon]]]) + (if (command/valid? input-command validator) + [touchable-highlight {:disabled animation? + :on-press command/send-command} + [view st/send-container [icon :send st/send-icon]]] + (when-not response? + [touchable-highlight {:disabled animation? + :on-press command/cancel-command-input} + [view st-command/cancel-container + [icon :close-gray st-command/cancel-icon]]])))]])) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index ec1ba801e2..556f9b7898 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -13,5 +13,5 @@ (def max-chat-name-length 20) -(def response-input-hiding-duration 200) +(def response-input-hiding-duration 300) (def response-suggesstion-resize-duration 100) diff --git a/src/status_im/db.cljs b/src/status_im/db.cljs index f38d4f870f..2ffdc70d88 100644 --- a/src/status_im/db.cljs +++ b/src/status_im/db.cljs @@ -33,8 +33,11 @@ :current-tag nil :disable-group-creation false :animations {;; mutable data - :response-suggestions-height (anim/create-value 0) - :response-input-is-hiding? false}}) + :message-input-offset (anim/create-value 0) + :message-input-buttons-scale (anim/create-value 1) + :commands-input-is-switching? false + :response-suggestions-height (anim/create-value 0) + :response-input-is-hiding? false}}) (def protocol-initialized-path [:protocol-initialized]) (defn chat-input-text-path [chat-id]