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
(:require [status-im.components.styles :refer [color-white
text1-color
text2-color
text3-color
color-red]]
[status-im.utils.platform :as p]))
(:require-macros [status-im.utils.styles :refer [defstyle defnstyle]])
(:require [status-im.components.styles :as common]))
(def drawer-menu
(def drawer
{:flex 1
:background-color color-white
:flex-direction :column})
:background-color common/color-white
: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
{:margin-top 40
:align-items :center
: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})
{:height 52
:width 52})
(def name-input-wrapper
{})
{:margin-top 24
:padding 0
:height 20})
(defn name-input-text [valid?]
{:color (if valid? text1-color
color-red)
:text-align :center})
(defnstyle name-input-text [valid?]
{:line-height 24
:height 20
:padding 0
:color (if valid? common/color-black common/color-red)
:android {:font-size 16}
:ios {:font-size 17}})
(def status-container
{:margin-left 16
:margin-right 16
:flex-direction :row
:margin-top 5
:justify-content :center})
{:flex-direction :row
:margin-top 3})
(def status-view
{:min-height 56
:width 200
:font-size 14
:text-align :center
:text-align-vertical :top
:color text2-color})
(def status-input
(merge status-view
{:padding-left 4
:padding-top (if p/ios? 0 5)}))
(def status-text
(merge status-view
{:padding-left 0
:padding-top 5}))
(def menu-items-container
{:flex 1
:margin-top 20
:align-items :stretch
:flex-direction :column})
(def menu-item-touchable
{:height 48
:paddingLeft 16
:paddingTop 14})
(def menu-item-text
{:font-size 14
(defstyle status-input-view
{:min-height 67
:width 236
:font-size 15
:line-height 21
:color text1-color})
:padding-left 0
:padding-top 5
:padding-bottom 0
:margin-bottom 0
:text-align-vertical :top
:color common/color-black})
(def name-text
{:color text1-color
(defnstyle status-view [placeholder?]
(merge status-input-view
{:color (if placeholder? common/color-gray common/color-black)
:min-height 0
:ios {:padding-top 10}}))
(def options-button
{:position :absolute
:top 16
:right 16})
;; network
(def network-label-container
{:margin-top 16})
(defstyle network-label
{:color common/color-gray4
:android {:font-size 12}
:ios {:font-size 14}})
(def network-title
{:color common/color-gray6
:font-size 16})
(def switch-users-container
{:padding-vertical 36
;; transactions
(def transactions-list-separator
{:margin-left 48})
(def empty-transactions-title-container
{:margin-bottom 32
:align-items :center})
(def switch-users-text
{:font-size 14
:line-height 21
:color text3-color})
(defstyle transactions-title-container
{:margin-left 16
:android {:margin-bottom 16}
:ios {:margin-bottom 8}})
(def feedback {:text-align :center})
(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
(:require-macros [status-im.utils.views :refer [defview]])
(:require [reagent.core :as r]
[re-frame.core :refer [subscribe dispatch dispatch-sync]]
(:require [cljs.spec :as s]
[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
text
text-input
image
icon
list-item
list-view
drawer-layout
touchable-without-feedback
touchable-opacity]]
[status-im.components.text-field.view :refer [text-field]]
[status-im.components.status-view.view :refer [status-view]]
[status-im.components.drawer.styles :as st]
touchable-highlight
touchable-opacity
dismiss-keyboard!]]
[status-im.components.status-view.view :as status-view]
[status-im.i18n :as i18n]
[status-im.profile.validations :as v]
[status-im.utils.gfycat.core :refer [generate-gfy]]
[status-im.utils.utils :refer [clean-text]]
[status-im.i18n :refer [label]]
[status-im.accessibility-ids :as id]
[status-im.components.react :refer [dismiss-keyboard!]]
[clojure.string :as str]
[status-im.components.chat-icon.screen :as ci]))
[status-im.utils.datetime :as time]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.listview :as lw]
[status-im.utils.platform :as platform]
[status-im.utils.utils :as utils]))
(defonce drawer-atom (atom))
(defn open-drawer []
(.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 open-drawer [] (.openDrawer @drawer-atom))
(defn close-drawer [] (.closeDrawer @drawer-atom))
(defn- update-status [new-status]
(when-not (str/blank? new-status)
(dispatch [:check-status-change new-status])
(dispatch [:account-update {:status new-status}])
(dispatch [:set-in [:profile-edit :status] new-status])))
(rf/dispatch [:check-status-change new-status])
(rf/dispatch [:account-update {:status new-status}])
(rf/dispatch [:set-in [:profile-edit :status] new-status])))
(defn drawer-menu []
(let
[account (subscribe [:get-current-account])
profile (subscribe [:get :profile-edit])
keyboard-height (subscribe [:get :keyboard-height])
placeholder (generate-gfy)
(defview profile-picture []
[account [:get-current-account]]
[touchable-opacity {:on-press #(rf/dispatch [:navigate-to :my-profile])
:style st/user-photo-container}
[view
[ci/chat-icon (:photo-path account) {:size 52}]]])
(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)]
(fn []
(let [{:keys [name photo-path status]} @account
{new-name :name} @profile]
[view st/drawer-menu
[touchable-without-feedback {:on-press #(dismiss-keyboard!)}
[view st/drawer-menu
[touchable-opacity {:on-press #(dispatch [:navigate-to :my-profile])}
[view st/user-photo-container
[ci/chat-icon photo-path {:size 64}]]]
[view st/name-container
[text-field
{: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)}])))}]]
(let [status (:status account)
placeholder (i18n/label :t/update-status)]
[view st/status-container
(if @status-edit?
[text-input {:style st/status-input
:editable true
[text-input {:style st/status-input-view
:multiline true
:auto-focus true
:focus status-edit?
:focus @status-edit?
:max-length 140
:accessibility-label id/drawer-status-input
:placeholder (label :t/profile-no-status)
:placeholder placeholder
: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)
: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 status))
(dispatch [:set-in [:profile-edit :status] status])))}]
[status-view {:style st/status-text
(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 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 []
: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)
(dispatch [:set-in [:profile-edit :name] nil])
(dispatch [:navigate-to :accounts]))}
[text {:style st/switch-users-text
:font :default}
(label :t/switch-users)]]])]]]))))
(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 []
[touchable-without-feedback {:on-press #(dismiss-keyboard!)}
[view st/drawer
[view st/upper-container
[view st/profile-container
[profile-picture]
[name-input placeholder]
[status-input]
[options-btn]]
[current-network]]
[unsigned-transactions]]])))
(defn drawer-view [items]
[drawer-layout {:drawerWidth 260
:renderNavigationView #(r/as-element [drawer-menu])
[drawer-layout {:drawerWidth 300
:renderNavigationView #(r/as-element [drawer])
:onDrawerSlide dismiss-keyboard!
:ref (fn [drawer]
(reset! drawer-atom drawer))}

View File

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

View File

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

View File

@ -22,6 +22,8 @@
:faq "FAQ"
:switch-users "Switch users"
:feedback "Got feedback?\nShake your phone!"
:view-all "View all"
:current-network "Current network"
;chat
:is-typing "is typing"
@ -81,7 +83,7 @@
:public-key "Public key"
:phone-number "Phone number"
:email "Email"
:profile-no-status "No status"
:update-status "Update your 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."
:add-to-contacts "Add to contacts"
@ -292,6 +294,7 @@
:zero "No transactions confirmed"}
:transaction "Transaction"
:unsigned-transactions "Unsigned transactions"
:no-unsigned-transactions "No unsigned transactions"
:enter-password-transactions {:one "Confirm transaction by entering your password"
:other "Confirm transactions by entering your password"}
:status "Status"