first iteration, implemented profile screens and my profile screen

android styles, moved styles to platform files

implemented edit profile, refactored components

refactored common components, moved platform specific

styles small fix

fixes for code review

use defstyle macro
This commit is contained in:
Andrey Shovkoplyas 2017-03-17 17:37:54 +03:00 committed by Roman Volosovskyi
parent 990f9fcbf5
commit 1b6112a9bd
58 changed files with 782 additions and 475 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 792 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 647 B

After

Width:  |  Height:  |  Size: 788 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 356 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 501 B

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 388 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 930 B

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1007 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 691 B

View File

@ -39,6 +39,7 @@
[status-im.participants.views.remove :refer [remove-participants]] [status-im.participants.views.remove :refer [remove-participants]]
[status-im.group-settings.screen :refer [group-settings]] [status-im.group-settings.screen :refer [group-settings]]
[status-im.profile.screen :refer [profile my-profile]] [status-im.profile.screen :refer [profile my-profile]]
[status-im.profile.edit.screen :refer [edit-my-profile]]
[status-im.profile.photo-capture.screen :refer [profile-photo-capture]] [status-im.profile.photo-capture.screen :refer [profile-photo-capture]]
status-im.data-store.core status-im.data-store.core
[taoensso.timbre :as log] [taoensso.timbre :as log]
@ -133,11 +134,13 @@
:qr-scanner qr-scanner :qr-scanner qr-scanner
:chat chat :chat chat
:profile profile :profile profile
:my-profile my-profile
:edit-my-profile edit-my-profile
:profile-photo-capture profile-photo-capture :profile-photo-capture profile-photo-capture
:accounts accounts :accounts accounts
:login login :login login
:recover recover :recover recover)]
:my-profile my-profile)]
[menu-context st/flex [menu-context st/flex
[view st/flex [view st/flex
[component] [component]

View File

@ -74,7 +74,6 @@
:contact-inner-container {:height 56} :contact-inner-container {:height 56}
:contact-list-spacing {:background-color styles/color-white :contact-list-spacing {:background-color styles/color-white
:height 8} :height 8}
:separator {:height 0}
:icon-check {:border-radius 2 :icon-check {:border-radius 2
:width 17 :width 17
:height 17} :height 17}
@ -95,6 +94,22 @@
:name-text {:fontSize 16 :name-text {:fontSize 16
:line-height 24 :line-height 24
:color styles/text1-color}} :color styles/text1-color}}
:profile {:profile-bage {:padding-top 24}
:profile-name-text {:color styles/color-black
:font-size 16
:line-height 24}
:profile-status-text {:font-size 15
:line-height 20}
:profile-setting-item {:padding-left 72
:padding-right 13
:height 72}
:profile-setting-title {:font-size 12}
:profile-setting-text {:font-size 16
:color styles/color-black}
:profile-setting-spacing {:height 7}
:form-separator {:margin-left 72}
:edit-name-title {:font-size 12}
:profile-icon-edit-text {:font-size 12}}
:new-group {:group-name-text {:font-size 12} :new-group {:group-name-text {:font-size 12}
:members-text {:font-size 14} :members-text {:font-size 14}
:members-text-count {:font-size 14} :members-text-count {:font-size 14}
@ -119,10 +134,17 @@
:line-height 24} :line-height 24}
:reorder-list-container {:padding-top 16} :reorder-list-container {:padding-top 16}
:order-item-contacts {:font-size 16 :order-item-contacts {:font-size 16
:line-height 24}} :line-height 24}
:add-to-contacts-text {:font-size 14
:letter-spacing 0.5}}
:confirm-button-label {:color styles/color-white :confirm-button-label {:color styles/color-white
:font-size 14 :font-size 14
:letter-spacing 0.5} :letter-spacing 0.5}
:action-button-label {:color styles/color-black
:font-size 16
:line-height 24}
:action-button {:height 56}
:separator {:height 0}
: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}
@ -133,7 +155,8 @@
:toolbar-last-activity {:color styles/text2-color :toolbar-last-activity {:color styles/text2-color
:background-color :transparent :background-color :transparent
:top 0 :top 0
:font-size 12}}) :font-size 12}
:text-field-focus-line-height 2})
(def fonts (def fonts
{:light {:font-family "Roboto-Light"} {:light {:font-family "Roboto-Light"}
@ -166,10 +189,9 @@
:render-separator? false} :render-separator? false}
:uppercase? true :uppercase? true
:contacts {:action-button? true :contacts {:action-button? true
:new-contact-in-toolbar? false :new-contact-in-toolbar? false}
:group-block-shadows? true} :group-block-shadows? true
:discover {:uppercase-subtitles? false} :discover {:uppercase-subtitles? false}
:public-group-icon-container {:margin-top 4} :public-group-icon-container {:margin-top 4}
:private-group-icon-container {:margin-top 6} :private-group-icon-container {:margin-top 6}
:group-chat-focus-line-height 2
:public-group-chat-hash-style {:top 10 :left 4}}) :public-group-chat-hash-style {:top 10 :left 4}})

View File

