drawer UI refresh

This commit is contained in:
Gustavo Nunes 2017-04-28 01:12:53 -03:00 committed by Roman Volosovskyi
parent 1119142913
commit e52b2c27dd
12 changed files with 327 additions and 180 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 926 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "icon_arrow_right_gray.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

View File

@ -1,92 +1,166 @@
(ns status-im.components.drawer.styles (ns status-im.components.drawer.styles
(:require [status-im.components.styles :refer [color-white (:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
text1-color (:require [status-im.components.styles :as common]))
text2-color
text3-color
color-red]]
[status-im.utils.platform :as p]))
(def drawer-menu (def drawer
{:flex 1 {:flex 1
:background-color color-white :background-color common/color-white
:flex-direction :column}) :justify-content :space-between})
;; profile
(def upper-container
{:margin 16
:margin-top 0})
(def profile-container
{:padding 16
:border-radius 8
:background-color common/color-light-blue4})
(def user-photo-container (def user-photo-container
{:margin-top 40 {:height 52
:align-items :center :width 52})
:justify-content :center})
(def user-photo
{:border-radius 32
:width 64
:height 64})
(def name-container
{:margin-top (if p/ios? -13 -19)
:margin-bottom -16
:margin-left 16
:margin-right 16})
(def name-input-wrapper (def name-input-wrapper
{}) {:margin-top 24
:padding 0
:height 20})
(defn name-input-text [valid?] (defnstyle name-input-text [valid?]
{:color (if valid? text1-color {:line-height 24
color-red) :height 20
:text-align :center}) :padding 0
:color (if valid? common/color-black common/color-red)
:android {:font-size 16}
:ios {:font-size 17}})
(def status-container (def status-container
{:margin-left 16 {:flex-direction :row
:margin-right 16 :margin-top 3})
:flex-direction :row
:margin-top 5
:justify-content :center})
(def status-view (defstyle status-input-view
{:min-height 56 {:min-height 67
:width 200 :width 236
:font-size 14 :font-size 15
:text-align :center :line-height 21
:padding-left 0
:padding-top 5
:padding-bottom 0
:margin-bottom 0
:text-align-vertical :top :text-align-vertical :top
:color text2-color}) :color common/color-black})
(def status-input (defnstyle status-view [placeholder?]
(merge status-view (merge status-input-view
{:padding-left 4 {:color (if placeholder? common/color-gray common/color-black)
:padding-top (if p/ios? 0 5)})) :min-height 0
:ios {:padding-top 10}}))
(def status-text (def options-button
(merge status-view {:position :absolute
{:padding-left 0 :top 16
:padding-top 5})) :right 16})
(def menu-items-container ;; network
{:flex 1
:margin-top 20
:align-items :stretch
:flex-direction :column})
(def menu-item-touchable (def network-label-container
{:height 48 {:margin-top 16})
:paddingLeft 16
:paddingTop 14})
(def menu-item-text (defstyle network-label
{:font-size 14 {:color common/color-gray4
:line-height 21 :android {:font-size 12}
:color text1-color}) :ios {:font-size 14}})
(def name-text (def network-title
{:color text1-color {:color common/color-gray6
:font-size 16}) :font-size 16})
(def switch-users-container ;; transactions
{:padding-vertical 36
:align-items :center})
(def switch-users-text (def transactions-list-separator
{:font-size 14 {:margin-left 48})
:line-height 21
:color text3-color})
(def feedback {:text-align :center}) (def empty-transactions-title-container
{:margin-bottom 32
:align-items :center})
(defstyle transactions-title-container
{:margin-left 16
:android {:margin-bottom 16}
:ios {:margin-bottom 8}})
(defstyle transactions-title
{:color common/color-gray4
:android {:font-size 12}
:ios {:font-size 14}})
(def transaction
{:padding 16
:flex-direction :row})
(defstyle transaction-icon
{:width 24
:height 24
:margin-right 8
:android {:margin-top 2}})
(def transaction-info
{:width 180})
(def transaction-value-container
{:flex-direction :row})
(def transaction-value
{:font-size 20
:line-height 22
:color common/color-black})
(def transaction-unit
{:font-size 20
:line-height 22
:color common/color-gray
:margin-left 8})
(def transaction-details-container
{:margin-top 8
:flex-direction :row})
(defstyle transaction-to
{:line-height 16
:color common/color-gray4
:android {:font-size 12}
:ios {:font-size 14}})
(defstyle transaction-recipient
{:line-height 16
:margin-left 4
:color common/color-black
:flex-shrink 1
:android {:font-size 12}
:ios {:font-size 14}})
(defstyle transaction-time
{:line-height 16
:color common/color-gray4
:margin-left 8
:android {:font-size 12}
:ios {:font-size 14}})
(def transaction-picture
{:margin-top 3
:margin-left 16
:min-width 40
:min-height 40})
(def view-all-transactions-button
{:height 52
:justify-content :center
:align-items :center
:border-top-width 1
:border-top-color common/color-light-gray2})
(defstyle view-all-transactions-text
{:color common/color-light-blue
:android {:font-size 14}
:ios {:font-size 17}})

View File

@ -1,130 +1,176 @@
(ns status-im.components.drawer.view (ns status-im.components.drawer.view
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require [reagent.core :as r] (:require [cljs.spec :as s]
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
[clojure.string :as str] [clojure.string :as str]
[cljs.spec :as s] [reagent.core :as r]
[re-frame.core :as rf]
[status-im.accessibility-ids :as id]
[status-im.components.chat-icon.screen :as ci]
[status-im.components.common.common :as common]
[status-im.components.context-menu :as context-menu]
[status-im.components.drawer.styles :as st]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
text-input text-input
image icon
list-item
list-view
drawer-layout drawer-layout
touchable-without-feedback touchable-without-feedback
touchable-opacity]] touchable-highlight
[status-im.components.text-field.view :refer [text-field]] touchable-opacity
[status-im.components.status-view.view :refer [status-view]] dismiss-keyboard!]]
[status-im.components.drawer.styles :as st] [status-im.components.status-view.view :as status-view]
[status-im.i18n :as i18n]
[status-im.profile.validations :as v] [status-im.profile.validations :as v]
[status-im.utils.gfycat.core :refer [generate-gfy]] [status-im.utils.datetime :as time]
[status-im.utils.utils :refer [clean-text]] [status-im.utils.gfycat.core :as gfycat]
[status-im.i18n :refer [label]] [status-im.utils.listview :as lw]
[status-im.accessibility-ids :as id] [status-im.utils.platform :as platform]
[status-im.components.react :refer [dismiss-keyboard!]] [status-im.utils.utils :as utils]))
[clojure.string :as str]
[status-im.components.chat-icon.screen :as ci]))
(defonce drawer-atom (atom)) (defonce drawer-atom (atom))
(defn open-drawer [] (.openDrawer @drawer-atom))
(defn open-drawer [] (defn close-drawer [] (.closeDrawer @drawer-atom))
(.openDrawer @drawer-atom))
(defn close-drawer []
(.closeDrawer @drawer-atom))
(defn menu-item [{:keys [name handler]}]
[touchable-opacity {:style st/menu-item-touchable
:onPress (fn []
(close-drawer)
(handler))}
[text {:style st/menu-item-text
:font :default}
name]])
(defn- update-status [new-status] (defn- update-status [new-status]
(when-not (str/blank? new-status) (when-not (str/blank? new-status)
(dispatch [:check-status-change new-status]) (rf/dispatch [:check-status-change new-status])
(dispatch [:account-update {:status new-status}]) (rf/dispatch [:account-update {:status new-status}])
(dispatch [:set-in [:profile-edit :status] new-status]))) (rf/dispatch [:set-in [:profile-edit :status] new-status])))
(defn drawer-menu [] (defview profile-picture []
(let [account [:get-current-account]]
[account (subscribe [:get-current-account]) [touchable-opacity {:on-press #(rf/dispatch [:navigate-to :my-profile])
profile (subscribe [:get :profile-edit]) :style st/user-photo-container}
keyboard-height (subscribe [:get :keyboard-height]) [view
placeholder (generate-gfy) [ci/chat-icon (:photo-path account) {:size 52}]]])
status-edit? (r/atom false)
status-text (r/atom nil)] (defview name-input [placeholder]
[account [:get-current-account]
new-name [:get-in [:profile-edit :name]]]
(let [current-name (:name account)]
[view {:style st/name-input-wrapper}
[text-input
{:placeholder placeholder
:style (st/name-input-text (s/valid? ::v/name (or new-name current-name)))
:font (if platform/ios? :medium :default)
:default-value (or new-name current-name)
:on-change-text #(rf/dispatch [:set-in [:profile-edit :name] %])
:on-end-editing #(do
(rf/dispatch [:set-in [:profile-edit :name] nil])
(when (s/valid? ::v/name new-name)
(rf/dispatch [:account-update {:name (utils/clean-text new-name)}])))}]]))
(defview status-input []
[account [:get-current-account]
status-edit? (r/atom false)
status-text (r/atom nil)]
(let [status (:status account)
placeholder (i18n/label :t/update-status)]
[view st/status-container
(if @status-edit?
[text-input {:style st/status-input-view
:multiline true
:auto-focus true
:focus @status-edit?
:max-length 140
:accessibility-label id/drawer-status-input
:placeholder placeholder
:default-value status
:on-blur #(do
(reset! status-edit? false)
(update-status @status-text))
:on-change-text #(let [new-status (utils/clean-text %)]
(reset! status-text new-status)
(if (str/includes? % "\n")
(do
(reset! status-edit? false)
(update-status new-status))
(rf/dispatch [:set-in [:profile-edit :status] new-status])))}]
[status-view/status-view {:style (st/status-view (str/blank? status))
:on-press #(reset! status-edit? true)
:number-of-lines 3
:status (if (str/blank? status) placeholder status)}])]))
(defview transaction-list-item [{:keys [to value timestamp] :as transaction}]
[recipient [:contact-by-address to]]
(let [eth-value (.fromWei js/Web3.prototype value "ether")
value (i18n/label-number eth-value)
recipient-name (or (:name recipient) to)]
[touchable-highlight {:on-press #(rf/dispatch [:navigate-to-modal :transaction-details transaction])}
[view {:style st/transaction}
[icon :arrow_right_gray st/transaction-icon]
[view {:style st/transaction-info}
[view {:style st/transaction-value-container}
[text {:style st/transaction-value :font :medium} value]
[text {:style st/transaction-unit} "ETH"]]
[view {:style st/transaction-details-container}
[text {:style st/transaction-to} (i18n/label :t/to)]
[text {:style st/transaction-recipient :number-of-lines 1} recipient-name]
[text {:style st/transaction-time} (time/format-date "dd MMM hh:mm" (time/to-date timestamp))]]]
[view {:style st/transaction-picture}
(when recipient
[ci/chat-icon (:photo-path recipient) {:size 40}])]]]))
(defn render-separator-fn [transactions-count]
(fn [_ row-id _]
(when (< row-id (dec transactions-count))
(list-item
^{:key row-id}
[common/separator {} st/transactions-list-separator]))))
(defview unsigned-transactions []
[all-transactions [:transactions]]
(let [transactions (take 2 (sort-by :timestamp > all-transactions))]
(if (empty? transactions)
[view {:style st/empty-transactions-title-container}
[text {:style st/transactions-title} (i18n/label :t/no-unsigned-transactions)]]
[view
[view {:style st/transactions-title-container}
[text {:style st/transactions-title} (i18n/label :t/unsigned-transactions)]]
[list-view {:dataSource (lw/to-datasource transactions)
:renderSeparator (render-separator-fn (count transactions))
:renderRow (fn [row _ _] (list-item [transaction-list-item row]))}]
[touchable-opacity {:style st/view-all-transactions-button
:on-press #(rf/dispatch [:navigate-to-modal :unsigned-transactions])}
[text {:style st/view-all-transactions-text
:font (if platform/android? :medium :default)
:uppercase? platform/android?}
(i18n/label :t/view-all)]]])))
(defn current-network []
[view {:style st/network-label-container}
[text {:style st/network-label} (i18n/label :t/current-network)]
[text {:style st/network-title} "Ropsten"]])
(defn options-btn []
(let [options [{:value (fn []
(close-drawer)
(rf/dispatch [:set-in [:profile-edit :name] nil])
(rf/dispatch [:navigate-to :accounts]))
:text (i18n/label :t/switch-users)}]]
[view {:style st/options-button}
[context-menu/context-menu [icon :options_gray] options]]))
(defn drawer []
(let [placeholder (gfycat/generate-gfy)]
(fn [] (fn []
(let [{:keys [name photo-path status]} @account [touchable-without-feedback {:on-press #(dismiss-keyboard!)}
{new-name :name} @profile] [view st/drawer
[view st/drawer-menu [view st/upper-container
[touchable-without-feedback {:on-press #(dismiss-keyboard!)} [view st/profile-container
[view st/drawer-menu [profile-picture]
[touchable-opacity {:on-press #(dispatch [:navigate-to :my-profile])} [name-input placeholder]
[view st/user-photo-container [status-input]
[ci/chat-icon photo-path {:size 64}]]] [options-btn]]
[view st/name-container [current-network]]
[text-field [unsigned-transactions]]])))
{:line-color :white
:focus-line-color :white
:placeholder placeholder
:editable true
:input-style (st/name-input-text (s/valid? ::v/name (or new-name name)))
:wrapper-style st/name-input-wrapper
:value (or new-name name)
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])
:on-end-editing #(do
(dispatch [:set-in [:profile-edit :name] nil])
(when (s/valid? ::v/name new-name)
(dispatch [:account-update {:name (clean-text new-name)}])))}]]
[view st/status-container
(if @status-edit?
[text-input {:style st/status-input
:editable true
:multiline true
:auto-focus true
:focus status-edit?
:max-length 140
:accessibility-label id/drawer-status-input
:placeholder (label :t/profile-no-status)
:default-value status
:on-blur #(do
(reset! status-edit? false)
(update-status @status-text))
:on-change-text #(let [status (clean-text %)]
(reset! status-text status)
(if (str/includes? % "\n")
(do
(reset! status-edit? false)
(update-status status))
(dispatch [:set-in [:profile-edit :status] status])))}]
[status-view {:style st/status-text
:on-press #(reset! status-edit? true)
:number-of-lines 3
:status status}])]
[view st/menu-items-container
[menu-item {:name (label :t/profile)
:handler #(dispatch [:navigate-to :my-profile])}]
[menu-item {:name (label :t/discover)
:handler #(dispatch [:navigate-to-tab :discover])}]
[menu-item {:name (label :t/contacts)
:handler #(dispatch [:navigate-to-tab :contact-list])}]]
(when (zero? @keyboard-height)
[text {:style st/feedback
:font :default} (label :t/feedback)])
(when (zero? @keyboard-height)
[view st/switch-users-container
[touchable-opacity {:onPress (fn []
(close-drawer)
(dispatch [:set-in [:profile-edit :name] nil])
(dispatch [:navigate-to :accounts]))}
[text {:style st/switch-users-text
:font :default}
(label :t/switch-users)]]])]]]))))
(defn drawer-view [items] (defn drawer-view [items]
[drawer-layout {:drawerWidth 260 [drawer-layout {:drawerWidth 300
:renderNavigationView #(r/as-element [drawer-menu]) :renderNavigationView #(r/as-element [drawer])
:onDrawerSlide dismiss-keyboard! :onDrawerSlide dismiss-keyboard!
:ref (fn [drawer] :ref (fn [drawer]
(reset! drawer-atom drawer))} (reset! drawer-atom drawer))}

View File

@ -21,6 +21,7 @@
(def color-light-blue-transparent "#628fe333") (def color-light-blue-transparent "#628fe333")
(def color-light-blue2 "#eff3fc") (def color-light-blue2 "#eff3fc")
(def color-light-blue3 "#a0bcf0") (def color-light-blue3 "#a0bcf0")
(def color-light-blue4 "#f1f4f5")
(def color-dark-blue-1 "#252c4a") (def color-dark-blue-1 "#252c4a")
(def color-dark-blue-2 "#1f253f") (def color-dark-blue-2 "#1f253f")
(def color-dark-blue-3 "#191f37") (def color-dark-blue-3 "#191f37")

View File

@ -2,6 +2,7 @@
(:require [re-frame.core :refer [after dispatch debug enrich]] (:require [re-frame.core :refer [after dispatch debug enrich]]
[status-im.utils.handlers :refer [register-handler]] [status-im.utils.handlers :refer [register-handler]]
[status-im.navigation.handlers :as nav] [status-im.navigation.handlers :as nav]
[status-im.utils.datetime :as time]
[status-im.utils.handlers :as u] [status-im.utils.handlers :as u]
[status-im.utils.types :as t] [status-im.utils.types :as t]
[status-im.utils.hex :refer [valid-hex? normalize-hex]] [status-im.utils.hex :refer [valid-hex? normalize-hex]]
@ -134,6 +135,7 @@
:data data :data data
:gas (.toDecimal js/Web3.prototype gas) :gas (.toDecimal js/Web3.prototype gas)
:gas-price (.toDecimal js/Web3.prototype gasPrice) :gas-price (.toDecimal js/Web3.prototype gasPrice)
:timestamp (time/now-ms)
:message-id message_id}] :message-id message_id}]
(assoc-in db [:transactions-queue id] transaction)) (assoc-in db [:transactions-queue id] transaction))
db)))) db))))

