diff --git a/android/app/src/main/res/drawable-hdpi/icon_arrow_right_blue.png b/android/app/src/main/res/drawable-hdpi/icon_arrow_right_blue.png new file mode 100644 index 0000000000..a5629972e1 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/icon_arrow_right_blue.png differ diff --git a/android/app/src/main/res/drawable-hdpi/icon_chats_blue.png b/android/app/src/main/res/drawable-hdpi/icon_chats_blue.png new file mode 100644 index 0000000000..6f555e7d83 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/icon_chats_blue.png differ diff --git a/android/app/src/main/res/drawable-hdpi/icon_ok_blue.png b/android/app/src/main/res/drawable-hdpi/icon_ok_blue.png index 66e62ce1a3..a067f8d04d 100644 Binary files a/android/app/src/main/res/drawable-hdpi/icon_ok_blue.png and b/android/app/src/main/res/drawable-hdpi/icon_ok_blue.png differ diff --git a/android/app/src/main/res/drawable-hdpi/icon_q_r_blue.png b/android/app/src/main/res/drawable-hdpi/icon_q_r_blue.png new file mode 100644 index 0000000000..ae26f3c5ee Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/icon_q_r_blue.png differ diff --git a/android/app/src/main/res/drawable-mdpi/icon_arrow_right_blue.png b/android/app/src/main/res/drawable-mdpi/icon_arrow_right_blue.png new file mode 100644 index 0000000000..cace86fba3 Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/icon_arrow_right_blue.png differ diff --git a/android/app/src/main/res/drawable-mdpi/icon_chats_blue.png b/android/app/src/main/res/drawable-mdpi/icon_chats_blue.png new file mode 100644 index 0000000000..e19d918472 Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/icon_chats_blue.png differ diff --git a/android/app/src/main/res/drawable-mdpi/icon_ok_blue.png b/android/app/src/main/res/drawable-mdpi/icon_ok_blue.png index 8b6c5482cf..dfc5073656 100644 Binary files a/android/app/src/main/res/drawable-mdpi/icon_ok_blue.png and b/android/app/src/main/res/drawable-mdpi/icon_ok_blue.png differ diff --git a/android/app/src/main/res/drawable-mdpi/icon_q_r_blue.png b/android/app/src/main/res/drawable-mdpi/icon_q_r_blue.png new file mode 100644 index 0000000000..0492d497be Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/icon_q_r_blue.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/icon_arrow_right_blue.png b/android/app/src/main/res/drawable-xhdpi/icon_arrow_right_blue.png new file mode 100644 index 0000000000..4c42595735 Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/icon_arrow_right_blue.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/icon_chats_blue.png b/android/app/src/main/res/drawable-xhdpi/icon_chats_blue.png new file mode 100644 index 0000000000..31c25b335c Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/icon_chats_blue.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/icon_ok_blue.png b/android/app/src/main/res/drawable-xhdpi/icon_ok_blue.png index df4ddc7541..f3db17d788 100644 Binary files a/android/app/src/main/res/drawable-xhdpi/icon_ok_blue.png and b/android/app/src/main/res/drawable-xhdpi/icon_ok_blue.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/icon_q_r_blue.png b/android/app/src/main/res/drawable-xhdpi/icon_q_r_blue.png new file mode 100644 index 0000000000..47c6572dac Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/icon_q_r_blue.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/icon_arrow_right_blue.png b/android/app/src/main/res/drawable-xxhdpi/icon_arrow_right_blue.png new file mode 100644 index 0000000000..ea4618c98e Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/icon_arrow_right_blue.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/icon_chats_blue.png b/android/app/src/main/res/drawable-xxhdpi/icon_chats_blue.png new file mode 100644 index 0000000000..7f13becbd3 Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/icon_chats_blue.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/icon_ok_blue.png b/android/app/src/main/res/drawable-xxhdpi/icon_ok_blue.png index 9e8661249d..364e066479 100644 Binary files a/android/app/src/main/res/drawable-xxhdpi/icon_ok_blue.png and b/android/app/src/main/res/drawable-xxhdpi/icon_ok_blue.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/icon_q_r_blue.png b/android/app/src/main/res/drawable-xxhdpi/icon_q_r_blue.png new file mode 100644 index 0000000000..b5a758fb6f Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/icon_q_r_blue.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/icon_arrow_right_blue.png b/android/app/src/main/res/drawable-xxxhdpi/icon_arrow_right_blue.png new file mode 100644 index 0000000000..d840b0b5de Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/icon_arrow_right_blue.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/icon_chats_blue.png b/android/app/src/main/res/drawable-xxxhdpi/icon_chats_blue.png new file mode 100644 index 0000000000..9b76c71c93 Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/icon_chats_blue.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/icon_ok_blue.png b/android/app/src/main/res/drawable-xxxhdpi/icon_ok_blue.png index f8a9b938b4..e2e5d28a0b 100644 Binary files a/android/app/src/main/res/drawable-xxxhdpi/icon_ok_blue.png and b/android/app/src/main/res/drawable-xxxhdpi/icon_ok_blue.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/icon_q_r_blue.png b/android/app/src/main/res/drawable-xxxhdpi/icon_q_r_blue.png new file mode 100644 index 0000000000..703b7be0a2 Binary files /dev/null and b/android/app/src/main/res/drawable-xxxhdpi/icon_q_r_blue.png differ diff --git a/ios/StatusIm/Images.xcassets/icon_arrow_right_blue.imageset/Contents.json b/ios/StatusIm/Images.xcassets/icon_arrow_right_blue.imageset/Contents.json new file mode 100644 index 0000000000..4caca9dce0 --- /dev/null +++ b/ios/StatusIm/Images.xcassets/icon_arrow_right_blue.imageset/Contents.json @@ -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" + } +} \ No newline at end of file diff --git a/ios/StatusIm/Images.xcassets/icon_arrow_right_blue.imageset/icon_arrow_right_blue.png b/ios/StatusIm/Images.xcassets/icon_arrow_right_blue.imageset/icon_arrow_right_blue.png new file mode 100644 index 0000000000..4c42595735 Binary files /dev/null and b/ios/StatusIm/Images.xcassets/icon_arrow_right_blue.imageset/icon_arrow_right_blue.png differ diff --git a/ios/StatusIm/Images.xcassets/icon_chats_blue.imageset/Contents.json b/ios/StatusIm/Images.xcassets/icon_chats_blue.imageset/Contents.json new file mode 100644 index 0000000000..93f4992915 --- /dev/null +++ b/ios/StatusIm/Images.xcassets/icon_chats_blue.imageset/Contents.json @@ -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" + } +} \ No newline at end of file diff --git a/ios/StatusIm/Images.xcassets/icon_chats_blue.imageset/icon_chats_blue.png b/ios/StatusIm/Images.xcassets/icon_chats_blue.imageset/icon_chats_blue.png new file mode 100644 index 0000000000..31c25b335c Binary files /dev/null and b/ios/StatusIm/Images.xcassets/icon_chats_blue.imageset/icon_chats_blue.png differ diff --git a/ios/StatusIm/Images.xcassets/icon_ok_blue.imageset/icon_ok_blue.png b/ios/StatusIm/Images.xcassets/icon_ok_blue.imageset/icon_ok_blue.png index 9e8661249d..f3db17d788 100644 Binary files a/ios/StatusIm/Images.xcassets/icon_ok_blue.imageset/icon_ok_blue.png and b/ios/StatusIm/Images.xcassets/icon_ok_blue.imageset/icon_ok_blue.png differ diff --git a/ios/StatusIm/Images.xcassets/icon_q_r_blue.imageset/Contents.json b/ios/StatusIm/Images.xcassets/icon_q_r_blue.imageset/Contents.json new file mode 100644 index 0000000000..81f28a1dd5 --- /dev/null +++ b/ios/StatusIm/Images.xcassets/icon_q_r_blue.imageset/Contents.json @@ -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" + } +} \ No newline at end of file diff --git a/ios/StatusIm/Images.xcassets/icon_q_r_blue.imageset/icon_q_r_blue.png b/ios/StatusIm/Images.xcassets/icon_q_r_blue.imageset/icon_q_r_blue.png new file mode 100644 index 0000000000..47c6572dac Binary files /dev/null and b/ios/StatusIm/Images.xcassets/icon_q_r_blue.imageset/icon_q_r_blue.png differ diff --git a/src/status_im/android/core.cljs b/src/status_im/android/core.cljs index b607fa3ce1..400d436700 100644 --- a/src/status_im/android/core.cljs +++ b/src/status_im/android/core.cljs @@ -39,6 +39,7 @@ [status-im.participants.views.remove :refer [remove-participants]] [status-im.group-settings.screen :refer [group-settings]] [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.data-store.core [taoensso.timbre :as log] @@ -133,11 +134,13 @@ :qr-scanner qr-scanner :chat chat :profile profile + :my-profile my-profile + :edit-my-profile edit-my-profile :profile-photo-capture profile-photo-capture :accounts accounts :login login - :recover recover - :my-profile my-profile)] + :recover recover)] + [menu-context st/flex [view st/flex [component] diff --git a/src/status_im/android/platform.cljs b/src/status_im/android/platform.cljs index 8e61ee2ed2..6190ed5b60 100644 --- a/src/status_im/android/platform.cljs +++ b/src/status_im/android/platform.cljs @@ -74,7 +74,6 @@ :contact-inner-container {:height 56} :contact-list-spacing {:background-color styles/color-white :height 8} - :separator {:height 0} :icon-check {:border-radius 2 :width 17 :height 17} @@ -95,6 +94,22 @@ :name-text {:fontSize 16 :line-height 24 :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} :members-text {:font-size 14} :members-text-count {:font-size 14} @@ -119,10 +134,17 @@ :line-height 24} :reorder-list-container {:padding-top 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 :font-size 14 :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} :input-label {:left 4} :input-error-text {:margin-left 4} @@ -133,7 +155,8 @@ :toolbar-last-activity {:color styles/text2-color :background-color :transparent :top 0 - :font-size 12}}) + :font-size 12} + :text-field-focus-line-height 2}) (def fonts {:light {:font-family "Roboto-Light"} @@ -166,10 +189,9 @@ :render-separator? false} :uppercase? true :contacts {:action-button? true - :new-contact-in-toolbar? false - :group-block-shadows? true} + :new-contact-in-toolbar? false} + :group-block-shadows? true :discover {:uppercase-subtitles? false} :public-group-icon-container {:margin-top 4} :private-group-icon-container {:margin-top 6} - :group-chat-focus-line-height 2 :public-group-chat-hash-style {:top 10 :left 4}}) diff --git a/src/status_im/chats_list/screen.cljs b/src/status_im/chats_list/screen.cljs index ad5bf38185..04cfb0d692 100644 --- a/src/status_im/chats_list/screen.cljs +++ b/src/status_im/chats_list/screen.cljs @@ -9,8 +9,7 @@ icon image touchable-highlight]] - [status-im.components.action-button :refer [action-button - action-button-item]] + [status-im.components.native-action-button :refer [native-action-button]] [status-im.components.drawer.view :refer [open-drawer]] [status-im.components.styles :refer [color-blue]] [status-im.components.status-bar :refer [status-bar]] @@ -62,12 +61,12 @@ :search-placeholder (label :t/search-for)}]) (defn chats-action-button [] - [action-button {:button-color color-blue - :offset-x 16 - :offset-y 22 - :hide-shadow true - :spacing 13 - :on-press #(dispatch [:navigate-to :new-chat])}]) + [native-action-button {:button-color color-blue + :offset-x 16 + :offset-y 22 + :hide-shadow true + :spacing 13 + :on-press #(dispatch [:navigate-to :new-chat])}]) (defn chat-list-padding [] [view {:height (if ios? 0 8) diff --git a/src/status_im/components/action_button.cljs b/src/status_im/components/action_button.cljs deleted file mode 100644 index 6ee896d1ed..0000000000 --- a/src/status_im/components/action_button.cljs +++ /dev/null @@ -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))) diff --git a/src/status_im/components/action_button/action_button.cljs b/src/status_im/components/action_button/action_button.cljs new file mode 100644 index 0000000000..28f991fb68 --- /dev/null +++ b/src/status_im/components/action_button/action_button.cljs @@ -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]) diff --git a/src/status_im/components/action_button/styles.cljs b/src/status_im/components/action_button/styles.cljs new file mode 100644 index 0000000000..16462cd0ef --- /dev/null +++ b/src/status_im/components/action_button/styles.cljs @@ -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}) + diff --git a/src/status_im/components/chat_icon/screen.cljs b/src/status_im/components/chat_icon/screen.cljs index 95e576c848..6e6a6f43b9 100644 --- a/src/status_im/components/chat_icon/screen.cljs +++ b/src/status_im/components/chat_icon/screen.cljs @@ -147,23 +147,30 @@ :default-chat-icon (st/default-chat-icon-chat-list default-chat-color) :default-chat-icon-text st/default-chat-icon-text}]) -(defn profile-icon-view [photo-path name color badge-type] - (let [styles {:container st/container-profile +(defn profile-icon-view [photo-path name color edit? size] + (let [styles {:container {:width size :height size} :online-view st/online-view-profile :online-dot-left st/online-dot-left-profile :online-dot-right st/online-dot-right-profile - :size 64 + :size size :chat-icon st/chat-icon-profile :default-chat-icon (st/default-chat-icon-profile color) :default-chat-icon-text st/default-chat-icon-text}] [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)) [chat-icon photo-path styles] - [default-chat-icon name styles]) - [contact-badge badge-type styles]])) + [default-chat-icon name styles])])) + + (defn my-profile-icon [{{:keys [photo-path name]} :account edit? :edit?}] - (let [type (if edit? :edit :blank) - color default-chat-color] - [profile-icon-view photo-path name color type])) + (let [color default-chat-color + size (if edit? 70 56)] + [profile-icon-view photo-path name color edit? size])) \ No newline at end of file diff --git a/src/status_im/components/chat_icon/styles.cljs b/src/status_im/components/chat_icon/styles.cljs index bde6566d6d..efa2efdef6 100644 --- a/src/status_im/components/chat_icon/styles.cljs +++ b/src/status_im/components/chat_icon/styles.cljs @@ -1,6 +1,7 @@ (ns status-im.components.chat-icon.styles (:require [status-im.components.styles :refer [color-white - online-color]])) + online-color]] + [status-im.utils.platform :as p])) (defn default-chat-icon [color] {:margin 0 @@ -237,3 +238,26 @@ :width 4 :height 4 :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})) + diff --git a/src/status_im/components/common/common.cljs b/src/status_im/components/common/common.cljs new file mode 100644 index 0000000000..d8adad2a11 --- /dev/null +++ b/src/status_im/components/common/common.cljs @@ -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)]]) diff --git a/src/status_im/components/common/styles.cljs b/src/status_im/components/common/styles.cljs new file mode 100644 index 0000000000..a095311e3b --- /dev/null +++ b/src/status_im/components/common/styles.cljs @@ -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])) diff --git a/src/status_im/components/list_selection.cljs b/src/status_im/components/list_selection.cljs index 5cd31c40ea..ea9c139cbd 100644 --- a/src/status_im/components/list_selection.cljs +++ b/src/status_im/components/list_selection.cljs @@ -10,6 +10,10 @@ (defn open [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] (let [list-selection-fn (:list-selection-fn platform-specific)] (list-selection-fn {:title dialog-title diff --git a/src/status_im/components/native_action_button.cljs b/src/status_im/components/native_action_button.cljs new file mode 100644 index 0000000000..8ff80c068f --- /dev/null +++ b/src/status_im/components/native_action_button.cljs @@ -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))) diff --git a/src/status_im/components/styles.cljs b/src/status_im/components/styles.cljs index c5a404bf45..861a304d78 100644 --- a/src/status_im/components/styles.cljs +++ b/src/status_im/components/styles.cljs @@ -13,6 +13,7 @@ (def color-steel "#838b91") (def color-white "white") (def color-light-blue "#628fe3") +(def color-light-blue-transparent "#628fe333") (def color-light-blue2 "#eff3fc") (def color-light-gray "#EEF2F5") (def color-red "red") diff --git a/src/status_im/components/text_field/view.cljs b/src/status_im/components/text_field/view.cljs index b1ba7ae6a7..c051d8a934 100644 --- a/src/status_im/components/text_field/view.cljs +++ b/src/status_im/components/text_field/view.cljs @@ -92,8 +92,7 @@ (log/debug "Input blurred") (r/set-state component {:has-focus false :float-label? (if (s/blank? value) false true)}) - (when (s/blank? value) - (field-animation animation)) + (field-animation animation) (when onBlur (onBlur))) (defn get-width [event] @@ -113,7 +112,8 @@ max-length]} (r/state component) {: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 - 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)) line-color (if error error-color line-color) focus-line-color (if error error-color focus-line-color) @@ -127,6 +127,8 @@ :style (merge st/text-input input-style) :placeholder (or placeholder "") :editable editable + :multiline multiline + :number-of-lines number-of-lines :secure-text-entry secure-text-entry :auto-capitalize auto-capitalize :on-focus #(on-input-focus {:component component diff --git a/src/status_im/components/toolbar_new/view.cljs b/src/status_im/components/toolbar_new/view.cljs index 5b98f13599..7e63af229c 100644 --- a/src/status_im/components/toolbar_new/view.cljs +++ b/src/status_im/components/toolbar_new/view.cljs @@ -23,6 +23,7 @@ custom-action :custom-action background-color :background-color custom-content :custom-content + hide-border? :hide-border? style :style}] (let [style (merge (st/toolbar-wrapper background-color) style)] [view {:style style} @@ -63,8 +64,9 @@ {:key (str "action-" action-image)})) custom-action)]] [sync-state-gradient-view] - [view st/toolbar-border-container - [view st/toolbar-border]]])) + (when-not hide-border? + [view st/toolbar-border-container + [view st/toolbar-border]])])) (def search-text-input (r/atom nil)) diff --git a/src/status_im/contacts/screen.cljs b/src/status_im/contacts/screen.cljs index fde74ed231..3b5e94de03 100644 --- a/src/status_im/contacts/screen.cljs +++ b/src/status_im/contacts/screen.cljs @@ -3,17 +3,18 @@ (:require [reagent.core :as r] [clojure.string :as str] [re-frame.core :refer [subscribe dispatch dispatch-sync]] + [status-im.components.common.common :refer [separator]] [status-im.components.react :refer [view text image icon touchable-highlight - linear-gradient scroll-view list-view list-item] :as react] - [status-im.components.action-button :refer [action-button - action-button-item]] + [status-im.components.common.common :refer [top-shaddow bottom-shaddow]] + [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.toolbar-new.view :refer [toolbar]] [status-im.components.toolbar-new.actions :as act] @@ -73,22 +74,14 @@ (when extended? [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]}] - (let [shadows? (get-in platform-specific [:contacts :group-block-shadows?]) + (let [shadows? (get-in platform-specific [:group-block-shadows?]) subtitle (:name group)] [view st/contact-group (when subtitle [subtitle-view subtitle contacts-count group edit?]) (when (and subtitle shadows?) - [group-top-view]) + [top-shaddow]) [view st/contacts-list [view st/contact-list-spacing] (doall @@ -108,13 +101,11 @@ (:group-id group)]) :text (label :t/remove-from-group)}])}] (when-not (= contact (last contacts)) - [view st/contact-item-separator-wrapper - [view st/contact-item-separator]])]) + [separator st/contact-item-separator])]) contacts))] (when (< contacts-limit contacts-count) [view - [view st/contact-item-separator-wrapper - [view st/contact-item-separator]] + [separator st/contact-item-separator] [view st/show-all [touchable-highlight {:on-press #(do (when edit? @@ -126,7 +117,7 @@ :font (get-in platform-specific [:component-styles :contacts :show-all-text-font])} (str (- contacts-count contacts-limit) " " (label :t/more))]]]]]) (when shadows? - [group-bottom-view])])) + [bottom-shaddow])])) (defview contact-group-view [{:keys [group] :as params}] [contacts [:all-added-group-contacts-with-limit (:group-id group) contacts-limit] @@ -135,12 +126,12 @@ :contacts-count contacts-count})]) (defn contacts-action-button [] - [action-button {:button-color color-blue - :offset-x 16 - :offset-y 22 - :hide-shadow true - :spacing 13} - [action-button-item + [native-action-button {:button-color color-blue + :offset-x 16 + :offset-y 22 + :hide-shadow true + :spacing 13} + [native-action-button-item {:title (label :t/new-contact) :buttonColor :#9b59b6 :onPress #(dispatch [:navigate-to :new-contact])} diff --git a/src/status_im/contacts/styles.cljs b/src/status_im/contacts/styles.cljs index 3d88cf27c4..6c07c0af4c 100644 --- a/src/status_im/contacts/styles.cljs +++ b/src/status_im/contacts/styles.cljs @@ -52,25 +52,6 @@ {:margin-left 8 :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 (merge (get-in p/platform-specific [:component-styles :contacts :show-all]) {:flexDirection :row @@ -80,11 +61,8 @@ (def 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 - (get-in p/platform-specific [:component-styles :contacts :separator])) + {:margin-left 72}) (def contact-container (merge (get-in p/platform-specific [:component-styles :contacts :contact-container]) @@ -155,13 +133,6 @@ :alignItems :center :justifyContent :center}) -(def search-btn - {:width 24 - :height 56 - :margin-right 24 - :alignItems :center - :justifyContent :center}) - ; New contact (def contact-form-container diff --git a/src/status_im/contacts/views/contact_list.cljs b/src/status_im/contacts/views/contact_list.cljs index aed9ece9c3..61d5424f83 100644 --- a/src/status_im/contacts/views/contact_list.cljs +++ b/src/status_im/contacts/views/contact_list.cljs @@ -1,6 +1,7 @@ (ns status-im.contacts.views.contact-list (:require-macros [status-im.utils.views :refer [defview]]) (:require [re-frame.core :refer [subscribe dispatch dispatch-sync]] + [status-im.components.common.common :refer [separator]] [status-im.components.react :refer [view text image icon @@ -114,8 +115,7 @@ (defn render-separator [_ row-id _] (list-item ^{:key row-id} - [view st/contact-item-separator-wrapper - [view st/contact-item-separator]])) + [separator st/contact-item-separator])) (defview contacts-list-view [group modal click-handler action edit?] [contacts [:all-added-group-contacts-filtered (:group-id group)] diff --git a/src/status_im/ios/core.cljs b/src/status_im/ios/core.cljs index 2d2c5ee656..d6544f1f89 100644 --- a/src/status_im/ios/core.cljs +++ b/src/status_im/ios/core.cljs @@ -37,6 +37,7 @@ [status-im.participants.views.remove :refer [remove-participants]] [status-im.group-settings.screen :refer [group-settings]] [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.data-store.core [taoensso.timbre :as log] @@ -114,11 +115,13 @@ :qr-scanner qr-scanner :chat chat :profile profile + :my-profile my-profile + :edit-my-profile edit-my-profile :profile-photo-capture profile-photo-capture :accounts accounts :login login - :recover recover - :my-profile my-profile)] + :recover recover)] + [view {:flex 1} [component] diff --git a/src/status_im/ios/platform.cljs b/src/status_im/ios/platform.cljs index 89f94dfa66..d3b43370a2 100644 --- a/src/status_im/ios/platform.cljs +++ b/src/status_im/ios/platform.cljs @@ -77,10 +77,6 @@ :subtitle-count {:color styles/color-gray4 :font-size 16 :letter-spacing -0.2} - :separator {:margin-left 72 - :height 1 - :background-color styles/color-gray5 - :opacity 0.5} :info-container {:margin-left 16} :contact-inner-container {:height 63} :icon-check {:border-radius 50 @@ -104,6 +100,29 @@ :line-height 20 :letter-spacing -0.2 :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} :members-text {:letter-spacing -0.2 :font-size 16} @@ -144,6 +163,15 @@ :font-size 17 :line-height 20 :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} :input-label {:left 0} :input-error-text {:margin-left 0} @@ -159,7 +187,8 @@ :toolbar-last-activity {:color styles/text2-color :background-color :transparent :top 0 - :font-size 14}}) + :font-size 14} + :text-field-focus-line-height 1}) (def fonts {:light {:font-family "SFUIText-Light"} @@ -196,10 +225,10 @@ :render-separator? true} :uppercase? false :contacts {:action-button? false - :new-contact-in-toolbar? true - :group-block-shadows? false} + :new-contact-in-toolbar? true} + :group-block-shadows? false :discover {:uppercase-subtitles? true} :public-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}}) + diff --git a/src/status_im/new_group/styles.cljs b/src/status_im/new_group/styles.cljs index 2a46c058b3..ede18b385a 100644 --- a/src/status_im/new_group/styles.cljs +++ b/src/status_im/new_group/styles.cljs @@ -62,7 +62,7 @@ (get-in platform-specific [:public-group-chat-hash-style]))) (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 {:padding-top 0 diff --git a/src/status_im/new_group/views/chat_group_settings.cljs b/src/status_im/new_group/views/chat_group_settings.cljs index f89a27032d..f801fd1a2f 100644 --- a/src/status_im/new_group/views/chat_group_settings.cljs +++ b/src/status_im/new_group/views/chat_group_settings.cljs @@ -68,7 +68,7 @@ [view st/group-container [view {:flex 1} [group-toolbar type true] - [scroll-view {:keyboardShouldPersistTaps true} + [scroll-view [group-name-view] [chat-group-members] [view st/separator] diff --git a/src/status_im/new_group/views/contact_toggle_list.cljs b/src/status_im/new_group/views/contact_toggle_list.cljs index 25178f7d6e..5e549fb404 100644 --- a/src/status_im/new_group/views/contact_toggle_list.cljs +++ b/src/status_im/new_group/views/contact_toggle_list.cljs @@ -12,7 +12,7 @@ [status-im.utils.listview :refer [to-datasource]] [status-im.new-group.views.toggle-contact :refer [group-toggle-contact 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.contacts.styles :as cst] [status-im.i18n :refer [label]] @@ -41,7 +41,7 @@ (defn render-separator [_ row-id _] (list-item ^{:key row-id} - [separator])) + [separator cst/contact-item-separator])) (defn render-spacing [] #(list-item [view cst/contact-list-spacing])) diff --git a/src/status_im/new_group/views/group.cljs b/src/status_im/new_group/views/group.cljs index 2a2dc96fd4..b8a8f8cd80 100644 --- a/src/status_im/new_group/views/group.cljs +++ b/src/status_im/new_group/views/group.cljs @@ -2,6 +2,7 @@ (:require-macros [status-im.utils.views :refer [defview]]) (:require [re-frame.core :refer [dispatch]] [status-im.contacts.styles :as cst] + [status-im.components.common.common :as cmn] [status-im.components.react :refer [view text icon @@ -15,8 +16,7 @@ [status-im.i18n :refer [label]])) (defn separator [] - [view cst/contact-item-separator-wrapper - [view cst/contact-item-separator]]) + [cmn/separator cst/contact-item-separator]) (defview group-name-input [] [new-group-name [:get :new-chat-name]] @@ -99,8 +99,7 @@ (defn more-btn [contacts-limit contacts-count on-press] [view - [view cst/contact-item-separator-wrapper - [view cst/contact-item-separator]] + [separator] [view cst/show-all [touchable-highlight {:on-press on-press} [view diff --git a/src/status_im/new_group/views/reorder_groups.cljs b/src/status_im/new_group/views/reorder_groups.cljs index 803fce4683..28fa96cd43 100644 --- a/src/status_im/new_group/views/reorder_groups.cljs +++ b/src/status_im/new_group/views/reorder_groups.cljs @@ -4,17 +4,16 @@ [status-im.components.react :refer [view text icon - linear-gradient touchable-highlight list-item]] [status-im.components.confirm-button :refer [confirm-button]] [status-im.components.status-bar :refer [status-bar]] [status-im.components.toolbar-new.view :refer [toolbar]] [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.platform :refer [android?]] [status-im.new-group.styles :as st] - [status-im.contacts.styles :as cst] [status-im.i18n :refer [label label-pluralize]] [status-im.utils.platform :refer [platform-specific]] [reagent.core :as r])) @@ -35,14 +34,6 @@ [view st/order-item-icon [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?] (fn [_ row-id _] (list-item @@ -57,7 +48,7 @@ (defview reorder-groups [] [groups [:get :contact-groups] 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)] [view st/reorder-groups-container [status-bar] diff --git a/src/status_im/profile/edit/screen.cljs b/src/status_im/profile/edit/screen.cljs new file mode 100644 index 0000000000..c5aa2a2f13 --- /dev/null +++ b/src/status_im/profile/edit/screen.cljs @@ -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]))])])) diff --git a/src/status_im/profile/handlers.cljs b/src/status_im/profile/handlers.cljs index 3b7b2b9a51..0d248257b7 100644 --- a/src/status_im/profile/handlers.cljs +++ b/src/status_im/profile/handlers.cljs @@ -1,5 +1,5 @@ (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.components.react :refer [show-image-picker]] [status-im.utils.image-processing :refer [img->base64]] @@ -44,3 +44,23 @@ (fn [db _] (dispatch [:navigate-to :chat console-chat-id]) (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)))) diff --git a/src/status_im/profile/screen.cljs b/src/status_im/profile/screen.cljs index 7e3ffb68b5..dec7b8a251 100644 --- a/src/status_im/profile/screen.cljs +++ b/src/status_im/profile/screen.cljs @@ -1,241 +1,211 @@ (ns status-im.profile.screen (: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] - [cljs.spec :as s] [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 text text-input image icon - modal scroll-view - touchable-highlight - touchable-opacity - touchable-without-feedback - show-image-picker - dismiss-keyboard!]] - [status-im.components.icons.custom-icons :refer [oct-icon]] + touchable-highlight]] [status-im.components.chat-icon.screen :refer [my-profile-icon]] [status-im.components.status-bar :refer [status-bar]] - [status-im.components.text-field.view :refer [text-field]] - [status-im.components.selectable-field.view :refer [selectable-field]] - [status-im.components.status-view.view :refer [status-view]] - [status-im.components.list-selection :refer [share]] - [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.components.toolbar-new.view :refer [toolbar]] + [status-im.components.toolbar-new.actions :as act] + [status-im.components.list-selection :refer [share-options]] + [status-im.utils.platform :refer [platform-specific android?]] [status-im.profile.handlers :refer [message-user]] - [status-im.profile.validations :as v] [status-im.profile.styles :as st] - [status-im.utils.random :refer [id]] - [status-im.utils.utils :refer [clean-text]] - [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]])) + [status-im.i18n :refer [label]] + [status-im.utils.datetime :as time])) -(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 [_] - (let [component (r/current-component) - just-opened? (r/atom true) - 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 +(defn my-profile-toolbar [] + [toolbar {:actions [(act/opts [{:value #(dispatch [:open-edit-my-profile]) + :text (label :t/edit)}])]}]) - (if edit? - [touchable-highlight {:on-press (fn [] - (let [list-selection-fn (:list-selection-fn platform-specific)] - (dispatch [:open-image-source-selector list-selection-fn])))} - [view - [my-profile-icon {:account {:photo-path photo-path - :name name} - :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}])])}))) +(defn online-text [last-online] + (let [last-online-date (time/to-date last-online) + now-date (time/now)] + (if (and (pos? last-online) + (<= last-online-date now-date)) + (time/time-ago last-online-date) + (label :t/active-unknown)))) -(defview profile [] - [{whisper-identity :whisper-identity - address :address - username :name - photo-path :photo-path - phone :phone - status :status - :as contact} [:contact]] - [scroll-view {:style st/profile} - [status-bar] - [view - [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]]]] +(defn profile-bage [{:keys [name last-online] :as contact}] + [view st/profile-bage + [my-profile-icon {:account contact + :edit? false}] + [view st/profile-name-container + [text {:style st/profile-name-text} + name]] + (when-not (nil? last-online) + [view st/profile-status-container + [text {:style st/profile-status-text} + (online-text last-online)]])]) - [status-image-view {:account contact - :photo-path photo-path - :edit? false}] +(defn add-to-contacts [pending? chat-id] + [view + (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 - :bounces false}) +(defn profile-actions [whisper-identity chat-id] + [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 - [view st/btns-container - [touchable-highlight {:onPress #(message-user whisper-identity)} - [view st/message-btn - [text {:style st/message-btn-text} (label :t/message)]]] - ;; TODO not implemented - #_[touchable-highlight {:onPress #(.log js/console "Not yet implemented")} - [view st/more-btn - [icon :more_vertical_blue st/more-btn-image]]]]] +(defn profile-info-item [label value options text-mode] + [view st/profile-setting-item + [view st/profile-setting-text-container + [text {:style st/profile-setting-title} + label] + [view st/profile-setting-spacing] + [text {:style st/profile-setting-text + :numberOfLines 1 + :ellipsizeMode text-mode} + value]] + (when options + [context-menu + [icon :options_gray] + options])]) - [view st/profile-property-with-top-spacing - [selectable-field {:label (label :t/phone-number) - :editable? false - :value (if (and phone (not (str/blank? phone))) - (format-phone-number phone) - (label :t/not-specified))}] - [view st/underline-container]] +(defn show-qr [contact qr-source] + #(dispatch [:navigate-to-modal :qr-code-view {:contact contact + :qr-source qr-source}])) - (when address - [view st/profile-property - [view st/profile-property-row - [view st/profile-property-field - [selectable-field {:label (label :t/address) - :editable? false - :value address - :on-press #(share address (label :t/address))}]] - [show-qr-button {:handler #(dispatch [:navigate-to-modal :qr-code-view {:contact contact - :qr-source :whisper-identity}])}]] - [view st/underline-container]]) +(defn profile-info-address-item [{:keys [address] :as contact}] + [profile-info-item + (label :t/address) + address + (into [] + (concat [{:value (show-qr contact :address) + :text (label :t/show-qr)}] + (share-options address))) + :middle]) - [view st/profile-property - [view st/profile-property-row - [view st/profile-property-field - [selectable-field {:label (label :t/public-key) - :editable? false - :value whisper-identity - :on-press #(share whisper-identity (label :t/public-key))}]] - [show-qr-button {:handler #(dispatch [:navigate-to-modal :qr-code-view {:contact contact - :qr-source :public-key}])}]]] +(defn profile-info-public-key-item [public-key contact] + [profile-info-item + (label :t/public-key) + public-key + (into [] + (concat [{:value (show-qr contact :public-key) + :text (label :t/show-qr)}] + (share-options 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 [] - [edit? [:get-in [:profile-edit :edit?]] - qr [:get-in [:profile-edit :qr-code]] - current-account [:get-current-account] - 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} + [current-account [:get-current-account]] + (let [shadows? (get-in platform-specific [:group-block-shadows?])] + [view st/profile [status-bar] - [toolbar {:account account - :edit? edit?}] + [my-profile-toolbar] + [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 - :edit? edit?}] - - [scroll-view (merge st/my-profile-properties-container {:bounces false}) - [view st/profile-property - [selectable-field {:label (label :t/phone-number) - :editable? edit? - :value (if (and phone (not (str/blank? phone))) - (format-phone-number phone) - (label :t/not-specified)) - :on-press #(dispatch [:phone-number-change-requested])}] - [view st/underline-container]] - - [view st/profile-property - [view st/profile-property-row - [view st/profile-property-field - [selectable-field {:label (label :t/address) - :editable? edit? - :value address - :on-press #(share address (label :t/address))}]] - [show-qr-button {:handler #(dispatch [:navigate-to-modal :qr-code-view {:contact account - :qr-source :address}])}]] - [view st/underline-container]] - - [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]]])) +(defview profile [] + [{:keys [pending? + whisper-identity] + :as contact} [:contact] + chat-id [:get :current-chat-id]] + (let [shadows? (get-in platform-specific [:group-block-shadows?])] + [view st/profile + [status-bar] + [toolbar] + [scroll-view + [view st/profile-form + [profile-bage contact] + [add-to-contacts pending? chat-id]] + (when shadows? + [bottom-shaddow]) + [view st/profile-info-container + (when shadows? + [top-shaddow]) + [profile-actions whisper-identity chat-id] + [view st/form-separator] + [profile-info contact] + (when shadows? + [bottom-shaddow])]]])) \ No newline at end of file diff --git a/src/status_im/profile/styles.cljs b/src/status_im/profile/styles.cljs index befa265d27..14a5754e95 100644 --- a/src/status_im/profile/styles.cljs +++ b/src/status_im/profile/styles.cljs @@ -1,168 +1,182 @@ (ns status-im.profile.styles + (:require-macros [status-im.utils.styles :refer [defstyle]]) (:require [status-im.components.styles :refer [color-white - color-gray - color-black - color-blue - color-blue-transparent - text1-color - text1-disabled-color - text2-color - color-red - separator-color]] + color-gray4 + color-gray5 + color-light-gray + color-light-blue + color-light-blue-transparent + text1-color]] [status-im.utils.platform :as p])) +(defn ps-profile [item] + (get-in p/platform-specific [:component-styles :profile item])) + (def profile {:flex 1 - :background-color color-white + :background-color color-light-gray :flex-direction :column}) -(def back-btn-touchable - {:position :absolute}) +(def profile-form + {:background-color color-white + :padding-bottom 16}) -(def back-btn-container - {:width 46 - :height 56 - :align-items :center - :justify-content :center}) +(def my-profile-form + {:background-color color-white + :padding-bottom 24}) -(def back-btn-icon - {:width 8 - :height 14}) +(def edit-my-profile-form + {:background-color color-white + :flex 1}) -(def actions-btn-touchable - {:position :absolute - :right 0}) +(defstyle profile-info-container + {:background-color color-white + :ios {:margin-top 16} + :android {:margin-top 12}}) -(def actions-btn-container - {:width 56 - :height 56 - :align-items :center - :justify-content :center}) +(defstyle profile-actions-container + {:android {:padding-top 8 + :padding-bottom 8}}) -(def edit-btn-icon - {:width 4 - :height 16}) +(def profile-bage + (merge (ps-profile :profile-bage) + {:align-items :center})) -(defn ok-btn-icon [enabled?] - {:font-size 22 - :color (if enabled? color-black color-gray)}) +(def edit-profile-bage + {:flex-direction :row + :align-items :center + :padding-left 24 + :padding-top 25}) -(def user-photo-container - {:margin-top 22}) +(def profile-name-container + {:margin-top 12}) -(def username-wrapper - {:width 300 - :margin-top (if p/ios? -18 -22) - :margin-bottom -16}) +(defstyle edit-profile-name-container + {:flex 1 + :ios {:padding-left 32 + :padding-top 11} + :android {:padding-top 16 + :padding-left 16}}) -(defn username-input [edit? valid?] - {:font-size 18 - :text-align :center - :color (if edit? - (if valid? text1-color color-red) - text1-disabled-color)}) +(def edit-name-title + (merge (ps-profile :edit-name-title) + {:color color-gray4})) -(def status-block - {:flex-direction "column" - :align-items "center" - :justifyContent "center" - :margin-left 55 - :margin-right 55}) +(def edit-status-title + edit-name-title) -(defn status-view [height] - {:align-self "stretch" - :font-size 14 - :min-height height - :text-align "center" - :color text2-color}) +(def profile-name-text + (ps-profile :profile-name-text)) -(defn status-input [height] - (merge (status-view height) - {:margin-left (if p/ios? 21 16) - :margin-right 16 - :margin-top (if p/ios? 6 1)})) +(def profile-status-container + {:margin-top 4}) -(defn status-text [height] - (merge (status-view (- height (if p/ios? 5 10))) - {:margin-left 18 - :margin-right 18 - :margin-top 11 - :margin-bottom 0})) +(def profile-status-text + (merge (ps-profile :profile-status-text) + {:color color-gray4})) -(def btns-container - {:margin-top 0 - :flex-direction :row}) +(def profile-setting-item + (merge (ps-profile :profile-setting-item) + {:flex-direction :row + :align-items :center})) -(def message-btn - {:height 40 - :justify-content :center - :background-color color-blue - :padding-left 25 - :padding-right 25 - :border-radius 20}) +(def profile-setting-text-container + {:flex 1 + :padding-right 20}) -(def message-btn-text - {:margin-top -2.5 - :font-size 14 - :color color-white}) +(def profile-setting-title + (merge (ps-profile :profile-setting-title) + {:color color-gray4})) -(def more-btn - {:margin-left 10 - :width 40 - :height 40 - :align-items :center - :justify-content :center - :background-color color-blue-transparent - :padding 8 - :border-radius 20}) +(def profile-setting-text + (ps-profile :profile-setting-text)) -(def more-btn-image - {:width 4 - :height 16}) +(def profile-setting-spacing + (ps-profile :profile-setting-spacing)) -(def profile-properties-container - {:align-items :stretch - :flex-firection :column - :margin-top 16}) - -(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" +(def add-to-contacts + {:margin-top 24 + :margin-left 16 + :margin-right 16 + :background-color color-light-blue :border-radius 4 - :align-items :center - :padding-top 15 - :elevation 4}) + :height 52 + :align-items :center + :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}) diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs index d870ead6b0..8e5b1e8c20 100644 --- a/src/status_im/translations/en.cljs +++ b/src/status_im/translations/en.cljs @@ -68,6 +68,7 @@ ;profile :profile "Profile" + :edit-profile "Edit profile" :report-user "REPORT USER" :message "Message" :username "Username" @@ -77,6 +78,10 @@ :email "Email" :profile-no-status "No status" :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-email "Incorrect e-mail" diff --git a/src/status_im/utils/datetime.cljs b/src/status_im/utils/datetime.cljs index 5e96371d37..a7adffdbbc 100644 --- a/src/status_im/utils/datetime.cljs +++ b/src/status_im/utils/datetime.cljs @@ -1,5 +1,5 @@ (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.format :refer [formatters formatter @@ -8,6 +8,9 @@ [goog.string :as gstring] goog.string.format)) +(defn now [] + (t/now)) + (def hour (* 1000 60 60)) (def day (* hour 24)) (def week (* 7 day))