@ -9,8 +9,7 @@
icon icon
image image
touchable-highlight]] touchable-highlight]]
[status-im.components.action-button :refer [action-button [status-im.components.native-action-button :refer [native-action-button]]
action-button-item]]
[status-im.components.drawer.view :refer [open-drawer]] [status-im.components.drawer.view :refer [open-drawer]]
[status-im.components.styles :refer [color-blue]] [status-im.components.styles :refer [color-blue]]
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
@ -62,12 +61,12 @@
:search-placeholder (label :t/search-for)}]) :search-placeholder (label :t/search-for)}])
(defn chats-action-button [] (defn chats-action-button []
[action-button {:button-color color-blue [native-action-button {:button-color color-blue
:offset-x 16 :offset-x 16
:offset-y 22 :offset-y 22
:hide-shadow true :hide-shadow true
:spacing 13 :spacing 13
:on-press #(dispatch [:navigate-to :new-chat])}]) :on-press #(dispatch [:navigate-to :new-chat])}])
(defn chat-list-padding [] (defn chat-list-padding []
[view {:height (if ios? 0 8) [view {:height (if ios? 0 8)

View File

@ -1,7 +0,0 @@
(ns status-im.components.action-button
(:require [reagent.core :as r]))
(def class (js/require "react-native-action-button"))
(def action-button (r/adapt-react-class (.-default class)))
(def action-button-item (r/adapt-react-class (.. class -default -Item)))

View File

@ -0,0 +1,19 @@
(ns status-im.components.action-button.action-button
(:require [status-im.components.action-button.styles :as st]
[status-im.components.common.common :refer [separator]]
[status-im.components.react :refer [view
text
icon
touchable-highlight]]))
(defn action-button [label icon-key on-press]
[touchable-highlight {:on-press on-press}
[view st/action-button
[view st/action-button-icon-container
[icon icon-key]]
[view st/action-button-label-container
[text {:style st/action-button-label}
label]]]])
(defn action-separator []
[separator st/action-separator])

View File

@ -0,0 +1,30 @@
(ns status-im.components.action-button.styles
(:require [status-im.utils.platform :as p]
[status-im.components.styles :refer [color-white
color-light-blue-transparent
color-light-blue
color-black]]))
(def action-button
(merge (get-in p/platform-specific [:component-styles :action-button])
{:padding-left 16
:flex-direction :row
:align-items :center}))
(def action-button-icon-container
(merge (get-in p/platform-specific [:component-styles :action-button-icon-container])
{:border-radius 50
:width 40
:height 40
:align-items :center
:justify-content :center}))
(def action-button-label-container
{:padding-left 16})
(def action-button-label
(get-in p/platform-specific [:component-styles :action-button-label]))
(def action-separator
{:margin-left 72})

View File

@ -147,23 +147,30 @@
:default-chat-icon (st/default-chat-icon-chat-list default-chat-color) :default-chat-icon (st/default-chat-icon-chat-list default-chat-color)
:default-chat-icon-text st/default-chat-icon-text}]) :default-chat-icon-text st/default-chat-icon-text}])
(defn profile-icon-view [photo-path name color badge-type] (defn profile-icon-view [photo-path name color edit? size]
(let [styles {:container st/container-profile (let [styles {:container {:width size :height size}
:online-view st/online-view-profile :online-view st/online-view-profile
:online-dot-left st/online-dot-left-profile :online-dot-left st/online-dot-left-profile
:online-dot-right st/online-dot-right-profile :online-dot-right st/online-dot-right-profile
:size 64 :size size
:chat-icon st/chat-icon-profile :chat-icon st/chat-icon-profile
:default-chat-icon (st/default-chat-icon-profile color) :default-chat-icon (st/default-chat-icon-profile color)
:default-chat-icon-text st/default-chat-icon-text}] :default-chat-icon-text st/default-chat-icon-text}]
[view (:container styles) [view (:container styles)
(when edit?
[view (st/profile-icon-mask size)])
(when edit?
[view (st/profile-icon-edit-text-containter size)
[text {:style st/profile-icon-edit-text}
"Edit"]])
(if (and photo-path (seq photo-path)) (if (and photo-path (seq photo-path))
[chat-icon photo-path styles] [chat-icon photo-path styles]
[default-chat-icon name styles]) [default-chat-icon name styles])]))
[contact-badge badge-type styles]]))
(defn my-profile-icon [{{:keys [photo-path name]} :account (defn my-profile-icon [{{:keys [photo-path name]} :account
edit? :edit?}] edit? :edit?}]
(let [type (if edit? :edit :blank) (let [color default-chat-color
color default-chat-color] size (if edit? 70 56)]
[profile-icon-view photo-path name color type])) [profile-icon-view photo-path name color edit? size]))

View File

@ -1,6 +1,7 @@
(ns status-im.components.chat-icon.styles (ns status-im.components.chat-icon.styles
(:require [status-im.components.styles :refer [color-white (:require [status-im.components.styles :refer [color-white
online-color]])) online-color]]
[status-im.utils.platform :as p]))
(defn default-chat-icon [color] (defn default-chat-icon [color]
{:margin 0 {:margin 0
@ -237,3 +238,26 @@
:width 4 :width 4
:height 4 :height 4
:border-radius 2}) :border-radius 2})
(defn profile-icon-mask [size]
{:height size
:width size
:position :absolute
:z-index 1
:background-color :black
:opacity 0.4
:border-radius 50})
(defn profile-icon-edit-text-containter [size]
{:height size
:width size
:position :absolute
:z-index 2
:align-items :center
:justify-content :center})
(def profile-icon-edit-text
(merge (get-in p/platform-specific [:component-styles :profile :profile-icon-edit-text])
{:color :white
:background-color :transparent}))

View File

@ -0,0 +1,17 @@
(ns status-im.components.common.common
(:require [status-im.components.react :refer [view linear-gradient]]
[status-im.components.common.styles :as st]))
(defn top-shaddow []
[linear-gradient
{:style st/gradient-bottom
:colors st/gradient-bottom-colors}])
(defn bottom-shaddow []
[linear-gradient
{:style st/gradient-top
:colors st/gradient-top-colors}])
(defn separator [style]
[view st/separator-wrapper
[view (merge st/separator style)]])

View File

@ -0,0 +1,28 @@
(ns status-im.components.common.styles
(:require [status-im.utils.platform :as p]
[status-im.components.styles :refer [color-white color-light-gray]]))
(def gradient-top
{:flexDirection :row
:height 3
:backgroundColor color-light-gray})
(def gradient-top-colors
["rgba(24, 52, 76, 0.165)"
"rgba(24, 52, 76, 0.03)"
"rgba(24, 52, 76, 0.01)"])
(def gradient-bottom
{:flexDirection :row
:height 2
:backgroundColor color-light-gray})
(def gradient-bottom-colors
["rgba(24, 52, 76, 0.01)"
"rgba(24, 52, 76, 0.05)"])
(def separator-wrapper
{:background-color color-white})
(def separator
(get-in p/platform-specific [:component-styles :separator]))

View File

@ -10,6 +10,10 @@
(defn open [opts] (defn open [opts]
(.open class (clj->js opts))) (.open class (clj->js opts)))
(defn share-options [text]
[{:text (label :t/sharing-copy-to-clipboard) :value #(copy-to-clipboard text)}
{:text (label :t/sharing-share) :value #(open {:message text})}])
(defn share [text dialog-title] (defn share [text dialog-title]
(let [list-selection-fn (:list-selection-fn platform-specific)] (let [list-selection-fn (:list-selection-fn platform-specific)]
(list-selection-fn {:title dialog-title (list-selection-fn {:title dialog-title

View File

@ -0,0 +1,7 @@
(ns status-im.components.native-action-button
(:require [reagent.core :as r]))
(def class (js/require "react-native-action-button"))
(def native-action-button (r/adapt-react-class (.-default class)))
(def native-action-button-item (r/adapt-react-class (.. class -default -Item)))

View File

@ -13,6 +13,7 @@
(def color-steel "#838b91") (def color-steel "#838b91")
(def color-white "white") (def color-white "white")
(def color-light-blue "#628fe3") (def color-light-blue "#628fe3")
(def color-light-blue-transparent "#628fe333")
(def color-light-blue2 "#eff3fc") (def color-light-blue2 "#eff3fc")
(def color-light-gray "#EEF2F5") (def color-light-gray "#EEF2F5")
(def color-red "red") (def color-red "red")

View File

@ -92,8 +92,7 @@
(log/debug "Input blurred") (log/debug "Input blurred")
(r/set-state component {:has-focus false (r/set-state component {:has-focus false
:float-label? (if (s/blank? value) false true)}) :float-label? (if (s/blank? value) false true)})
(when (s/blank? value) (field-animation animation)
(field-animation animation))
(when onBlur (onBlur))) (when onBlur (onBlur)))
(defn get-width [event] (defn get-width [event]
@ -113,7 +112,8 @@
max-length]} (r/state component) max-length]} (r/state component)
{:keys [wrapper-style input-style label-hidden? line-color focus-line-color focus-line-height {:keys [wrapper-style input-style label-hidden? line-color focus-line-color focus-line-height
secure-text-entry label-color error-color error label value on-focus on-blur validator secure-text-entry label-color error-color error label value on-focus on-blur validator
auto-focus on-change-text on-change on-end-editing editable placeholder auto-capitalize]} auto-focus on-change-text on-change on-end-editing editable placeholder auto-capitalize
multiline number-of-lines]}
(merge default-props (r/props component)) (merge default-props (r/props component))
line-color (if error error-color line-color) line-color (if error error-color line-color)
focus-line-color (if error error-color focus-line-color) focus-line-color (if error error-color focus-line-color)
@ -127,6 +127,8 @@
:style (merge st/text-input input-style) :style (merge st/text-input input-style)
:placeholder (or placeholder "") :placeholder (or placeholder "")
:editable editable :editable editable
:multiline multiline
:number-of-lines number-of-lines
:secure-text-entry secure-text-entry :secure-text-entry secure-text-entry
:auto-capitalize auto-capitalize :auto-capitalize auto-capitalize
:on-focus #(on-input-focus {:component component :on-focus #(on-input-focus {:component component

View File

@ -23,6 +23,7 @@
custom-action :custom-action custom-action :custom-action
background-color :background-color background-color :background-color
custom-content :custom-content custom-content :custom-content
hide-border? :hide-border?
style :style}] style :style}]
(let [style (merge (st/toolbar-wrapper background-color) style)] (let [style (merge (st/toolbar-wrapper background-color) style)]
[view {:style style} [view {:style style}
@ -63,8 +64,9 @@
{:key (str "action-" action-image)})) {:key (str "action-" action-image)}))
custom-action)]] custom-action)]]
[sync-state-gradient-view] [sync-state-gradient-view]
[view st/toolbar-border-container (when-not hide-border?
[view st/toolbar-border]]])) [view st/toolbar-border-container
[view st/toolbar-border]])]))
(def search-text-input (r/atom nil)) (def search-text-input (r/atom nil))

