first attempt

This commit is contained in:
Roman Volosovskyi 2016-06-25 18:44:37 +03:00
parent 923b2af648
commit 6cd5e29c8a
10 changed files with 201 additions and 94 deletions

View File

@ -4,3 +4,4 @@
(def request-info-height 61)
(def response-height-normal 211)
(def minimum-suggestion-height (+ input-height request-info-height))
(def minimum-command-suggestions-height (+ input-height 22))

View File

@ -19,6 +19,7 @@
[status-im.utils.phone-number :refer [format-phone-number]]
[status-im.utils.datetime :as time]
[status-im.components.jail :as j]
[status-im.utils.types :refer [json->clj]]
[status-im.commands.utils :refer [generate-hiccup]]))
(register-handler :set-show-actions
@ -115,9 +116,7 @@
(register-handler :set-response-chat-command
[(after invoke-suggestions-handler!)
(after #(dispatch [:command-edit-mode]))
;(after #(dispatch [:animate-show-response]))
]
(after #(dispatch [:command-edit-mode]))]
(fn [db [_ to-msg-id command-key]]
(commands/set-response-chat-command db to-msg-id command-key)))
@ -133,8 +132,17 @@
db))
db))
(defn check-suggestions
[{:keys [current-chat-id] :as db} [_ text]]
(assoc-in db
[:command-suggestions current-chat-id]
(suggestions/get-suggestions db text)))
(register-handler :set-chat-input-text
((enrich update-command) update-text))
[(enrich update-command)
(enrich check-suggestions)
(after #(dispatch [:animate-command-suggestions]))]
update-text)
(defn console? [s]
(= "console" s))
@ -437,9 +445,11 @@
((after save-chat!))
((after open-chat!))))
(register-handler :switch-command-suggestions
(fn [db [_]]
(suggestions/switch-command-suggestions db)))
(register-handler :switch-command-suggestions!
(u/side-effect!
(fn [db]
(let [text (if (suggestions/typing-command? db) "" "!")]
(dispatch [:set-chat-input-text text])))))
(defn remove-chat
[{:keys [current-chat-id] :as db} _]

View File

@ -3,6 +3,7 @@
[re-frame.middleware :refer [path]]
[status-im.handlers.content-suggestions :refer [get-content-suggestions]]
[status-im.chat.constants :refer [input-height request-info-height
minimum-command-suggestions-height
response-height-normal minimum-suggestion-height]]
[status-im.constants :refer [response-input-hiding-duration]]))
@ -19,45 +20,45 @@
(fn [db _]
(assoc db
:to-response-height input-height
:messages-offset 0)))
:messages-offset? false)))
(defn get-response-height
[{:keys [current-chat-id] :as db}]
(let [suggestions (get-in db [:suggestions current-chat-id])
suggestions-height (if suggestions middle-height 0)]
(+ input-height
(min response-height-normal (+ suggestions-height request-info-height)))))
(def response-height (+ input-height response-height-normal))
(defn update-response-height [db]
(assoc-in db [:animations :to-response-height] (get-response-height db)))
(assoc-in db [:animations :to-response-height] response-height))
(register-handler :animate-show-response
[(after #(dispatch [:command-edit-mode]))]
(fn [db _]
(register-handler :animate-command-suggestions
(fn [{:keys [current-chat-id] :as db} _]
(let [suggestions? (seq (get-in db [:command-suggestions current-chat-id]))
current (get-in db [:animations :command-suggestions-height])
height (if suggestions? middle-height 0.1)]
(-> db
(assoc-in [:animations :messages-offset] request-info-height)
(update-response-height))))
(update :animations assoc
:messages-offset? suggestions?
:messages-offset-max 22
:command-suggestions-height height)
(update-in [:animations :commands-height-changed]
(if (and suggestions? (not= 0.1 current))
identity inc))))))
(animation-handler :set-response-max-height
(fn [db [_ height]]
(let [prev-height (:response-height-max db)]
(if (not= height prev-height)
(let [db (assoc db :response-height-max height)]
(if (= prev-height (:to-response-height db))
(assoc db :to-response-height height)
db))
db))))
(animation-handler :animate-show-response
[(after #(dispatch [:command-edit-mode]))]
(fn [db]
(assoc db :messages-offset? true
:messages-offset-max request-info-height
:to-response-height response-height)))
(register-handler :fix-response-height
(defn fix-height
[height-key height-signal-key suggestions-key minimum]
(fn [{:keys [current-chat-id] :as db} [_ vy current]]
(let [max-height (get-in db [:animations :response-height-max])
(let [max-height (get-in db [:layout-height])
moving-down? (pos? vy)
moving-up? (not moving-down?)
under-middle-position? (<= current middle-height)
over-middle-position? (not under-middle-position?)
suggestions (get-in db [:suggestions current-chat-id])
suggestions (get-in db [suggestions-key current-chat-id])
new-fixed (cond (not suggestions)
minimum-suggestion-height
minimum
(and under-middle-position? moving-up?)
middle-height
@ -70,7 +71,20 @@
(and under-middle-position?
moving-down?)
minimum-suggestion-height)]
minimum)]
(println height-key new-fixed)
(-> db
(assoc-in [:animations :to-response-height] new-fixed)
(update-in [:animations :response-height-changed] inc)))))
(assoc-in [:animations height-key] new-fixed)
(update-in [:animations height-signal-key] inc)))))
(register-handler :fix-commands-suggestions-height
(fix-height :command-suggestions-height
:commands-height-changed
:command-suggestions
minimum-command-suggestions-height))
(register-handler :fix-response-height
(fix-height :to-response-height
:response-height-changed
:suggestions
minimum-suggestion-height))

