From cad5cbaf10aaf835a4cb321993930c7a943be8c9 Mon Sep 17 00:00:00 2001 From: virvar Date: Thu, 2 Jun 2016 15:53:13 +0300 Subject: [PATCH] Response suggestions dragging (minimize/maximize) --- src/status_im/chat/handlers.cljs | 83 ++++++++++++++----- src/status_im/chat/screen.cljs | 11 ++- .../chat/styles/content_suggestions.cljs | 3 + src/status_im/chat/styles/response.cljs | 31 ++++--- .../chat/styles/response_suggestions.cljs | 2 +- src/status_im/chat/styles/suggestions.cljs | 3 + .../chat/views/content_suggestions.cljs | 2 +- src/status_im/chat/views/plain_input.cljs | 11 +-- src/status_im/chat/views/response.cljs | 34 ++++---- src/status_im/chat/views/suggestions.cljs | 2 +- src/status_im/components/react.cljs | 3 + src/status_im/db.cljs | 7 +- 12 files changed, 128 insertions(+), 64 deletions(-) diff --git a/src/status_im/chat/handlers.cljs b/src/status_im/chat/handlers.cljs index 481e5372fc..2f1fd3288c 100644 --- a/src/status_im/chat/handlers.cljs +++ b/src/status_im/chat/handlers.cljs @@ -46,23 +46,23 @@ (register-handler :cancel-command (fn [{:keys [current-chat-id] :as db} _] (-> db - (assoc-in [:animations :response-input-is-hiding?] false) + (assoc-in [:animations :commands-input-is-switching?] false) (assoc-in [:chats current-chat-id :command-input] {}) (update-in [:chats current-chat-id :input-text] safe-trim)))) -(defn animate-cancel-command! [{{:keys [response-suggestions-height +(defn animate-cancel-command! [{{:keys [response-height-anim-value message-input-buttons-scale message-input-offset]} :animations}] (let [height-to-value 1] - (anim/add-listener response-suggestions-height + (anim/add-listener response-height-anim-value (fn [val] (when (<= (- height-to-value delta) (anim/value val) (+ height-to-value delta)) - (anim/remove-all-listeners response-suggestions-height) + (anim/remove-all-listeners response-height-anim-value) (dispatch [:cancel-command])))) - (anim/start (anim/spring response-suggestions-height {:toValue height-to-value - :velocity 1 - :tension 1 - :friction 5})) + (anim/start (anim/spring response-height-anim-value {: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 @@ -71,14 +71,13 @@ (register-handler :start-cancel-command (after animate-cancel-command!) (fn [db _] - (let [hiding? (get-in db [:animations :response-input-is-hiding?])] + (let [hiding? (get-in db [:animations :commands-input-is-switching?])] (if-not hiding? - (assoc-in db [:animations :response-input-is-hiding?] true) + (assoc-in db [:animations :commands-input-is-switching?] true) db)))) (defn update-response-suggestions-height! [db] - (when (and (not (get-in db [:animations :response-input-is-hiding?])) - (commands/get-chat-command-to-msg-id db)) + (when (commands/get-chat-command-to-msg-id db) (let [command (commands/get-chat-command db) text (commands/get-chat-command-content db) suggestions (get-content-suggestions command text) @@ -88,7 +87,7 @@ response-suggestions-styles/suggestion-height) suggestions))) height (+ suggestions-height response-styles/request-info-height) - anim-value (get-in db [:animations :response-suggestions-height])] + anim-value (get-in db [:animations :response-height-anim-value])] (anim/start (anim/spring anim-value {:toValue height :speed 1 @@ -329,18 +328,62 @@ messages/get-messages (assoc db :messages)))) -(defn create-response-pan-responder [pan] +(register-handler :set-response-max-height + (fn [db [_ height]] + (assoc-in db [:animations :response-height-max] height))) + +(register-handler :on-drag-response + (fn [db [_ dy]] + (let [fixed (get-in db [:animations :response-height-fixed])] + (assoc-in db [:animations :response-height] (- fixed dy))))) + +(register-handler :finish-animate-fix-response-height! + (fn [db _] + (let [fixed (get-in db [:animations :response-height-fixed])] + (-> db + (assoc-in [:animations :response-height] fixed) + (assoc-in [:animations :response-resize?] false))))) + +(defn animate-fix-response-height! [{{height-anim-value :response-height-anim-value + from :response-height + to :response-height-fixed} :animations}] + (let [delta 5] + (anim/set-value height-anim-value from) + (anim/add-listener height-anim-value + (fn [val] + (when (<= (- to delta) (anim/value val) (+ to delta)) + (anim/remove-all-listeners height-anim-value) + (dispatch [:finish-animate-fix-response-height!])))) + (anim/start (anim/spring height-anim-value {:toValue to})))) + +(register-handler :fix-response-height + (after animate-fix-response-height!) + (fn [db _] + (let [current (get-in db [:animations :response-height]) + normal-height response-styles/response-height-normal + max-height (get-in db [:animations :response-height-max]) + delta (/ normal-height 2) + new-fixed (cond + (<= current delta) response-styles/request-info-height + (<= current (+ normal-height delta)) normal-height + :else max-height)] + (-> db + (assoc-in [:animations :response-height-fixed] new-fixed) + (assoc-in [:animations :response-resize?] true))))) + +(defn create-response-pan-responder [] (drag/create-pan-responder - {:on-move (anim/event {:dy (anim/y pan)}) + {:on-move (fn [e gesture] + (dispatch [:on-drag-response (.-dy gesture)])) :on-release (fn [e gesture] - (anim/start (anim/spring pan - {:toValue {:x 0, :y 0}})))})) + (dispatch [:fix-response-height]))})) (defn init-response-dragging [db] - (let [pan (anim/create-value-xy 0 0)] + (let [height response-suggestions-styles/max-suggestions-height] (-> db - (assoc-in [:animations :response-pan] pan) - (assoc-in [:animations :response-pan-responder] (create-response-pan-responder pan))))) + (assoc-in [:animations :response-height-fixed] height) + (assoc-in [:animations :response-height] height) + (assoc-in [:animations :response-pan-responder] (create-response-pan-responder))))) (defn init-chat ([db] (init-chat db nil)) diff --git a/src/status_im/chat/screen.cljs b/src/status_im/chat/screen.cljs index 2ed10ba018..a43f16763c 100644 --- a/src/status_im/chat/screen.cljs +++ b/src/status_im/chat/screen.cljs @@ -17,6 +17,9 @@ [status-im.components.invertible-scroll-view :refer [invertible-scroll-view]] [status-im.components.toolbar :refer [toolbar]] [status-im.chat.views.message :refer [chat-message]] + [status-im.chat.views.content-suggestions :refer [content-suggestions-view]] + [status-im.chat.views.suggestions :refer [suggestions-view]] + [status-im.chat.views.response :refer [request-view]] [status-im.chat.views.new-message :refer [chat-message-new]])) @@ -229,10 +232,16 @@ (defview chat [] [group-chat [:chat :group-chat] - show-actions-atom [:show-actions]] + show-actions-atom [:show-actions] + command [:get-chat-command] + to-msg-id [:get-chat-command-to-msg-id]] [view st/chat-view [chat-toolbar] [messages-view group-chat] (when group-chat [typing-all]) + (cond + (and command to-msg-id) [request-view] + command [content-suggestions-view] + :else [suggestions-view]) [chat-message-new] (when show-actions-atom [actions-view])]) diff --git a/src/status_im/chat/styles/content_suggestions.cljs b/src/status_im/chat/styles/content_suggestions.cljs index 198468a549..47ee5fc1fb 100644 --- a/src/status_im/chat/styles/content_suggestions.cljs +++ b/src/status_im/chat/styles/content_suggestions.cljs @@ -44,6 +44,9 @@ :backgroundColor color-white :borderRadius 5}) +(def container + {:backgroundColor color-white}) + (def drag-down-touchable {:height 22 :alignItems :center diff --git a/src/status_im/chat/styles/response.cljs b/src/status_im/chat/styles/response.cljs index a9293b78c5..7125ee4f03 100644 --- a/src/status_im/chat/styles/response.cljs +++ b/src/status_im/chat/styles/response.cljs @@ -7,21 +7,16 @@ chat-background color-black]])) +(def response-height-normal 211) (def request-info-height 61) -(def drag-touchable - {:height 16 - :alignItems :center}) - (def drag-container - {:width 16 - :height 16}) + {:height 16 + :alignItems :center + :justifyContent :center}) (def drag-icon - {:position :absolute - :top 6.5 - :left 1 - :width 14 + {:width 14 :height 3}) (def command-icon-container @@ -55,9 +50,21 @@ :opacity 0.69 :color color-white}) +(def container + {:flexDirection :column + :justifyContent :flex-end + :position :absolute + :left 0 + :right 0 + :top 0 + :bottom 56 + :backgroundColor :transparent + :elevation 2}) + (defn request-view [height] - {:flexDirection :column - :height height}) + {:flexDirection :column + :height height + :backgroundColor color-white}) (defn request-info [color] {:flexDirection :column diff --git a/src/status_im/chat/styles/response_suggestions.cljs b/src/status_im/chat/styles/response_suggestions.cljs index e039264a06..f17a095863 100644 --- a/src/status_im/chat/styles/response_suggestions.cljs +++ b/src/status_im/chat/styles/response_suggestions.cljs @@ -31,7 +31,7 @@ (def suggestion-container {:flexDirection :column :paddingLeft 16 - :height 56 + :height suggestion-height :backgroundColor color-white}) (def suggestion-sub-container diff --git a/src/status_im/chat/styles/suggestions.cljs b/src/status_im/chat/styles/suggestions.cljs index 2d5eaaab8e..0c35347f79 100644 --- a/src/status_im/chat/styles/suggestions.cljs +++ b/src/status_im/chat/styles/suggestions.cljs @@ -59,6 +59,9 @@ :backgroundColor color-white :borderRadius 5}) +(def container + {:backgroundColor color-white}) + (def drag-down-touchable {:height 22 :alignItems :center diff --git a/src/status_im/chat/views/content_suggestions.cljs b/src/status_im/chat/views/content_suggestions.cljs index e200aee8db..4dfefe2cf4 100644 --- a/src/status_im/chat/views/content_suggestions.cljs +++ b/src/status_im/chat/views/content_suggestions.cljs @@ -26,7 +26,7 @@ (defview content-suggestions-view [] [suggestions [:get-content-suggestions]] (when-let [values (not-empty (filter :value suggestions))] - [view + [view st/container [touchable-highlight {:style st/drag-down-touchable ;; TODO hide suggestions? :onPress (fn [])} diff --git a/src/status_im/chat/views/plain_input.cljs b/src/status_im/chat/views/plain_input.cljs index 94b9144f9a..509e961456 100644 --- a/src/status_im/chat/views/plain_input.cljs +++ b/src/status_im/chat/views/plain_input.cljs @@ -7,8 +7,6 @@ touchable-highlight text-input dismiss-keyboard!]] - [status-im.chat.views.suggestions :refer [suggestions-view]] - [status-im.chat.views.content-suggestions :refer [content-suggestions-view]] [status-im.chat.views.command :as command] [status-im.chat.views.response :as response] [status-im.chat.styles.plain-input :as st] @@ -63,17 +61,12 @@ 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?)] + message-input? (or (not command) commands-button-is-switching?) + animation? 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?] diff --git a/src/status_im/chat/views/response.cljs b/src/status_im/chat/views/response.cljs index 4dd39ab9e9..8ca97f69ad 100644 --- a/src/status_im/chat/views/response.cljs +++ b/src/status_im/chat/views/response.cljs @@ -8,18 +8,13 @@ text text-input touchable-highlight]] - [status-im.components.animation :as anim] [status-im.components.drag-drop :as drag] [status-im.chat.views.response-suggestions :refer [response-suggestions-view]] [status-im.chat.styles.response :as st])) -(defn drag-touchable [] - [touchable-highlight {:style st/drag-touchable - :onPress (fn [] - ;; TODO drag up/down - )} - [view st/drag-container - [icon :drag-white st/drag-icon]]]) +(defn drag-icon [] + [view st/drag-container + [icon :drag-white st/drag-icon]]) (defn command-icon [] [view st/command-icon-container @@ -37,7 +32,7 @@ (defview request-info [] [command [:get-chat-command]] [view (st/request-info (:color command)) - [drag-touchable] + [drag-icon] [view st/inner-container [command-icon nil] [info-container command] @@ -46,11 +41,18 @@ [icon :close-white st/cancel-icon]]]]]) (defview request-view [] - [height [:get-in [:animations :response-suggestions-height]] + [height [:get-in [:animations :response-height-anim-value]] pan-responder [:get-in [:animations :response-pan-responder]] - pan [:get-in [:animations :response-pan]]] - [animated-view (merge (drag/pan-handlers pan-responder) - {:style (merge (anim/get-layout pan) - (st/request-view height))}) - [request-info] - [response-suggestions-view]]) + response-height [:get-in [:animations :response-height]] + commands-input-is-switching? [:get-in [:animations :commands-input-is-switching?]] + response-resize? [:get-in [:animations :response-resize?]]] + [view {:style st/container + :onLayout (fn [event] + (let [height (.. event -nativeEvent -layout -height)] + (dispatch [:set-response-max-height height])))} + [animated-view (merge (drag/pan-handlers pan-responder) + {:style (st/request-view (if (or commands-input-is-switching? response-resize?) + height + response-height))}) + [request-info] + [response-suggestions-view]]]) diff --git a/src/status_im/chat/views/suggestions.cljs b/src/status_im/chat/views/suggestions.cljs index 157c23b74e..e0f261542a 100644 --- a/src/status_im/chat/views/suggestions.cljs +++ b/src/status_im/chat/views/suggestions.cljs @@ -33,7 +33,7 @@ (fn [] (let [suggestions @suggestions-atom] (when (seq suggestions) - [view + [view st/container [touchable-highlight {:style st/drag-down-touchable :onPress (fn [] ;; TODO hide suggestions? diff --git a/src/status_im/components/react.cljs b/src/status_im/components/react.cljs index 1967c91801..bd534c2ec1 100644 --- a/src/status_im/components/react.cljs +++ b/src/status_im/components/react.cljs @@ -39,6 +39,9 @@ (def animated-view (r/adapt-react-class (.-View animated))) (def animated-text (r/adapt-react-class (.-Text animated))) +(def dimensions (.-Dimensions js/React)) +(defn get-dimensions [name] + (js->clj (.get dimensions name) :keywordize-keys true)) (defn icon ([n] (icon n {})) diff --git a/src/status_im/db.cljs b/src/status_im/db.cljs index af852299af..dbaba99eaf 100644 --- a/src/status_im/db.cljs +++ b/src/status_im/db.cljs @@ -33,13 +33,14 @@ :current-tag nil :disable-group-creation false :animations {;; mutable data - :response-pan nil + :response-height nil + :response-height-fixed nil :response-pan-responder nil :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}}) + :response-height-anim-value (anim/create-value 0) + :response-resize? false}}) (def protocol-initialized-path [:protocol-initialized]) (defn chat-input-text-path [chat-id]