View File

@ -3,17 +3,18 @@
(:require [reagent.core :as r] (:require [reagent.core :as r]
[clojure.string :as str] [clojure.string :as str]
[re-frame.core :refer [subscribe dispatch dispatch-sync]] [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[status-im.components.common.common :refer [separator]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
image image
icon icon
touchable-highlight touchable-highlight
linear-gradient
scroll-view scroll-view
list-view list-view
list-item] :as react] list-item] :as react]
[status-im.components.action-button :refer [action-button [status-im.components.common.common :refer [top-shaddow bottom-shaddow]]
action-button-item]] [status-im.components.native-action-button :refer [native-action-button
native-action-button-item]]
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar-new.view :refer [toolbar]] [status-im.components.toolbar-new.view :refer [toolbar]]
[status-im.components.toolbar-new.actions :as act] [status-im.components.toolbar-new.actions :as act]
@ -73,22 +74,14 @@
(when extended? (when extended?
[options-btn group])]) [options-btn group])])
(defn group-top-view []
[linear-gradient {:style st/contact-group-header-gradient-bottom
:colors st/contact-group-header-gradient-bottom-colors}])
(defn group-bottom-view []
[linear-gradient {:style st/contact-group-header-gradient-top
:colors st/contact-group-header-gradient-top-colors}])
(defn contact-group-form [{:keys [contacts contacts-count group edit? click-handler]}] (defn contact-group-form [{:keys [contacts contacts-count group edit? click-handler]}]
(let [shadows? (get-in platform-specific [:contacts :group-block-shadows?]) (let [shadows? (get-in platform-specific [:group-block-shadows?])
subtitle (:name group)] subtitle (:name group)]
[view st/contact-group [view st/contact-group
(when subtitle (when subtitle
[subtitle-view subtitle contacts-count group edit?]) [subtitle-view subtitle contacts-count group edit?])
(when (and subtitle shadows?) (when (and subtitle shadows?)
[group-top-view]) [top-shaddow])
[view st/contacts-list [view st/contacts-list
[view st/contact-list-spacing] [view st/contact-list-spacing]
(doall (doall
@ -108,13 +101,11 @@
(:group-id group)]) (:group-id group)])
:text (label :t/remove-from-group)}])}] :text (label :t/remove-from-group)}])}]
(when-not (= contact (last contacts)) (when-not (= contact (last contacts))
[view st/contact-item-separator-wrapper [separator st/contact-item-separator])])
[view st/contact-item-separator]])])
contacts))] contacts))]
(when (< contacts-limit contacts-count) (when (< contacts-limit contacts-count)
[view [view
[view st/contact-item-separator-wrapper [separator st/contact-item-separator]
[view st/contact-item-separator]]
[view st/show-all [view st/show-all
[touchable-highlight {:on-press #(do [touchable-highlight {:on-press #(do
(when edit? (when edit?
@ -126,7 +117,7 @@
:font (get-in platform-specific [:component-styles :contacts :show-all-text-font])} :font (get-in platform-specific [:component-styles :contacts :show-all-text-font])}
(str (- contacts-count contacts-limit) " " (label :t/more))]]]]]) (str (- contacts-count contacts-limit) " " (label :t/more))]]]]])
(when shadows? (when shadows?
[group-bottom-view])])) [bottom-shaddow])]))
(defview contact-group-view [{:keys [group] :as params}] (defview contact-group-view [{:keys [group] :as params}]
[contacts [:all-added-group-contacts-with-limit (:group-id group) contacts-limit] [contacts [:all-added-group-contacts-with-limit (:group-id group) contacts-limit]
@ -135,12 +126,12 @@
:contacts-count contacts-count})]) :contacts-count contacts-count})])
(defn contacts-action-button [] (defn contacts-action-button []
[action-button {:button-color color-blue [native-action-button {:button-color color-blue
:offset-x 16 :offset-x 16
:offset-y 22 :offset-y 22
:hide-shadow true :hide-shadow true
:spacing 13} :spacing 13}
[action-button-item [native-action-button-item
{:title (label :t/new-contact) {:title (label :t/new-contact)
:buttonColor :#9b59b6 :buttonColor :#9b59b6
:onPress #(dispatch [:navigate-to :new-contact])} :onPress #(dispatch [:navigate-to :new-contact])}

View File

@ -52,25 +52,6 @@
{:margin-left 8 {:margin-left 8
:opacity 0.6}) :opacity 0.6})
(def contact-group-header-gradient-top
{:flexDirection :row
:height 3
:backgroundColor toolbar-background2})
(def contact-group-header-gradient-top-colors
["rgba(24, 52, 76, 0.165)"
"rgba(24, 52, 76, 0.03)"
"rgba(24, 52, 76, 0.01)"])
(def contact-group-header-gradient-bottom
{:flexDirection :row
:height 2
:backgroundColor toolbar-background2})
(def contact-group-header-gradient-bottom-colors
["rgba(24, 52, 76, 0.01)"
"rgba(24, 52, 76, 0.05)"])
(def show-all (def show-all
(merge (get-in p/platform-specific [:component-styles :contacts :show-all]) (merge (get-in p/platform-specific [:component-styles :contacts :show-all])
{:flexDirection :row {:flexDirection :row
@ -80,11 +61,8 @@
(def show-all-text (def show-all-text
(get-in p/platform-specific [:component-styles :contacts :show-all-text])) (get-in p/platform-specific [:component-styles :contacts :show-all-text]))
(def contact-item-separator-wrapper
{:background-color color-white})
(def contact-item-separator (def contact-item-separator
(get-in p/platform-specific [:component-styles :contacts :separator])) {:margin-left 72})
(def contact-container (def contact-container
(merge (get-in p/platform-specific [:component-styles :contacts :contact-container]) (merge (get-in p/platform-specific [:component-styles :contacts :contact-container])
@ -155,13 +133,6 @@
:alignItems :center :alignItems :center
:justifyContent :center}) :justifyContent :center})
(def search-btn
{:width 24
:height 56
:margin-right 24
:alignItems :center
:justifyContent :center})
; New contact ; New contact
(def contact-form-container (def contact-form-container

View File

@ -1,6 +1,7 @@
(ns status-im.contacts.views.contact-list (ns status-im.contacts.views.contact-list
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]]
[status-im.components.common.common :refer [separator]]
[status-im.components.react :refer [view text [status-im.components.react :refer [view text
image image
icon icon
@ -114,8 +115,7 @@
(defn render-separator [_ row-id _] (defn render-separator [_ row-id _]
(list-item ^{:key row-id} (list-item ^{:key row-id}
[view st/contact-item-separator-wrapper [separator st/contact-item-separator]))
[view st/contact-item-separator]]))
(defview contacts-list-view [group modal click-handler action edit?] (defview contacts-list-view [group modal click-handler action edit?]
[contacts [:all-added-group-contacts-filtered (:group-id group)] [contacts [:all-added-group-contacts-filtered (:group-id group)]

View File

@ -37,6 +37,7 @@
[status-im.participants.views.remove :refer [remove-participants]] [status-im.participants.views.remove :refer [remove-participants]]
[status-im.group-settings.screen :refer [group-settings]] [status-im.group-settings.screen :refer [group-settings]]
[status-im.profile.screen :refer [profile my-profile]] [status-im.profile.screen :refer [profile my-profile]]
[status-im.profile.edit.screen :refer [edit-my-profile]]
[status-im.profile.photo-capture.screen :refer [profile-photo-capture]] [status-im.profile.photo-capture.screen :refer [profile-photo-capture]]
status-im.data-store.core status-im.data-store.core
[taoensso.timbre :as log] [taoensso.timbre :as log]
@ -114,11 +115,13 @@
:qr-scanner qr-scanner :qr-scanner qr-scanner
:chat chat :chat chat
:profile profile :profile profile
:my-profile my-profile
:edit-my-profile edit-my-profile
:profile-photo-capture profile-photo-capture :profile-photo-capture profile-photo-capture
:accounts accounts :accounts accounts
:login login :login login
:recover recover :recover recover)]
:my-profile my-profile)]
[view [view
{:flex 1} {:flex 1}
[component] [component]

View File

@ -77,10 +77,6 @@
:subtitle-count {:color styles/color-gray4 :subtitle-count {:color styles/color-gray4
:font-size 16 :font-size 16
:letter-spacing -0.2} :letter-spacing -0.2}
:separator {:margin-left 72
:height 1
:background-color styles/color-gray5
:opacity 0.5}
:info-container {:margin-left 16} :info-container {:margin-left 16}
:contact-inner-container {:height 63} :contact-inner-container {:height 63}
:icon-check {:border-radius 50 :icon-check {:border-radius 50
@ -104,6 +100,29 @@
:line-height 20 :line-height 20
:letter-spacing -0.2 :letter-spacing -0.2
:color styles/text1-color}} :color styles/text1-color}}
:profile {:profile-bage {:padding-top 24}
:profile-name-text {:font-size 17
:line-height 20
:letter-spacing -0.2}
:profile-status-text {:font-size 14
:line-height 20
:letter-spacing -0.2}
:profile-setting-item {:padding-left 16
:padding-right 16
:height 73}
:profile-setting-title {:font-size 14
:letter-spacing -0.2}
:profile-setting-text {:font-size 17
:letter-spacing -0.2}
:profile-setting-spacing {:height 10}
:add-to-contacts-text {:font-size 17
:line-height 20
:letter-spacing -0.2}
:edit-name-title {:font-size 13
:letter-spacing -0.1}
:profile-icon-edit-text {:font-size 15
:line-height 20
:letter-spacing -0.2}}
:new-group {:group-name-text {:font-size 13} :new-group {:group-name-text {:font-size 13}
:members-text {:letter-spacing -0.2 :members-text {:letter-spacing -0.2
:font-size 16} :font-size 16}
@ -144,6 +163,15 @@
:font-size 17 :font-size 17
:line-height 20 :line-height 20
:letter-spacing -0.2} :letter-spacing -0.2}
:action-button-label {:color styles/color-light-blue
:letter-spacing -0.2
:font-size 17
:line-height 20}
:action-button-icon-container {:background-color styles/color-light-blue-transparent}
:action-button {:height 64}
:separator {:height 1
:background-color styles/color-gray5
:opacity 0.5}
:bottom-gradient {:height 1} :bottom-gradient {:height 1}
:input-label {:left 0} :input-label {:left 0}
:input-error-text {:margin-left 0} :input-error-text {:margin-left 0}
@ -159,7 +187,8 @@
:toolbar-last-activity {:color styles/text2-color :toolbar-last-activity {:color styles/text2-color
:background-color :transparent :background-color :transparent
:top 0 :top 0
:font-size 14}}) :font-size 14}
:text-field-focus-line-height 1})
(def fonts (def fonts
{:light {:font-family "SFUIText-Light"} {:light {:font-family "SFUIText-Light"}
@ -196,10 +225,10 @@
:render-separator? true} :render-separator? true}
:uppercase? false :uppercase? false
:contacts {:action-button? false :contacts {:action-button? false
:new-contact-in-toolbar? true :new-contact-in-toolbar? true}
:group-block-shadows? false} :group-block-shadows? false
:discover {:uppercase-subtitles? true} :discover {:uppercase-subtitles? true}
:public-group-icon-container {:margin-top 2} :public-group-icon-container {:margin-top 2}
:private-group-icon-container {:margin-top 2} :private-group-icon-container {:margin-top 2}
:group-chat-focus-line-height 1
:public-group-chat-hash-style {:top 6 :left 3}}) :public-group-chat-hash-style {:top 6 :left 3}})

View File

@ -62,7 +62,7 @@
(get-in platform-specific [:public-group-chat-hash-style]))) (get-in platform-specific [:public-group-chat-hash-style])))
(def group-chat-focus-line-height (def group-chat-focus-line-height
(get-in platform-specific [:group-chat-focus-line-height])) (get-in platform-specific [:component-styles :text-field-focus-line-height]))
(def group-chat-name-wrapper (def group-chat-name-wrapper
{:padding-top 0 {:padding-top 0

View File

@ -68,7 +68,7 @@
[view st/group-container [view st/group-container
[view {:flex 1} [view {:flex 1}
[group-toolbar type true] [group-toolbar type true]
[scroll-view {:keyboardShouldPersistTaps true} [scroll-view
[group-name-view] [group-name-view]
[chat-group-members] [chat-group-members]
[view st/separator] [view st/separator]

View File

@ -12,7 +12,7 @@
[status-im.utils.listview :refer [to-datasource]] [status-im.utils.listview :refer [to-datasource]]
[status-im.new-group.views.toggle-contact :refer [group-toggle-contact [status-im.new-group.views.toggle-contact :refer [group-toggle-contact
group-toggle-participant]] group-toggle-participant]]
[status-im.new-group.views.group :refer [separator]] [status-im.components.common.common :refer [separator]]
[status-im.new-group.styles :as st] [status-im.new-group.styles :as st]
[status-im.contacts.styles :as cst] [status-im.contacts.styles :as cst]
[status-im.i18n :refer [label]] [status-im.i18n :refer [label]]
@ -41,7 +41,7 @@
(defn render-separator [_ row-id _] (defn render-separator [_ row-id _]
(list-item ^{:key row-id} (list-item ^{:key row-id}
[separator])) [separator cst/contact-item-separator]))
(defn render-spacing [] (defn render-spacing []
#(list-item [view cst/contact-list-spacing])) #(list-item [view cst/contact-list-spacing]))

View File

@ -2,6 +2,7 @@
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [dispatch]] (:require [re-frame.core :refer [dispatch]]
[status-im.contacts.styles :as cst] [status-im.contacts.styles :as cst]
[status-im.components.common.common :as cmn]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
icon icon
@ -15,8 +16,7 @@
[status-im.i18n :refer [label]])) [status-im.i18n :refer [label]]))
(defn separator [] (defn separator []
[view cst/contact-item-separator-wrapper [cmn/separator cst/contact-item-separator])
[view cst/contact-item-separator]])
(defview group-name-input [] (defview group-name-input []
[new-group-name [:get :new-chat-name]] [new-group-name [:get :new-chat-name]]
@ -99,8 +99,7 @@
(defn more-btn [contacts-limit contacts-count on-press] (defn more-btn [contacts-limit contacts-count on-press]
[view [view
[view cst/contact-item-separator-wrapper [separator]
[view cst/contact-item-separator]]
[view cst/show-all [view cst/show-all
[touchable-highlight {:on-press on-press} [touchable-highlight {:on-press on-press}
[view [view

View File

@ -4,17 +4,16 @@
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
icon icon
linear-gradient
touchable-highlight touchable-highlight
list-item]] list-item]]
[status-im.components.confirm-button :refer [confirm-button]] [status-im.components.confirm-button :refer [confirm-button]]
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar-new.view :refer [toolbar]] [status-im.components.toolbar-new.view :refer [toolbar]]
[status-im.components.sortable-list-view :refer [sortable-list-view sortable-item]] [status-im.components.sortable-list-view :refer [sortable-list-view sortable-item]]
[status-im.components.common.common :refer [top-shaddow bottom-shaddow]]
[status-im.utils.listview :refer [to-datasource]] [status-im.utils.listview :refer [to-datasource]]
[status-im.utils.platform :refer [android?]] [status-im.utils.platform :refer [android?]]
[status-im.new-group.styles :as st] [status-im.new-group.styles :as st]
[status-im.contacts.styles :as cst]
[status-im.i18n :refer [label label-pluralize]] [status-im.i18n :refer [label label-pluralize]]
[status-im.utils.platform :refer [platform-specific]] [status-im.utils.platform :refer [platform-specific]]
[reagent.core :as r])) [reagent.core :as r]))
@ -35,14 +34,6 @@
[view st/order-item-icon [view st/order-item-icon
[icon :grab_gray]]]])) [icon :grab_gray]]]]))
(defn top-shaddow []
[linear-gradient {:style cst/contact-group-header-gradient-bottom
:colors cst/contact-group-header-gradient-bottom-colors}])
(defn bottom-shaddow []
[linear-gradient {:style cst/contact-group-header-gradient-top
:colors cst/contact-group-header-gradient-top-colors}])
(defn render-separator [last shadows?] (defn render-separator [last shadows?]
(fn [_ row-id _] (fn [_ row-id _]
(list-item (list-item
@ -57,7 +48,7 @@
(defview reorder-groups [] (defview reorder-groups []
[groups [:get :contact-groups] [groups [:get :contact-groups]
order [:get :groups-order] order [:get :groups-order]
shadows? (get-in platform-specific [:contacts :group-block-shadows?])] shadows? (get-in platform-specific [:group-block-shadows?])]
(let [this (r/current-component)] (let [this (r/current-component)]
[view st/reorder-groups-container [view st/reorder-groups-container
[status-bar] [status-bar]

View File

@ -0,0 +1,90 @@
(ns status-im.profile.edit.screen
(:require-macros [status-im.utils.views :refer [defview]])
(:require [status-im.profile.styles :as st]
[status-im.components.styles :refer [color-blue color-gray5]]
[re-frame.core :refer [dispatch]]
[status-im.components.status-bar :refer [status-bar]]
[status-im.components.toolbar-new.view :refer [toolbar]]
[status-im.components.toolbar-new.actions :as act]
[status-im.components.text-field.view :refer [text-field]]
[status-im.i18n :refer [label]]
[status-im.components.confirm-button :refer [confirm-button]]
[status-im.components.chat-icon.screen :refer [my-profile-icon]]
[status-im.components.context-menu :refer [context-menu]]
[status-im.profile.validations :as v]
[status-im.components.react :refer [view
scroll-view
text
touchable-highlight
text-input]]
[cljs.spec :as s]))
(defn edit-my-profile-toolbartoolbar []
[toolbar {:title (label :t/edit-profile)
:actions [{:image :blank}]}])
(defview profile-name-input []
[new-profile-name [:get-in [:profile-edit :name]]]
[view
[text-field
{:wrapper-style st/profile-name-wrapper
:line-color st/edit-line-color
:focus-line-color st/profile-focus-line-color
:focus-line-height st/profile-focus-line-height
:label-hidden? true
:input-style st/profile-name-input
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])
:value new-profile-name}]])
(def profile-icon-options
[{:text (label :t/image-source-gallery) :value #(dispatch [:open-image-picker])}
{:text (label :t/image-source-make-photo) :value #(dispatch [:navigate-to :profile-photo-capture])}])
(defn edit-profile-bage [contact]
[view st/edit-profile-bage
[view
[context-menu
[my-profile-icon {:account contact
:edit? true}]
profile-icon-options]]
[view st/edit-profile-name-container
[text {:style st/edit-name-title}
(label :t/name)]
[profile-name-input]]])
(defn edit-profile-status [{:keys [status]}]
[view st/edit-profile-status
[view
[text {:style st/edit-status-title} "Status"]
[view
[text-field
{:wrapper-style st/profile-status-wrapper
:line-color st/edit-line-color
:focus-line-color st/profile-focus-line-color
:focus-line-height st/profile-focus-line-height
:multiline true
:max-length 140
:placeholder (label :t/profile-no-status)
:label-hidden? true
:input-style st/profile-status-input
:on-change-text #(dispatch [:set-in [:profile-edit :status] %])
:value status}]]]])
(defview edit-my-profile []
[current-account [:get-current-account]
changed-account [:get :profile-edit]]
(let [profile-edit-data-valid? (s/valid? ::v/profile changed-account)
profile-edit-data-changed? (or (not= (:name current-account) (:name changed-account))
(not= (:status current-account) (:status changed-account))
(not= (:photo-path current-account) (:photo-path changed-account)))]
[view st/profile
[status-bar]
[edit-my-profile-toolbartoolbar]
[view {:flex 1}
[scroll-view st/edit-my-profile-form
[edit-profile-bage changed-account]
[edit-profile-status changed-account]]]
(when (and profile-edit-data-changed? profile-edit-data-valid?)
[confirm-button (label :t/save) #(do
(dispatch [:check-status-change (:status changed-account)])
(dispatch [:account-update changed-account]))])]))

View File

@ -1,5 +1,5 @@
(ns status-im.profile.handlers (ns status-im.profile.handlers
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [subscribe dispatch after]]
[status-im.utils.handlers :refer [register-handler]] [status-im.utils.handlers :refer [register-handler]]
[status-im.components.react :refer [show-image-picker]] [status-im.components.react :refer [show-image-picker]]
[status-im.utils.image-processing :refer [img->base64]] [status-im.utils.image-processing :refer [img->base64]]
@ -44,3 +44,23 @@
(fn [db _] (fn [db _]
(dispatch [:navigate-to :chat console-chat-id]) (dispatch [:navigate-to :chat console-chat-id])
(dispatch [:set-chat-command :phone])))) (dispatch [:set-chat-command :phone]))))
(register-handler :open-chat-with-the-send-transaction
(u/side-effect!
(fn [db [_ chat-id]]
(dispatch [:navigate-to :chat chat-id])
(dispatch [:set-chat-command :send]))))
(defn prepare-edit-profile
[{:keys [current-account-id] :as db} _]
(let [current-account (select-keys (get-in db [:accounts current-account-id])
[:name :photo-path :status])]
(update-in db [:profile-edit] merge current-account)))
(defn open-edit-profile [_ _]
(dispatch [:navigate-to :edit-my-profile]))
(register-handler
:open-edit-my-profile
(-> prepare-edit-profile
((after open-edit-profile))))

View File

@ -1,241 +1,211 @@
(ns status-im.profile.screen (ns status-im.profile.screen
(:require-macros [status-im.utils.views :refer [defview]]) (:require-macros [status-im.utils.views :refer [defview]])
(:require [re-frame.core :refer [subscribe dispatch]] (:require [re-frame.core :refer [dispatch]]
[clojure.string :as str] [clojure.string :as str]
[cljs.spec :as s]
[reagent.core :as r] [reagent.core :as r]
[status-im.contacts.styles :as cst]
[status-im.components.common.common :refer [separator]]
[status-im.components.styles :refer [color-blue color-gray5]]
[status-im.components.context-menu :refer [context-menu]]
[status-im.components.action-button.action-button :refer [action-button
action-separator]]
[status-im.components.common.common :refer [top-shaddow bottom-shaddow]]
[status-im.components.react :refer [view [status-im.components.react :refer [view
text text
text-input text-input
image image
icon icon
modal
scroll-view scroll-view
touchable-highlight touchable-highlight]]
touchable-opacity
touchable-without-feedback
show-image-picker
dismiss-keyboard!]]
[status-im.components.icons.custom-icons :refer [oct-icon]]
[status-im.components.chat-icon.screen :refer [my-profile-icon]] [status-im.components.chat-icon.screen :refer [my-profile-icon]]
[status-im.components.status-bar :refer [status-bar]] [status-im.components.status-bar :refer [status-bar]]
[status-im.components.text-field.view :refer [text-field]] [status-im.components.toolbar-new.view :refer [toolbar]]
[status-im.components.selectable-field.view :refer [selectable-field]] [status-im.components.toolbar-new.actions :as act]
[status-im.components.status-view.view :refer [status-view]] [status-im.components.list-selection :refer [share-options]]
[status-im.components.list-selection :refer [share]] [status-im.utils.platform :refer [platform-specific android?]]
[status-im.utils.phone-number :refer [format-phone-number]]
[status-im.utils.image-processing :refer [img->base64]]
[status-im.utils.platform :refer [platform-specific]]
[status-im.profile.handlers :refer [message-user]] [status-im.profile.handlers :refer [message-user]]
[status-im.profile.validations :as v]
[status-im.profile.styles :as st] [status-im.profile.styles :as st]
[status-im.utils.random :refer [id]] [status-im.i18n :refer [label]]
[status-im.utils.utils :refer [clean-text]] [status-im.utils.datetime :as time]))
[status-im.components.image-button.view :refer [show-qr-button]]
[status-im.i18n :refer [label
get-contact-translated]]
[status-im.constants :refer [console-chat-id wallet-chat-id]]))
(defn toolbar [{:keys [account edit?]}]
(let [profile-edit-data-valid? (s/valid? ::v/profile account)]
[view
[touchable-highlight {:style st/back-btn-touchable
:on-press (fn []
(dispatch [:set-in [:profile-edit :edit?] false])
(dispatch [:set-in [:profile-edit :name] nil])
(dispatch [:navigate-back]))}
[view st/back-btn-container
[icon :back st/back-btn-icon]]]
[touchable-highlight {:style st/actions-btn-touchable
:on-press (fn []
(if edit?
(when profile-edit-data-valid?
(dismiss-keyboard!)
(dispatch [:check-status-change (:status account)])
(dispatch [:account-update account])
(dispatch [:set-in [:profile-edit :edit?] false]))
(dispatch [:set :profile-edit (merge account {:edit? true})])))}
[view st/actions-btn-container
(if edit?
[oct-icon {:name :check
:style (st/ok-btn-icon profile-edit-data-valid?)}]
[icon :dots st/edit-btn-icon])]]]))
(defn status-image-view [_] (defn my-profile-toolbar []
(let [component (r/current-component) [toolbar {:actions [(act/opts [{:value #(dispatch [:open-edit-my-profile])
just-opened? (r/atom true) :text (label :t/edit)}])]}])
input-ref (r/atom nil)
set-status-height #(let [height (-> (.-nativeEvent %)
(.-contentSize)
(.-height))]
(r/set-state component {:height height}))]
(r/create-class
{:reagent-render
(fn [{{:keys [whisper-identity
name
status
photo-path]} :account
edit? :edit?}]
[view st/status-block
[view st/user-photo-container
(if edit? (defn online-text [last-online]
[touchable-highlight {:on-press (fn [] (let [last-online-date (time/to-date last-online)
(let [list-selection-fn (:list-selection-fn platform-specific)] now-date (time/now)]
(dispatch [:open-image-source-selector list-selection-fn])))} (if (and (pos? last-online)
[view (<= last-online-date now-date))
[my-profile-icon {:account {:photo-path photo-path (time/time-ago last-online-date)
:name name} (label :t/active-unknown))))
:edit? edit?}]]]
[my-profile-icon {:account {:photo-path photo-path
:name name}
:edit? edit?}])]
[text-field
{:line-color :white
:focus-line-color :white
:editable edit?
:input-style (st/username-input edit? (s/valid? ::v/name name))
:wrapper-style st/username-wrapper
:value (get-contact-translated whisper-identity :name name)
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])}]
(if (or edit? @just-opened?)
[text-input {:ref #(reset! input-ref %)
:style (st/status-input (:height (r/state component)))
:multiline true
:editable true
:on-content-size-change #(do (set-status-height %)
(reset! just-opened? false))
:max-length 140
:placeholder (label :t/profile-no-status)
:on-change-text #(let [status (clean-text %)]
(if (str/includes? % "\n")
(.blur @input-ref)
(dispatch [:set-in [:profile-edit :status] status])))
:default-value status}]
[status-view {:style (st/status-text (:height (r/state component)))
:status status}])])})))
(defview profile [] (defn profile-bage [{:keys [name last-online] :as contact}]
[{whisper-identity :whisper-identity [view st/profile-bage
address :address [my-profile-icon {:account contact
username :name :edit? false}]
photo-path :photo-path [view st/profile-name-container
phone :phone [text {:style st/profile-name-text}
status :status name]]
:as contact} [:contact]] (when-not (nil? last-online)
[scroll-view {:style st/profile} [view st/profile-status-container
[status-bar] [text {:style st/profile-status-text}
[view (online-text last-online)]])])
[touchable-highlight {:style st/back-btn-touchable
:on-press (fn []
(dispatch [:navigate-back]))}
[view (get-in platform-specific [:component-styles :toolbar-nav-action])
[icon :back st/back-btn-icon]]]
;; TODO not implemented
#_[touchable-highlight {:style st/actions-btn-touchable
:on-press (fn []
(.log js/console "Dots pressed!"))}
[view st/actions-btn-container
[icon :dots st/edit-btn-icon]]]]
[status-image-view {:account contact (defn add-to-contacts [pending? chat-id]
:photo-path photo-path [view
:edit? false}] (if pending?
[touchable-highlight {:on-press #(dispatch [:add-pending-contact chat-id])}
[view st/add-to-contacts
[text {:style st/add-to-contacts-text
:font (when android? :medium)
:uppercase? (get-in platform-specific [:uppercase?])}
(label :t/add-to-contacts)]]]
[view st/in-contacts
[icon :ok_blue]
[view st/in-contacts-inner
[text {:style st/in-contacts-text
:font (when android? :medium)
:uppercase? (get-in platform-specific [:uppercase?])}
(label :t/in-contacts)]]])])
[scroll-view (merge st/profile-properties-container {:keyboardShouldPersistTaps true (defn profile-actions [whisper-identity chat-id]
:bounces false}) [view st/profile-actions-container
[action-button (label :t/start-conversation)
:chats_blue
#(message-user whisper-identity)]
[action-separator]
[action-button (label :t/send-transaction)
:arrow_right_blue
#(dispatch [:open-chat-with-the-send-transaction chat-id])]])
[view st/status-block (defn profile-info-item [label value options text-mode]
[view st/btns-container [view st/profile-setting-item
[touchable-highlight {:onPress #(message-user whisper-identity)} [view st/profile-setting-text-container
[view st/message-btn [text {:style st/profile-setting-title}
[text {:style st/message-btn-text} (label :t/message)]]] label]
;; TODO not implemented [view st/profile-setting-spacing]
#_[touchable-highlight {:onPress #(.log js/console "Not yet implemented")} [text {:style st/profile-setting-text
[view st/more-btn :numberOfLines 1
[icon :more_vertical_blue st/more-btn-image]]]]] :ellipsizeMode text-mode}
value]]
(when options
[context-menu
[icon :options_gray]
options])])
[view st/profile-property-with-top-spacing (defn show-qr [contact qr-source]
[selectable-field {:label (label :t/phone-number) #(dispatch [:navigate-to-modal :qr-code-view {:contact contact
:editable? false :qr-source qr-source}]))
:value (if (and phone (not (str/blank? phone)))
(format-phone-number phone)
(label :t/not-specified))}]
[view st/underline-container]]
(when address (defn profile-info-address-item [{:keys [address] :as contact}]
[view st/profile-property [profile-info-item
[view st/profile-property-row (label :t/address)
[view st/profile-property-field address
[selectable-field {:label (label :t/address) (into []
:editable? false (concat [{:value (show-qr contact :address)
:value address :text (label :t/show-qr)}]
:on-press #(share address (label :t/address))}]] (share-options address)))
[show-qr-button {:handler #(dispatch [:navigate-to-modal :qr-code-view {:contact contact :middle])
:qr-source :whisper-identity}])}]]
[view st/underline-container]])
[view st/profile-property (defn profile-info-public-key-item [public-key contact]
[view st/profile-property-row [profile-info-item
[view st/profile-property-field (label :t/public-key)
[selectable-field {:label (label :t/public-key) public-key
:editable? false (into []
:value whisper-identity (concat [{:value (show-qr contact :public-key)
:on-press #(share whisper-identity (label :t/public-key))}]] :text (label :t/show-qr)}]
[show-qr-button {:handler #(dispatch [:navigate-to-modal :qr-code-view {:contact contact (share-options public-key)))
:qr-source :public-key}])}]]] :middle])
[view st/underline-container]]]) (defn info-item-separator []
[separator st/info-item-separator])
(defn tag-view [tag]
[text {:style {:color color-blue}
:font :medium}
(str tag " ")])
(defn colorize-status-hashtags [status]
(for [[i status] (map-indexed vector (str/split status #" "))]
(if (.startsWith status "#")
^{:key (str "item-" i)}
[tag-view status]
^{:key (str "item-" i)}
(str status " "))))
(defn profile-info [{:keys [whisper-identity :whisper-identity
status :status
phone :phone] :as contact}]
[view
[profile-info-item (label :t/status) (colorize-status-hashtags status)]
[info-item-separator]
[profile-info-address-item contact]
[info-item-separator]
[profile-info-public-key-item whisper-identity contact]
[info-item-separator]
[profile-info-item (label :t/phone-number) phone]])
(defn my-profile-info [{:keys [public-key :public-key
status :status
phone :phone] :as contact}]
[view
[profile-info-item
(label :t/status)
(colorize-status-hashtags status)
[{:value #(dispatch [:open-edit-my-profile])
:text (label :t/edit)}]]
[info-item-separator]
[profile-info-address-item contact]
[info-item-separator]
[profile-info-public-key-item public-key contact]
[info-item-separator]
[profile-info-item (label :t/phone-number) phone [{:value #(dispatch [:phone-number-change-requested])
:text (label :t/edit)}]]])
(defview my-profile [] (defview my-profile []
[edit? [:get-in [:profile-edit :edit?]] [current-account [:get-current-account]]
qr [:get-in [:profile-edit :qr-code]] (let [shadows? (get-in platform-specific [:group-block-shadows?])]
current-account [:get-current-account] [view st/profile
changed-account [:get :profile-edit]]
(let [{:keys [phone
address
public-key]
:as account} (if edit?
changed-account
current-account)]
[scroll-view {:style st/profile
:bounces false}
[status-bar] [status-bar]
[toolbar {:account account [my-profile-toolbar]
:edit? edit?}] [view st/my-profile-form
[profile-bage current-account]]
(when shadows?
[bottom-shaddow])
[view st/profile-info-container
(when shadows?
[top-shaddow])
[view st/profile-actions-container
[action-button (label :t/share-qr)
:q_r_blue
(show-qr current-account :public-key)]]
[view st/form-separator]
[my-profile-info current-account]
(when shadows?
[bottom-shaddow])]]))
[status-image-view {:account account (defview profile []
:edit? edit?}] [{:keys [pending?
whisper-identity]
[scroll-view (merge st/my-profile-properties-container {:bounces false}) :as contact} [:contact]
[view st/profile-property chat-id [:get :current-chat-id]]
[selectable-field {:label (label :t/phone-number) (let [shadows? (get-in platform-specific [:group-block-shadows?])]
:editable? edit? [view st/profile
:value (if (and phone (not (str/blank? phone))) [status-bar]
(format-phone-number phone) [toolbar]
(label :t/not-specified)) [scroll-view
:on-press #(dispatch [:phone-number-change-requested])}] [view st/profile-form
[view st/underline-container]] [profile-bage contact]
[add-to-contacts pending? chat-id]]
[view st/profile-property (when shadows?
[view st/profile-property-row [bottom-shaddow])
[view st/profile-property-field [view st/profile-info-container
[selectable-field {:label (label :t/address) (when shadows?
:editable? edit? [top-shaddow])
:value address [profile-actions whisper-identity chat-id]
:on-press #(share address (label :t/address))}]] [view st/form-separator]
[show-qr-button {:handler #(dispatch [:navigate-to-modal :qr-code-view {:contact account [profile-info contact]
:qr-source :address}])}]] (when shadows?
[view st/underline-container]] [bottom-shaddow])]]]))
[view st/profile-property
[view st/profile-property-row
[view st/profile-property-field
[selectable-field {:label (label :t/public-key)
:editable? edit?
:value public-key
:on-press #(share public-key (label :t/public-key))}]]
[show-qr-button {:handler #(dispatch [:navigate-to-modal :qr-code-view {:contact account
:qr-source :public-key}])}]]]
[view st/underline-container]]]))

View File

@ -1,168 +1,182 @@
(ns status-im.profile.styles (ns status-im.profile.styles
(:require-macros [status-im.utils.styles :refer [defstyle]])
(:require [status-im.components.styles :refer [color-white (:require [status-im.components.styles :refer [color-white
color-gray color-gray4
color-black color-gray5
color-blue color-light-gray
color-blue-transparent color-light-blue
text1-color color-light-blue-transparent
text1-disabled-color text1-color]]
text2-color
color-red
separator-color]]
[status-im.utils.platform :as p])) [status-im.utils.platform :as p]))
(defn ps-profile [item]
(get-in p/platform-specific [:component-styles :profile item]))
(def profile (def profile
{:flex 1 {:flex 1
:background-color color-white :background-color color-light-gray
:flex-direction :column}) :flex-direction :column})
(def back-btn-touchable (def profile-form
{:position :absolute}) {:background-color color-white
:padding-bottom 16})
(def back-btn-container (def my-profile-form
{:width 46 {:background-color color-white
:height 56 :padding-bottom 24})
:align-items :center
:justify-content :center})
(def back-btn-icon (def edit-my-profile-form
{:width 8 {:background-color color-white
:height 14}) :flex 1})
(def actions-btn-touchable (defstyle profile-info-container
{:position :absolute {:background-color color-white
:right 0}) :ios {:margin-top 16}
:android {:margin-top 12}})
(def actions-btn-container (defstyle profile-actions-container
{:width 56 {:android {:padding-top 8
:height 56 :padding-bottom 8}})
:align-items :center
:justify-content :center})
(def edit-btn-icon (def profile-bage
{:width 4 (merge (ps-profile :profile-bage)
:height 16}) {:align-items :center}))
(defn ok-btn-icon [enabled?] (def edit-profile-bage
{:font-size 22 {:flex-direction :row
:color (if enabled? color-black color-gray)}) :align-items :center
:padding-left 24
:padding-top 25})
(def user-photo-container (def profile-name-container
{:margin-top 22}) {:margin-top 12})
(def username-wrapper (defstyle edit-profile-name-container
{:width 300 {:flex 1
:margin-top (if p/ios? -18 -22) :ios {:padding-left 32
:margin-bottom -16}) :padding-top 11}
:android {:padding-top 16
:padding-left 16}})
(defn username-input [edit? valid?] (def edit-name-title
{:font-size 18 (merge (ps-profile :edit-name-title)
:text-align :center {:color color-gray4}))
:color (if edit?
(if valid? text1-color color-red)
text1-disabled-color)})
(def status-block (def edit-status-title
{:flex-direction "column" edit-name-title)
:align-items "center"
:justifyContent "center"
:margin-left 55
:margin-right 55})
(defn status-view [height] (def profile-name-text
{:align-self "stretch" (ps-profile :profile-name-text))
:font-size 14
:min-height height
:text-align "center"
:color text2-color})
(defn status-input [height] (def profile-status-container
(merge (status-view height) {:margin-top 4})
{:margin-left (if p/ios? 21 16)
:margin-right 16
:margin-top (if p/ios? 6 1)}))
(defn status-text [height] (def profile-status-text
(merge (status-view (- height (if p/ios? 5 10))) (merge (ps-profile :profile-status-text)
{:margin-left 18 {:color color-gray4}))
:margin-right 18
:margin-top 11
:margin-bottom 0}))
(def btns-container (def profile-setting-item
{:margin-top 0 (merge (ps-profile :profile-setting-item)
:flex-direction :row}) {:flex-direction :row
:align-items :center}))
(def message-btn (def profile-setting-text-container
{:height 40 {:flex 1
:justify-content :center :padding-right 20})
:background-color color-blue
:padding-left 25
:padding-right 25
:border-radius 20})
(def message-btn-text (def profile-setting-title
{:margin-top -2.5 (merge (ps-profile :profile-setting-title)
:font-size 14 {:color color-gray4}))
:color color-white})
(def more-btn (def profile-setting-text
{:margin-left 10 (ps-profile :profile-setting-text))
:width 40
:height 40
:align-items :center
:justify-content :center
:background-color color-blue-transparent
:padding 8
:border-radius 20})
(def more-btn-image (def profile-setting-spacing
{:width 4 (ps-profile :profile-setting-spacing))
:height 16})
(def profile-properties-container (def add-to-contacts
{:align-items :stretch {:margin-top 24
:flex-firection :column :margin-left 16
:margin-top 16}) :margin-right 16
:background-color color-light-blue
(def my-profile-properties-container
{:align-items :stretch
:flex-firection :column
:margin-top 32})
(def profile-property
{:margin-left 16})
(def profile-property-with-top-spacing
{:margin-top 32
:margin-left 16})
(def profile-property-row
{:flex 1
:flex-direction :row})
(def profile-property-field
{:margin-right 96
:flex 1})
(def report-user-text
{:font-size 14
:line-height 21
:color text2-color
;; IOS:
:letter-spacing 0.5})
(def qr-code
{:width 250
:height 250
:background-color "white"
:border-radius 4 :border-radius 4
:align-items :center :height 52
:padding-top 15 :align-items :center
:elevation 4}) :justify-content :center})
(def in-contacts
(merge add-to-contacts
{:flex-direction :row
:padding-right 40
:padding-left 16
:justify-content :flex-start
:background-color color-light-blue-transparent}))
(def in-contacts-inner
{:align-items :center
:flex 1})
(def add-to-contacts-text
(merge (ps-profile :add-to-contacts-text)
{:color color-white}))
(def in-contacts-text
(merge add-to-contacts-text
{:color color-light-blue}))
(def info-item-separator
{:margin-left 16})
(def form-separator
(merge (ps-profile :form-separator)
{:height 1
:background-color color-gray5
:opacity 0.5}))
(def profile-name-wrapper
{:padding-top 0
:margin-top 0
:margin-bottom 0
:height 42
:padding-bottom 0})
(defstyle profile-status-wrapper
{:padding-top 0
:margin-bottom 0
:height 85
:padding-bottom 1
:ios {:margin-top 3}
:android {:margin-top 1}})
(def edit-line-color
(if p/ios?
(str color-gray5 "80")
color-gray5))
(def profile-focus-line-color
color-light-blue)
(def profile-focus-line-height
(get-in p/platform-specific [:component-styles :text-field-focus-line-height]))
(defstyle profile-name-input
{:color text1-color
:ios {:font-size 17
:padding-bottom 0
:line-height 17
:letter-spacing -0.2}
:android {:font-size 16
:line-height 16
:padding-top 5
:height 30
:padding-bottom 0}})
(defstyle profile-status-input
{:height 82
:line-height 24;;TODO doesnt' work for multiline because bug in the RN
:android {:padding-top 0}})
(def edit-profile-status
{:padding-left 16
:padding-top 35})
(def underline-container
{:background-color separator-color
:margin-bottom 18
:height 1
:align-items :center})

View File

@ -68,6 +68,7 @@
;profile ;profile
:profile "Profile" :profile "Profile"
:edit-profile "Edit profile"
:report-user "REPORT USER" :report-user "REPORT USER"
:message "Message" :message "Message"
:username "Username" :username "Username"
@ -77,6 +78,10 @@
:email "Email" :email "Email"
:profile-no-status "No status" :profile-no-status "No status"
:add-to-contacts "Add to contacts" :add-to-contacts "Add to contacts"
:in-contacts "In contacts"
:start-conversation "Start conversation"
:send-transaction "Send transaction"
:share-qr "Share QR"
:error-incorrect-name "Please select another name" :error-incorrect-name "Please select another name"
:error-incorrect-email "Incorrect e-mail" :error-incorrect-email "Incorrect e-mail"

View File

@ -1,5 +1,5 @@
(ns status-im.utils.datetime (ns status-im.utils.datetime
(:require [cljs-time.core :as t :refer [date-time now plus days hours before?]] (:require [cljs-time.core :as t :refer [date-time plus days hours before?]]
[cljs-time.coerce :refer [from-long to-long from-date]] [cljs-time.coerce :refer [from-long to-long from-date]]
[cljs-time.format :refer [formatters [cljs-time.format :refer [formatters
formatter formatter
@ -8,6 +8,9 @@
[goog.string :as gstring] [goog.string :as gstring]
goog.string.format)) goog.string.format))
(defn now []
(t/now))
(def hour (* 1000 60 60)) (def hour (* 1000 60 60))
(def day (* hour 24)) (def day (* hour 24))
(def week (* 7 day)) (def week (* 7 day))