View File

@ -18,7 +18,7 @@
[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.suggestions :refer [suggestions-view]]
[status-im.chat.views.suggestions :refer [suggestion-container]]
[status-im.chat.views.response :refer [response-view]]
[status-im.chat.views.new-message :refer [chat-message-new]]
[status-im.i18n :refer [label label-pluralize]]
@ -228,20 +228,19 @@
:keyboardShouldPersistTaps true
:dataSource (to-datasource-inverted messages)}]))
(defn messages-container-animation-logic [{:keys [to-value val]}]
(defn messages-container-animation-logic
[{:keys [offset? val max]}]
(fn [_]
(let [to-value @to-value]
(anim/start (anim/spring val {:toValue to-value})
(fn [arg]
(when (.-finished arg)
(dispatch [:set-animation ::messages-offset-current to-value])))))))
(let [to-value (if @offset? @max 0)]
(anim/start (anim/spring val {:toValue to-value})))))
(defn messages-container [messages]
(let [to-messages-offset (subscribe [:animations :messages-offset])
cur-messages-offset (subscribe [:animations ::messages-offset-current])
messages-offset (anim/create-value (or @cur-messages-offset 0))
context {:to-value to-messages-offset
:val messages-offset}
(let [messages-offset? (subscribe [:animations :messages-offset?])
maximum-offset (subscribe [:animations :messages-offset-max])
messages-offset (anim/create-value 0)
context {:offset? messages-offset?
:val messages-offset
:max maximum-offset}
on-update (messages-container-animation-logic context)]
(r/create-class
{:component-did-mount
@ -250,7 +249,7 @@
on-update
:reagent-render
(fn [messages]
@to-messages-offset
@messages-offset?
[animated-view {:style (st/messages-container messages-offset)}
messages])})))
@ -259,16 +258,19 @@
show-actions-atom [:show-actions]
command [:get-chat-command]
command? [:command?]
to-msg-id [:get-chat-command-to-msg-id]]
suggestions [:get-suggestions]
to-msg-id [:get-chat-command-to-msg-id]
layout-height [:get :layout-height]]
[view {:style st/chat-view
:onLayout (fn [event]
(let [height (.. event -nativeEvent -layout -height)]
(dispatch [:set-response-max-height height])))}
(when (not= height layout-height)
(dispatch [:set :layout-height height]))))}
[chat-toolbar]
[messages-container
[messages-view group-chat]]
(when group-chat [typing-all])
[response-view]
(when-not command? [suggestions-view])
(when-not command? [suggestion-container])
[chat-message-new]
(when show-actions-atom [actions-view])])

View File

@ -59,11 +59,19 @@
:backgroundColor color-white
:borderRadius 5})
(def container
{:backgroundColor color-white})
(defn container [height]
{:flexDirection :column
:position :absolute
:left 0
:right 0
:bottom 0
:height height
:backgroundColor color-white
:elevation 2})
(def drag-down-touchable
{:height 22
:background-color color-white
:alignItems :center
:justifyContent :center})

View File

