Staging area fixes (#366, #382)

This commit is contained in:
Alexander Pantyuhov 2016-10-22 14:39:21 +03:00
parent 581b64fa10
commit df9600525c
18 changed files with 173 additions and 79 deletions

View File

@ -1,7 +1,7 @@
{ {
"name": "StatusIm", "name": "StatusIm",
"interface": "reagent", "interface": "reagent",
"androidHost": "10.0.3.2", "androidHost": "10.0.2.2",
"modules": [ "modules": [
"react-native-contacts", "react-native-contacts",
"react-native-invertible-scroll-view", "react-native-invertible-scroll-view",

View File

@ -10,7 +10,7 @@
(def root-el (r/as-element [reloader])) (def root-el (r/as-element [reloader]))
(figwheel/watch-and-reload (figwheel/watch-and-reload
:websocket-url "ws://localhost:3449/figwheel-ws" :websocket-url "ws://10.0.2.2:3449/figwheel-ws"
:heads-up-display false :heads-up-display false
:jsload-callback #(swap! cnt inc)) :jsload-callback #(swap! cnt inc))

View File

@ -13,6 +13,8 @@
:bar-style "default" :bar-style "default"
:translucent? true :translucent? true
:color styles/color-transparent}} :color styles/color-transparent}}
:chat {:new-message {:border-top-color styles/color-transparent
:border-top-width 0.5}}
:bottom-gradient {:height 3} :bottom-gradient {:height 3}
:input-label {:left 4} :input-label {:left 4}
:input-error-text {:margin-left 4} :input-error-text {:margin-left 4}

View File

@ -36,7 +36,8 @@
[cljs.core.async :as a] [cljs.core.async :as a]
status-im.chat.handlers.webview-bridge status-im.chat.handlers.webview-bridge
status-im.chat.handlers.wallet-chat status-im.chat.handlers.wallet-chat
status-im.chat.handlers.console)) status-im.chat.handlers.console
[taoensso.timbre :as log]))
(register-handler :set-chat-ui-props (register-handler :set-chat-ui-props
(fn [db [_ ui-element value]] (fn [db [_ ui-element value]]
@ -154,6 +155,29 @@
(dispatch [:set-chat-command command type]) (dispatch [:set-chat-command command type])
(dispatch [:set-chat-command-content text])))) (dispatch [:set-chat-command-content text]))))
(register-handler :set-staged-commands-scroll-view
(fn [{:keys [current-chat-id] :as db} [_ view]]
(assoc-in db [:chats current-chat-id :staged-scroll-view] view)))
(register-handler :set-staged-commands-scroll-height
(fn [{:keys [current-chat-id] :as db} [_ height]]
(assoc-in db [:chats current-chat-id :staged-scroll-height] height)))
(register-handler :staged-commands-scroll-to
(u/side-effect!
(fn [{:keys [current-chat-id chats]} [_ height]]
(let [{:keys [staged-scroll-view staged-scroll-height]} (get chats current-chat-id)]
(when staged-scroll-view
(let [y (if (and (> staged-scroll-height 0)
(< staged-scroll-height height))
(- height staged-scroll-height)
0)]
(.scrollTo staged-scroll-view (clj->js {:x 0 :y y}))))))))
(register-handler :set-message-input-view-height
(fn [{:keys [current-chat-id] :as db} [_ height]]
(assoc-in db [:chats current-chat-id :message-input-height] height)))
(register-handler ::check-suggestions (register-handler ::check-suggestions
[(after select-suggestion!) [(after select-suggestion!)
(after #(dispatch [:animate-command-suggestions]))] (after #(dispatch [:animate-command-suggestions]))]

View File

@ -1,11 +1,13 @@
(ns status-im.chat.handlers.animation (ns status-im.chat.handlers.animation
(:require [re-frame.core :refer [after dispatch debug path]] (:require [re-frame.core :refer [after dispatch subscribe debug path]]
[status-im.utils.handlers :refer [register-handler]] [status-im.utils.handlers :refer [register-handler]]
[status-im.chat.constants :refer [input-height request-info-height [status-im.chat.constants :refer [input-height request-info-height
suggestions-header-height suggestions-header-height
minimum-command-suggestions-height minimum-command-suggestions-height
response-height-normal minimum-suggestion-height]] response-height-normal minimum-suggestion-height]]
[status-im.constants :refer [response-input-hiding-duration]])) [status-im.utils.platform :refer [platform-specific]]
[status-im.constants :refer [response-input-hiding-duration]]
[taoensso.timbre :as log]))
;; todo magic value ;; todo magic value
(def middle-height 270) (def middle-height 270)
@ -71,7 +73,10 @@
(defn fix-height (defn fix-height
[height-key height-signal-key suggestions-key minimum] [height-key height-signal-key suggestions-key minimum]
(fn [{:keys [current-chat-id] :as db} [_ vy current no-animation]] (fn [{:keys [current-chat-id] :as db} [_ vy current no-animation]]
(let [max-height (get-in db [:layout-height]) (let [input-margin (subscribe [:input-margin])
max-height (- (get-in db [:layout-height])
(get-in platform-specific [:component-styles :status-bar :default :height])
@input-margin)
moving-down? (pos? vy) moving-down? (pos? vy)
moving-up? (not moving-down?) moving-up? (not moving-down?)
under-middle-position? (<= current middle-height) under-middle-position? (<= current middle-height)

View File

@ -20,19 +20,18 @@
[status-im.components.toolbar.view :refer [toolbar]] [status-im.components.toolbar.view :refer [toolbar]]
[status-im.chat.views.message :refer [chat-message]] [status-im.chat.views.message :refer [chat-message]]
[status-im.chat.views.datemark :refer [chat-datemark]] [status-im.chat.views.datemark :refer [chat-datemark]]
[status-im.chat.views.suggestions :refer [suggestion-container]]
[status-im.chat.views.response :refer [response-view]] [status-im.chat.views.response :refer [response-view]]
[status-im.chat.views.new-message :refer [chat-message-new]] [status-im.chat.views.new-message :refer [chat-message-input-view]]
[status-im.chat.views.staged-commands :refer [staged-commands-view]]
[status-im.chat.views.actions :refer [actions-view]] [status-im.chat.views.actions :refer [actions-view]]
[status-im.chat.views.bottom-info :refer [bottom-info-view]] [status-im.chat.views.bottom-info :refer [bottom-info-view]]
[status-im.chat.views.toolbar-content :refer [toolbar-content-view]] [status-im.chat.views.toolbar-content :refer [toolbar-content-view]]
[status-im.chat.views.suggestions :refer [suggestion-container]]
[status-im.i18n :refer [label label-pluralize]] [status-im.i18n :refer [label label-pluralize]]
[status-im.components.animation :as anim] [status-im.components.animation :as anim]
[status-im.components.sync-state.offline :refer [offline-view]] [status-im.components.sync-state.offline :refer [offline-view]]
[status-im.constants :refer [content-type-status]] [status-im.constants :refer [content-type-status]]
[reagent.core :as r] [reagent.core :as r]))
[cljs-time.core :as t]
[taoensso.timbre :as log]))
(defn contacts-by-identity [contacts] (defn contacts-by-identity [contacts]
(->> contacts (->> contacts
@ -171,14 +170,16 @@
:reagent-render :reagent-render
(fn [messages] (fn [messages]
@offset @offset
[animated-view {:style (st/messages-container messages-offset)} (let [staged-scroll-height (subscribe [:get-chat-staged-commands-scroll-height])]
messages])}))) [animated-view {:style (st/messages-container @staged-scroll-height messages-offset)}
messages]))})))
(defn chat [] (defn chat []
(let [group-chat (subscribe [:chat :group-chat]) (let [group-chat (subscribe [:chat :group-chat])
show-actions? (subscribe [:chat-ui-props :show-actions?]) show-actions? (subscribe [:chat-ui-props :show-actions?])
show-bottom-info? (subscribe [:chat-ui-props :show-bottom-info?]) show-bottom-info? (subscribe [:chat-ui-props :show-bottom-info?])
command? (subscribe [:command?]) command? (subscribe [:command?])
staged-commands (subscribe [:get-chat-staged-commands])
layout-height (subscribe [:get :layout-height])] layout-height (subscribe [:get :layout-height])]
(r/create-class (r/create-class
{:component-did-mount #(dispatch [:check-autorun]) {:component-did-mount #(dispatch [:check-autorun])
@ -194,10 +195,12 @@
[messages-view @group-chat]] [messages-view @group-chat]]
;; todo uncomment this ;; todo uncomment this
#_(when @group-chat [typing-all]) #_(when @group-chat [typing-all])
[response-view] (when (seq @staged-commands)
[staged-commands-view @staged-commands])
(when-not @command? (when-not @command?
[suggestion-container]) [suggestion-container])
[chat-message-new] [response-view]
[chat-message-input-view]
(when @show-actions? (when @show-actions?
[actions-view]) [actions-view])
(when @show-bottom-info? (when @show-bottom-info?

View File

@ -12,8 +12,7 @@
(def command-input-container (def command-input-container
{:flexDirection :row {:flexDirection :row
:height 56 :height 56
:backgroundColor color-white :backgroundColor color-white})
:elevation 4})
(def command-container (def command-container
{:left 0 {:left 0
@ -71,6 +70,15 @@
:width 12 :width 12
:height 12}) :height 12})
(defn staged-commands [message-input-height input-margin]
{:position :absolute
:background-color color-white
:bottom (+ message-input-height input-margin)
:left 0
:right 0
:max-height 150
:elevation 5})
(def staged-command-container (def staged-command-container
{:flex 1 {:flex 1
:alignItems :flex-start :alignItems :flex-start
@ -79,7 +87,9 @@
(def staged-command-background (def staged-command-background
{:flexDirection :column {:flexDirection :column
:margin 16 :margin-top 16
:margin-left 16
:margin-right 16
:padding-bottom 12 :padding-bottom 12
:padding-left 12 :padding-left 12
:backgroundColor chat-background :backgroundColor chat-background
@ -103,3 +113,7 @@
:marginHorizontal 0 :marginHorizontal 0
:fontSize 14 :fontSize 14
:color color-black}) :color color-black})
(def staged-commands-bottom
{:height 16
:background-color "white"})

View File

@ -264,7 +264,7 @@
(defn message-container [height] (defn message-container [height]
{:height height}) {:height height})
(defn new-message-container [margin] (defn new-message-container [margin on-top?]
{:backgroundColor color-white {:background-color color-white
:elevation 4 :margin-bottom margin
:margin-bottom margin}) :elevation (if on-top? 6 5)})

View File

@ -26,7 +26,7 @@
:margin-right 0}) :margin-right 0})
(def send-wrapper (def send-wrapper
{:margin-bottom 8 {:margin-bottom 10
:margin-right 10 :margin-right 10
:width 36 :width 36
:flex 1 :flex 1

View File

@ -49,15 +49,15 @@
:opacity 0.69 :opacity 0.69
:color color-white}) :color color-white})
(defn response-view [keyboard-height height] (defn response-view [keyboard-height height staged-commands]
{:flexDirection :column {:flexDirection :column
:position :absolute :position :absolute
:elevation (if (seq staged-commands) 5 4)
:left 0 :left 0
:right 0 :right 0
:bottom keyboard-height :bottom keyboard-height
:height height :height height
:backgroundColor color-white :backgroundColor color-white})
:elevation 2})
(def input-placeholder (def input-placeholder
{:height input-height}) {:height input-height})

View File

@ -16,9 +16,10 @@
(def toolbar-container (def toolbar-container
{}) {})
(defn messages-container [bottom] (defn messages-container [staged-height bottom]
{:flex 1 {:flex 1
:padding-bottom bottom}) :padding-bottom bottom
:margin-bottom staged-height})
(def toolbar-view (def toolbar-view
{:flexDirection :row {:flexDirection :row

View File

@ -66,15 +66,15 @@
:fontSize 12 :fontSize 12
:color text2-color}) :color text2-color})
(defn container [keyboard-height height] (defn container [height input-margin staged-commands]
{:flexDirection :column {:flexDirection :column
:position :absolute :position :absolute
:left 0 :left 0
:right 0 :right 0
:bottom keyboard-height :bottom input-margin
:height height :height height
:backgroundColor color-white :backgroundColor color-white
:elevation 2}) :elevation (if (seq staged-commands) 5 4)})
(def request-container (def request-container
{:height 56 {:height 56

View File

@ -10,7 +10,8 @@
[status-im.chat.views.command :as command] [status-im.chat.views.command :as command]
[status-im.constants :refer [content-type-status]] [status-im.constants :refer [content-type-status]]
[status-im.utils.datetime :as time] [status-im.utils.datetime :as time]
[status-im.utils.platform :refer [platform-specific]])) [status-im.utils.platform :refer [platform-specific]]
[taoensso.timbre :as log]))
(register-sub :chat-properties (register-sub :chat-properties
(fn [db [_ properties]] (fn [db [_ properties]]
@ -79,6 +80,17 @@
vals vals
(reaction)))) (reaction))))
(register-sub :get-chat-staged-commands-scroll-height
(fn [db _]
(let [{:keys [staged-commands
staged-scroll-height]} (get-in @db [:chats (:current-chat-id @db)])]
(reaction
(if (seq staged-commands) staged-scroll-height 0)))))
(register-sub :get-message-input-view-height
(fn [db _]
(reaction (get-in @db [:chats (:current-chat-id @db) :message-input-height]))))
(register-sub :valid-plain-message? (register-sub :valid-plain-message?
(fn [_ _] (fn [_ _]
(let [input-message (subscribe [:get-chat-input-text]) (let [input-message (subscribe [:get-chat-input-text])
@ -145,17 +157,14 @@
(let [command? (subscribe [:command?]) (let [command? (subscribe [:command?])
type (subscribe [:command-type]) type (subscribe [:command-type])
command-suggestions (subscribe [:get-content-suggestions]) command-suggestions (subscribe [:get-content-suggestions])
suggestions (subscribe [:get-suggestions])] staged-commands (subscribe [:get-chat-staged-commands])]
(reaction (reaction
(cond (and @command? (= @type :response)) (cond (and @command? (= @type :response) (not (seq @staged-commands)))
c/request-info-height c/request-info-height
(and @command? (= @type :command) (seq @command-suggestions)) (and @command? (= @type :command) (seq @command-suggestions))
c/suggestions-header-height c/suggestions-header-height
(and (not @command?) (seq @suggestions))
c/suggestions-header-height
:else 0))))) :else 0)))))
(register-sub :command-icon-width (register-sub :command-icon-width
@ -257,6 +266,14 @@
:else 0))))) :else 0)))))
(register-sub :max-layout-height
(fn [db [_ status-bar]]
(let [layout-height (subscribe [:get :layout-height])
input-margin (subscribe [:input-margin])
status-bar-height (get-in platform-specific [:component-styles :status-bar status-bar :height])]
(reaction
(- @layout-height @input-margin status-bar-height)))))
(register-sub :all-messages-loaded? (register-sub :all-messages-loaded?
(fn [db] (fn [db]
(let [chat-id (subscribe [:get-current-chat-id])] (let [chat-id (subscribe [:get-current-chat-id])]

View File

@ -1,20 +1,18 @@
(ns status-im.chat.views.new-message (ns status-im.chat.views.new-message
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require (:require
[re-frame.core :refer [subscribe]] [re-frame.core :refer [dispatch subscribe]]
[status-im.components.react :refer [view]] [status-im.components.react :refer [view
scroll-view]]
[status-im.chat.views.message-input :refer [plain-message-input-view]] [status-im.chat.views.message-input :refer [plain-message-input-view]]
[status-im.chat.views.staged-command :refer [simple-command-staged-view]] [status-im.chat.views.staged-commands :refer [simple-command-staged-view]]
[status-im.chat.constants :refer [input-height]]
[status-im.utils.platform :refer [platform-specific]] [status-im.utils.platform :refer [platform-specific]]
[status-im.chat.styles.message :as st])) [status-im.chat.styles.message :as st]
[taoensso.timbre :as log]))
(defn staged-command-view [stage-command] (defn get-height [event]
[simple-command-staged-view stage-command]) (.-height (.-layout (.-nativeEvent event))))
(defn staged-commands-view [staged-commands]
[view {}
(for [command staged-commands]
^{:key command} [staged-command-view command])])
(defn get-options [{:keys [type placeholder]} command-type] (defn get-options [{:keys [type placeholder]} command-type]
(let [options (case (keyword type) (let [options (case (keyword type)
@ -29,19 +27,20 @@
options) options)
(assoc-in options [:input-options :placeholder] "")))) (assoc-in options [:input-options :placeholder] ""))))
(defview show-input [] (defview chat-message-input-view []
[parameter [:get-command-parameter] [margin [:input-margin]
command? [:command?] command? [:command?]
type [:command-type]] response-height [:response-height]
[plain-message-input-view parameter [:get-command-parameter]
(when command? (get-options parameter type))]) type [:command-type]
suggestions [:get-suggestions]
(defview chat-message-new [] staged-commands [:get-chat-staged-commands]]
[staged-commands [:get-chat-staged-commands] (let [on-top? (or (and (not (empty? suggestions))
margin [:input-margin]] (not command?))
(let [style (get-in platform-specific [:component-styles :chat :new-message])] (not= response-height input-height))
[view (merge (st/new-message-container margin) style (when-not (seq staged-commands)
style) (get-in platform-specific [:component-styles :chat :new-message]))]
(when (seq staged-commands) [view {:style (merge (st/new-message-container margin on-top?) style)
[staged-commands-view staged-commands]) :on-layout #(dispatch [:set-message-input-view-height (get-height %)])}
[show-input]])) [plain-message-input-view
(when command? (get-options parameter type))]]))

View File

@ -87,6 +87,7 @@
changed (subscribe [:animations :response-height-changed]) changed (subscribe [:animations :response-height-changed])
animate? (subscribe [:animate?]) animate? (subscribe [:animate?])
keyboard-height (subscribe [:get :keyboard-height]) keyboard-height (subscribe [:get :keyboard-height])
staged-commands (subscribe [:get-chat-staged-commands])
context {:to-value to-response-height context {:to-value to-response-height
:val response-height :val response-height
:animate? animate?} :animate? animate?}
@ -101,7 +102,8 @@
@to-response-height @changed @to-response-height @changed
(into [animated-view {:style (st/response-view (into [animated-view {:style (st/response-view
(if ios? @keyboard-height 0) (if ios? @keyboard-height 0)
response-height)}] response-height
@staged-commands)}]
children))}))) children))})))
(defn on-navigation-change (defn on-navigation-change

View File

@ -1,17 +1,23 @@
(ns status-im.chat.views.staged-command (ns status-im.chat.views.staged-commands
(:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
image image
icon icon
text text
touchable-highlight]] touchable-highlight
[status-im.resources :as res] scroll-view]]
[status-im.chat.styles.input :as st] [status-im.chat.styles.input :as st]
[status-im.chat.styles.command-pill :as pill-st])) [status-im.chat.styles.command-pill :as pill-st]
[status-im.utils.platform :refer [platform-specific]]
[taoensso.timbre :as log]))
(defn cancel-command-input [staged-command] (defn cancel-command-input [staged-command]
(dispatch [:unstage-command staged-command])) (dispatch [:unstage-command staged-command]))
(defn get-height [event]
(.-height (.-layout (.-nativeEvent event))))
(defn simple-command-staged-view (defn simple-command-staged-view
[{:keys [command params] :as staged-command}] [{:keys [command params] :as staged-command}]
(let [{:keys [type name]} command] (let [{:keys [type name]} command]
@ -34,3 +40,21 @@
(if (= 1 (count params)) (if (= 1 (count params))
(first (vals params)) (first (vals params))
(str params))])]])) (str params))])]]))
(defn staged-command-view [stage-command]
[simple-command-staged-view stage-command])
(defview staged-commands-view [staged-commands]
[message-input-height [:get-message-input-view-height]
input-margin [:input-margin]]
(let [style (when (seq staged-commands)
(get-in platform-specific [:component-styles :chat :new-message]))]
[view {:style (merge (st/staged-commands message-input-height input-margin)
style)}
[scroll-view {:bounces false
:ref #(dispatch [:set-staged-commands-scroll-view %])
:on-layout #(dispatch [:set-staged-commands-scroll-height (get-height %)])}
[view {:on-layout #(dispatch [:staged-commands-scroll-to (get-height %)])}
(for [command staged-commands]
^{:key command} [staged-command-view command])
[view st/staged-commands-bottom]]]]))

View File

@ -18,7 +18,8 @@
[status-im.components.drag-drop :as drag] [status-im.components.drag-drop :as drag]
[status-im.utils.platform :refer [ios?]] [status-im.utils.platform :refer [ios?]]
[status-im.chat.suggestions-responder :as resp] [status-im.chat.suggestions-responder :as resp]
[status-im.chat.constants :as c])) [status-im.chat.constants :as c]
[taoensso.timbre :as log]))
(defn set-command-input [command] (defn set-command-input [command]
(dispatch [:set-chat-command command])) (dispatch [:set-chat-command command]))
@ -88,7 +89,7 @@
:renderRow render-row}]]]) :renderRow render-row}]]])
(defn header [h] (defn header [h]
(let [layout-height (subscribe [:get :layout-height]) (let [layout-height (subscribe [:max-layout-height :default])
pan-responder (resp/pan-responder h pan-responder (resp/pan-responder h
layout-height layout-height
:fix-commands-suggestions-height)] :fix-commands-suggestions-height)]
@ -109,13 +110,14 @@
(let [;; todo to-response-height, cur-response-height must be specific (let [;; todo to-response-height, cur-response-height must be specific
;; for each chat ;; for each chat
to-response-height (subscribe [:command-suggestions-height]) to-response-height (subscribe [:command-suggestions-height])
keyboard-height (subscribe [:get :keyboard-height]) input-margin (subscribe [:input-margin])
changed (subscribe [:animations :commands-height-changed]) changed (subscribe [:animations :commands-height-changed])
animate? (subscribe [:animate?]) animate? (subscribe [:animate?])
context {:to-value to-response-height staged-commands (subscribe [:get-chat-staged-commands])
:val h context {:to-value to-response-height
:animate? animate?} :val h
on-update #(container-animation-logic context)] :animate? animate?}
on-update #(container-animation-logic context)]
(r/create-class (r/create-class
{:component-did-mount {:component-did-mount
on-update on-update
@ -124,9 +126,9 @@
:reagent-render :reagent-render
(fn [h & elements] (fn [h & elements]
@to-response-height @changed @to-response-height @changed
(into [animated-view {:style (st/container (if ios? @keyboard-height 0) h)}] elements))}))) (into [animated-view {:style (st/container h @input-margin @staged-commands)}] elements))})))
(defn suggestion-container [] (defview suggestion-container [any-staged-commands?]
(let [h (anim/create-value c/input-height)] (let [h (anim/create-value c/input-height)]
[container h [container h
[header h] [header h]

View File

@ -143,6 +143,7 @@
:command-text-location "Location: {{address}}" :command-text-location "Location: {{address}}"
:command-text-browse "Browsing webpage: {{webpage}}" :command-text-browse "Browsing webpage: {{webpage}}"
:command-text-send "Transaction: {{amount}} ETH" :command-text-send "Transaction: {{amount}} ETH"
:command-text-help "Help"
;new-group ;new-group
:group-chat-name "Chat name" :group-chat-name "Chat name"