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
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 792 B |
Before Width: | Height: | Size: 647 B After Width: | Height: | Size: 788 B |
After Width: | Height: | Size: 704 B |
After Width: | Height: | Size: 356 B |
After Width: | Height: | Size: 474 B |
Before Width: | Height: | Size: 501 B After Width: | Height: | Size: 490 B |
After Width: | Height: | Size: 388 B |
After Width: | Height: | Size: 554 B |
After Width: | Height: | Size: 810 B |
Before Width: | Height: | Size: 930 B After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 691 B |
After Width: | Height: | Size: 721 B |
After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1007 B |
After Width: | Height: | Size: 916 B |
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.3 KiB |
|
@ -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"
|
||||
}
|
||||
}
|
BIN
ios/StatusIm/Images.xcassets/icon_arrow_right_blue.imageset/icon_arrow_right_blue.png
vendored
Normal file
After Width: | Height: | Size: 554 B |
|
@ -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"
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 810 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -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"
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 691 B |
|
@ -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]
|
||||
|
|
|
@ -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}})
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)))
|
|
@ -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])
|
|
@ -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})
|
||||
|
|
@ -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]))
|
|
@ -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}))
|
||||
|
||||
|
|
|
@ -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)]])
|
|
@ -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]))
|
|
@ -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
|
||||
|
|
|
@ -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)))
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
||||
|
|
|
@ -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])}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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}})
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]))])]))
|
|
@ -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))))
|
||||
|
|
|
@ -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])]]]))
|
|
@ -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})
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|