@ -43,11 +43,8 @@
(register-sub :get-suggestions
(fn [db _]
(let [input-text (->> (:current-chat-id @db)
db/chat-input-text-path
(get-in @db)
(reaction))]
(reaction (get-suggestions @db @input-text)))))
(let [chat-id (subscribe [:get-current-chat-id])]
(reaction (get-in @db [:command-suggestions @chat-id])))))
(register-sub :get-commands
(fn [db _]

View File

@ -21,19 +21,19 @@
command? [:command?]]
[plain-message-input-view
(when command?
(case (:command command)
(case (keyword (:name command))
:phone {:input-options {:keyboardType :phone-pad}
:validator valid-mobile-number?}
:keypair {:input-options {:secureTextEntry true}}
:confirmation-code {:input-options {:keyboardType :numeric}}
:money {:input-options {:keyboardType :numeric}}
:request {:input-options {:keyboardType :numeric}}
;; todo maybe nil is finr for now :)
;; todo maybe nil is fine for now :)
nil #_(throw (js/Error. "Uknown command type"))))])
(defview chat-message-new []
[staged-commands [:get-chat-staged-commands]]
[view st/new-message-container
(when (and staged-commands (pos? (count staged-commands)))
(when (seq staged-commands)
[staged-commands-view staged-commands])
[show-input]])

View File

@ -52,7 +52,7 @@
on-update
:reagent-render
(fn []
[touchable-highlight {:on-press #(dispatch [:switch-command-suggestions])
[touchable-highlight {:on-press #(dispatch [:switch-command-suggestions!])
:disabled @command?}
[animated-view {:style (st/message-input-button-touchable
container-width)}

View File

@ -6,9 +6,14 @@
icon
touchable-highlight
list-view
list-item]]
list-item
animated-view]]
[status-im.utils.listview :refer [to-datasource]]
[status-im.chat.styles.suggestions :as st]))
[status-im.chat.styles.suggestions :as st]
[reagent.core :as r]
[status-im.components.animation :as anim]
[status-im.components.drag-drop :as drag]
[status-im.components.react :as react]))
(defn set-command-input [command]
(dispatch [:set-chat-command command]))
@ -31,18 +36,89 @@
(list-item [suggestion-list-item row]))
(defview suggestions-view []
[suggestions [:get-suggestions]]
(when (seq suggestions)
[view st/container
[touchable-highlight {:style st/drag-down-touchable
:onPress (fn []
;; TODO hide suggestions?
)}
[view
[icon :drag_down st/drag-down-icon]]]
[view (st/suggestions-container (count suggestions))
[list-view {:dataSource (to-datasource suggestions)
(defn suggestions-view []
(let
[suggestions (subscribe [:get-suggestions])]
(r/create-class
{:reagent-render
(fn []
[view (st/suggestions-container (count @suggestions))
[list-view {:dataSource (to-datasource @suggestions)
:enableEmptySections true
:keyboardShouldPersistTaps true
:renderRow render-row}]]]))
:renderRow render-row}]])})))
;; todo bad name. Ideas?
(defn enough-dy [gesture]
(> (Math/abs (.-dy gesture)) 10))
(defn on-move [response-height kb-height orientation]
(fn [_ gesture]
(when (enough-dy gesture)
(let [w (react/get-dimensions "window")
;; depending on orientation use height or width of screen
prop (if (= :portrait @orientation)
:height
:width)
;; subtract keyboard height to get "real height" of screen
;; then subtract gesture position to get suggestions height
;; todo maybe it is better to use margin-top instead height
;; it is not obvious
to-value (- (prop w) @kb-height (.-moveY gesture))]
(anim/start
(anim/spring response-height {:toValue to-value}))))))
(defn on-release [response-height]
(fn [_ gesture]
(when (enough-dy gesture)
(dispatch [:fix-commands-suggestions-height
(.-vy gesture)
;; todo access to "private" property
;; better to find another way...
(.-_value response-height)]))))
(defn pan-responder [response-height kb-height orientation]
(drag/create-pan-responder
{:on-move (on-move response-height kb-height orientation)
:on-release (on-release response-height)}))
(defn header [h]
(let [orientation (subscribe [:get :orientation])
kb-height (subscribe [:get :keyboard-height])
pan-responder (pan-responder h kb-height orientation)]
(fn [_]
[view
(merge (drag/pan-handlers pan-responder)
{:style st/drag-down-touchable})
[icon :drag_down st/drag-down-icon]])))
(defn container-animation-logic [{:keys [to-value val]}]
(fn [_]
(let [to-value @to-value]
(anim/start (anim/spring val {:toValue to-value
:tension 50
:friction 10})))))
(defn container [h & elements]
(let [;; todo to-response-height, cur-response-height must be specific
;; for each chat
to-response-height (subscribe [:animations :command-suggestions-height])
changed (subscribe [:animations :commands-height-changed])
context {:to-value to-response-height
:val h}
on-update (container-animation-logic context)]
(r/create-class
{:component-did-mount
on-update
:component-did-update
on-update
:reagent-render
(fn [h & elements]
@changed
(into [animated-view {:style (st/container h)}] elements))})))
(defn suggestion-container []
(let [h (anim/create-value 0)]
[container h
[header h]
[suggestions-view] ]))

View File

@ -38,7 +38,6 @@
:phone-number ""}
:disable-group-creation false
:animations {:to-response-height 0.1
:messages-offset 0
;; todo clear this
:tabs-bar-value (anim/create-value 0)}})