View File

@ -22,6 +22,8 @@
:faq "FAQ" :faq "FAQ"
:switch-users "Switch users" :switch-users "Switch users"
:feedback "Got feedback?\nShake your phone!" :feedback "Got feedback?\nShake your phone!"
:view-all "View all"
:current-network "Current network"
;chat ;chat
:is-typing "is typing" :is-typing "is typing"
@ -81,7 +83,7 @@
:public-key "Public key" :public-key "Public key"
:phone-number "Phone number" :phone-number "Phone number"
:email "Email" :email "Email"
:profile-no-status "No status" :update-status "Update your status..."
:add-a-status "Add a status..." :add-a-status "Add a status..."
:status-prompt "Create a status to help people know about the things you are offering. You can use #hashtags too." :status-prompt "Create a status to help people know about the things you are offering. You can use #hashtags too."
:add-to-contacts "Add to contacts" :add-to-contacts "Add to contacts"
@ -292,6 +294,7 @@
:zero "No transactions confirmed"} :zero "No transactions confirmed"}
:transaction "Transaction" :transaction "Transaction"
:unsigned-transactions "Unsigned transactions" :unsigned-transactions "Unsigned transactions"
:no-unsigned-transactions "No unsigned transactions"
:enter-password-transactions {:one "Confirm transaction by entering your password" :enter-password-transactions {:one "Confirm transaction by entering your password"
:other "Confirm transactions by entering your password"} :other "Confirm transactions by entering your password"}
:status "Status" :status "Status"