Response suggestions dragging (minimize/maximize)

Former-commit-id: cad5cbaf10
This commit is contained in:
virvar 2016-06-02 15:53:13 +03:00
parent 51287cd47a
commit 60ee2d132c
12 changed files with 128 additions and 64 deletions

View File

@ -46,23 +46,23 @@
(register-handler :cancel-command (register-handler :cancel-command
(fn [{:keys [current-chat-id] :as db} _] (fn [{:keys [current-chat-id] :as db} _]
(-> 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] {}) (assoc-in [:chats current-chat-id :command-input] {})
(update-in [:chats current-chat-id :input-text] safe-trim)))) (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-buttons-scale
message-input-offset]} :animations}] message-input-offset]} :animations}]
(let [height-to-value 1] (let [height-to-value 1]
(anim/add-listener response-suggestions-height (anim/add-listener response-height-anim-value
(fn [val] (fn [val]
(when (<= (- height-to-value delta) (anim/value val) (+ height-to-value delta)) (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])))) (dispatch [:cancel-command]))))
(anim/start (anim/spring response-suggestions-height {:toValue height-to-value (anim/start (anim/spring response-height-anim-value {:toValue height-to-value
:velocity 1 :velocity 1
:tension 1 :tension 1
:friction 5})) :friction 5}))
(anim/start (anim/timing message-input-buttons-scale {:toValue 1 (anim/start (anim/timing message-input-buttons-scale {:toValue 1
:duration response-input-hiding-duration})) :duration response-input-hiding-duration}))
(anim/start (anim/timing message-input-offset {:toValue 0 (anim/start (anim/timing message-input-offset {:toValue 0
@ -71,14 +71,13 @@
(register-handler :start-cancel-command (register-handler :start-cancel-command
(after animate-cancel-command!) (after animate-cancel-command!)
(fn [db _] (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? (if-not hiding?
(assoc-in db [:animations :response-input-is-hiding?] true) (assoc-in db [:animations :commands-input-is-switching?] true)
db)))) db))))
(defn update-response-suggestions-height! [db] (defn update-response-suggestions-height! [db]
(when (and (not (get-in db [:animations :response-input-is-hiding?])) (when (commands/get-chat-command-to-msg-id db)
(commands/get-chat-command-to-msg-id db))
(let [command (commands/get-chat-command db) (let [command (commands/get-chat-command db)
text (commands/get-chat-command-content db) text (commands/get-chat-command-content db)
suggestions (get-content-suggestions command text) suggestions (get-content-suggestions command text)
@ -88,7 +87,7 @@
response-suggestions-styles/suggestion-height) response-suggestions-styles/suggestion-height)
suggestions))) suggestions)))
height (+ suggestions-height response-styles/request-info-height) 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/start
(anim/spring anim-value {:toValue height (anim/spring anim-value {:toValue height
:speed 1 :speed 1
@ -329,18 +328,62 @@
messages/get-messages messages/get-messages
(assoc db :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 (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] :on-release (fn [e gesture]
(anim/start (anim/spring pan (dispatch [:fix-response-height]))}))
{:toValue {:x 0, :y 0}})))}))
(defn init-response-dragging [db] (defn init-response-dragging [db]
(let [pan (anim/create-value-xy 0 0)] (let [height response-suggestions-styles/max-suggestions-height]
(-> db (-> db
(assoc-in [:animations :response-pan] pan) (assoc-in [:animations :response-height-fixed] height)
(assoc-in [:animations :response-pan-responder] (create-response-pan-responder pan))))) (assoc-in [:animations :response-height] height)
(assoc-in [:animations :response-pan-responder] (create-response-pan-responder)))))
(defn init-chat (defn init-chat
([db] (init-chat db nil)) ([db] (init-chat db nil))

View File

@ -17,6 +17,9 @@
[status-im.components.invertible-scroll-view :refer [invertible-scroll-view]] [status-im.components.invertible-scroll-view :refer [invertible-scroll-view]]
[status-im.components.toolbar :refer [toolbar]] [status-im.components.toolbar :refer [toolbar]]
[status-im.chat.views.message :refer [chat-message]] [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]])) [status-im.chat.views.new-message :refer [chat-message-new]]))
@ -229,10 +232,16 @@
(defview chat [] (defview chat []
[group-chat [:chat :group-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 [view st/chat-view
[chat-toolbar] [chat-toolbar]
[messages-view group-chat] [messages-view group-chat]
(when group-chat [typing-all]) (when group-chat [typing-all])
(cond
(and command to-msg-id) [request-view]
command [content-suggestions-view]
:else [suggestions-view])
[chat-message-new] [chat-message-new]
(when show-actions-atom [actions-view])]) (when show-actions-atom [actions-view])])

View File

@ -44,6 +44,9 @@
:backgroundColor color-white :backgroundColor color-white
:borderRadius 5}) :borderRadius 5})
(def container
{:backgroundColor color-white})
(def drag-down-touchable (def drag-down-touchable
{:height 22 {:height 22
:alignItems :center :alignItems :center

View File

@ -7,21 +7,16 @@
chat-background chat-background
color-black]])) color-black]]))
(def response-height-normal 211)
(def request-info-height 61) (def request-info-height 61)
(def drag-touchable
{:height 16
:alignItems :center})
(def drag-container (def drag-container
{:width 16 {:height 16
:height 16}) :alignItems :center
:justifyContent :center})
(def drag-icon (def drag-icon
{:position :absolute {:width 14
:top 6.5
:left 1
:width 14
:height 3}) :height 3})
(def command-icon-container (def command-icon-container
@ -55,9 +50,21 @@
:opacity 0.69 :opacity 0.69
:color color-white}) :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] (defn request-view [height]
{:flexDirection :column {:flexDirection :column
:height height}) :height height
:backgroundColor color-white})
(defn request-info [color] (defn request-info [color]
{:flexDirection :column {:flexDirection :column

View File

@ -31,7 +31,7 @@
(def suggestion-container (def suggestion-container
{:flexDirection :column {:flexDirection :column
:paddingLeft 16 :paddingLeft 16
:height 56 :height suggestion-height
:backgroundColor color-white}) :backgroundColor color-white})
(def suggestion-sub-container (def suggestion-sub-container

View File

@ -59,6 +59,9 @@
:backgroundColor color-white :backgroundColor color-white
:borderRadius 5}) :borderRadius 5})
(def container
{:backgroundColor color-white})
(def drag-down-touchable (def drag-down-touchable
{:height 22 {:height 22
:alignItems :center :alignItems :center

View File

@ -26,7 +26,7 @@
(defview content-suggestions-view [] (defview content-suggestions-view []
[suggestions [:get-content-suggestions]] [suggestions [:get-content-suggestions]]
(when-let [values (not-empty (filter :value suggestions))] (when-let [values (not-empty (filter :value suggestions))]
[view [view st/container
[touchable-highlight {:style st/drag-down-touchable [touchable-highlight {:style st/drag-down-touchable
;; TODO hide suggestions? ;; TODO hide suggestions?
:onPress (fn [])} :onPress (fn [])}

View File

@ -7,8 +7,6 @@
touchable-highlight touchable-highlight
text-input text-input
dismiss-keyboard!]] 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.command :as command]
[status-im.chat.views.response :as response] [status-im.chat.views.response :as response]
[status-im.chat.styles.plain-input :as st] [status-im.chat.styles.plain-input :as st]
@ -63,17 +61,12 @@
input-command [:get-chat-command-content] input-command [:get-chat-command-content]
staged-commands [:get-chat-staged-commands] staged-commands [:get-chat-staged-commands]
typing-command? [:typing-command?] 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?]]] commands-button-is-switching? [:get-in [:animations :commands-input-is-switching?]]]
(let [dismiss-keyboard (not (or command typing-command?)) (let [dismiss-keyboard (not (or command typing-command?))
response? (and command to-msg-id) response? (and command to-msg-id)
message-input? (or (not command) response-input-is-hiding? commands-button-is-switching?) message-input? (or (not command) commands-button-is-switching?)
animation? (or response-input-is-hiding? commands-button-is-switching?)] animation? commands-button-is-switching?]
[view st/input-container [view st/input-container
(cond
response? [response/request-view]
command [content-suggestions-view]
:else [suggestions-view])
[view st/input-view [view st/input-view
(if message-input? (if message-input?
[commands-button animation?] [commands-button animation?]

View File

@ -8,18 +8,13 @@
text text
text-input text-input
touchable-highlight]] touchable-highlight]]
[status-im.components.animation :as anim]
[status-im.components.drag-drop :as drag] [status-im.components.drag-drop :as drag]
[status-im.chat.views.response-suggestions :refer [response-suggestions-view]] [status-im.chat.views.response-suggestions :refer [response-suggestions-view]]
[status-im.chat.styles.response :as st])) [status-im.chat.styles.response :as st]))
(defn drag-touchable [] (defn drag-icon []
[touchable-highlight {:style st/drag-touchable [view st/drag-container
:onPress (fn [] [icon :drag-white st/drag-icon]])
;; TODO drag up/down
)}
[view st/drag-container
[icon :drag-white st/drag-icon]]])
(defn command-icon [] (defn command-icon []
[view st/command-icon-container [view st/command-icon-container
@ -37,7 +32,7 @@
(defview request-info [] (defview request-info []
[command [:get-chat-command]] [command [:get-chat-command]]
[view (st/request-info (:color command)) [view (st/request-info (:color command))
[drag-touchable] [drag-icon]
[view st/inner-container [view st/inner-container
[command-icon nil] [command-icon nil]
[info-container command] [info-container command]
@ -46,11 +41,18 @@
[icon :close-white st/cancel-icon]]]]]) [icon :close-white st/cancel-icon]]]]])
(defview request-view [] (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-responder [:get-in [:animations :response-pan-responder]]
pan [:get-in [:animations :response-pan]]] response-height [:get-in [:animations :response-height]]
[animated-view (merge (drag/pan-handlers pan-responder) commands-input-is-switching? [:get-in [:animations :commands-input-is-switching?]]
{:style (merge (anim/get-layout pan) response-resize? [:get-in [:animations :response-resize?]]]
(st/request-view height))}) [view {:style st/container
[request-info] :onLayout (fn [event]
[response-suggestions-view]]) (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]]])

View File

@ -33,7 +33,7 @@
(fn [] (fn []
(let [suggestions @suggestions-atom] (let [suggestions @suggestions-atom]
(when (seq suggestions) (when (seq suggestions)
[view [view st/container
[touchable-highlight {:style st/drag-down-touchable [touchable-highlight {:style st/drag-down-touchable
:onPress (fn [] :onPress (fn []
;; TODO hide suggestions? ;; TODO hide suggestions?

View File

@ -39,6 +39,9 @@
(def animated-view (r/adapt-react-class (.-View animated))) (def animated-view (r/adapt-react-class (.-View animated)))
(def animated-text (r/adapt-react-class (.-Text 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 (defn icon
([n] (icon n {})) ([n] (icon n {}))

View File

@ -33,13 +33,14 @@
:current-tag nil :current-tag nil
:disable-group-creation false :disable-group-creation false
:animations {;; mutable data :animations {;; mutable data
:response-pan nil :response-height nil
:response-height-fixed nil
:response-pan-responder nil :response-pan-responder nil
:message-input-offset (anim/create-value 0) :message-input-offset (anim/create-value 0)
:message-input-buttons-scale (anim/create-value 1) :message-input-buttons-scale (anim/create-value 1)
:commands-input-is-switching? false :commands-input-is-switching? false
:response-suggestions-height (anim/create-value 0) :response-height-anim-value (anim/create-value 0)
:response-input-is-hiding? false}}) :response-resize? false}})
(def protocol-initialized-path [:protocol-initialized]) (def protocol-initialized-path [:protocol-initialized])
(defn chat-input-text-path [chat-id] (defn chat-input-text-path [chat-id]