mirror of
https://github.com/status-im/status-mobile.git
synced 2025-02-10 23:56:48 +00:00
Former-commit-id: 3ea4cff4b9b332d0b19d97724ac4df4842b51184
This commit is contained in:
parent
bddbfb9176
commit
b369e632a0
@ -14,8 +14,9 @@
|
|||||||
status-im.accounts.recover.handlers
|
status-im.accounts.recover.handlers
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[status-im.utils.datetime :as time]
|
[status-im.utils.datetime :as time]
|
||||||
[status-im.utils.handlers :as u]
|
[status-im.utils.handlers :as u :refer [get-hashtags]]
|
||||||
[status-im.accounts.statuses :as statuses]
|
[status-im.accounts.statuses :as statuses]
|
||||||
|
[status-im.utils.gfycat.core :refer [generate-gfy]]
|
||||||
[status-im.constants :refer [console-chat-id]]))
|
[status-im.constants :refer [console-chat-id]]))
|
||||||
|
|
||||||
|
|
||||||
@ -36,7 +37,7 @@
|
|||||||
{:keys [public private]} (protocol/new-keypair!)
|
{:keys [public private]} (protocol/new-keypair!)
|
||||||
account {:public-key public-key
|
account {:public-key public-key
|
||||||
:address address
|
:address address
|
||||||
:name address
|
:name (generate-gfy)
|
||||||
:status (rand-nth statuses/data)
|
:status (rand-nth statuses/data)
|
||||||
:signed-up? true
|
:signed-up? true
|
||||||
:updates-public-key public
|
:updates-public-key public
|
||||||
@ -74,6 +75,18 @@
|
|||||||
:status status
|
:status status
|
||||||
:profile-image photo-path}}}})))
|
:profile-image photo-path}}}})))
|
||||||
|
|
||||||
|
(register-handler
|
||||||
|
:check-status-change
|
||||||
|
(u/side-effect!
|
||||||
|
(fn [{:keys [current-account-id accounts]} [_ status]]
|
||||||
|
(let [{old-status :status :as account} (get accounts current-account-id)
|
||||||
|
status-updated? (and (not= status nil)
|
||||||
|
(not= status old-status))]
|
||||||
|
(when status-updated?
|
||||||
|
(let [hashtags (get-hashtags status)]
|
||||||
|
(when-not (empty? hashtags)
|
||||||
|
(dispatch [:broadcast-status status hashtags]))))))))
|
||||||
|
|
||||||
(register-handler
|
(register-handler
|
||||||
:account-update
|
:account-update
|
||||||
(-> (fn [{:keys [current-account-id accounts] :as db} [_ data]]
|
(-> (fn [{:keys [current-account-id accounts] :as db} [_ data]]
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
[taoensso.timbre :as log]
|
[taoensso.timbre :as log]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[status-im.utils.handlers :as u]
|
[status-im.utils.handlers :as u]
|
||||||
|
[status-im.utils.gfycat.core :refer [generate-gfy]]
|
||||||
[status-im.protocol.core :as protocol]))
|
[status-im.protocol.core :as protocol]))
|
||||||
|
|
||||||
(defn account-recovered [result]
|
(defn account-recovered [result]
|
||||||
@ -16,7 +17,7 @@
|
|||||||
{:keys [public private]} (protocol/new-keypair!)
|
{:keys [public private]} (protocol/new-keypair!)
|
||||||
account {:public-key public-key
|
account {:public-key public-key
|
||||||
:address address
|
:address address
|
||||||
:name address
|
:name (generate-gfy)
|
||||||
:photo-path (identicon public-key)
|
:photo-path (identicon public-key)
|
||||||
:updates-public-key public
|
:updates-public-key public
|
||||||
:updates-private-key private
|
:updates-private-key private
|
||||||
|
@ -14,7 +14,6 @@
|
|||||||
[status-im.components.text-field.view :refer [text-field]]
|
[status-im.components.text-field.view :refer [text-field]]
|
||||||
[status-im.components.drawer.styles :as st]
|
[status-im.components.drawer.styles :as st]
|
||||||
[status-im.profile.validations :as v]
|
[status-im.profile.validations :as v]
|
||||||
[status-im.profile.handlers :refer [update-profile]]
|
|
||||||
[status-im.resources :as res]
|
[status-im.resources :as res]
|
||||||
[status-im.i18n :refer [label]]
|
[status-im.i18n :refer [label]]
|
||||||
[status-im.components.react :refer [dismiss-keyboard!]]))
|
[status-im.components.react :refer [dismiss-keyboard!]]))
|
||||||
@ -43,8 +42,8 @@
|
|||||||
name]])
|
name]])
|
||||||
|
|
||||||
(defview drawer-menu []
|
(defview drawer-menu []
|
||||||
[{:keys [name address photo-path status] :as account} [:get-current-account]
|
[{:keys [name photo-path status]} [:get-current-account]
|
||||||
{new-name :name :as profile-edit-data} [:get :profile-edit]
|
{new-name :name new-status :status} [:get :profile-edit]
|
||||||
keyboard-height [:get :keyboard-height]]
|
keyboard-height [:get :keyboard-height]]
|
||||||
[view st/drawer-menu
|
[view st/drawer-menu
|
||||||
[touchable-without-feedback {:on-press #(dismiss-keyboard!)}
|
[touchable-without-feedback {:on-press #(dismiss-keyboard!)}
|
||||||
@ -60,10 +59,9 @@
|
|||||||
:editable true
|
:editable true
|
||||||
:input-style (st/name-input-text (s/valid? ::v/name (or new-name name)))
|
:input-style (st/name-input-text (s/valid? ::v/name (or new-name name)))
|
||||||
:wrapper-style st/name-input-wrapper
|
:wrapper-style st/name-input-wrapper
|
||||||
:value (if (not= name address)
|
:value name
|
||||||
name)
|
|
||||||
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])
|
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])
|
||||||
:on-end-editing #(update-profile account profile-edit-data)}]]
|
:on-end-editing #(dispatch [:account-update {:name new-name}])}]]
|
||||||
[view st/status-container
|
[view st/status-container
|
||||||
[text-input {:style st/status-input
|
[text-input {:style st/status-input
|
||||||
:editable true
|
:editable true
|
||||||
@ -73,7 +71,9 @@
|
|||||||
:accessibility-label :input
|
:accessibility-label :input
|
||||||
:placeholder (label :t/profile-no-status)
|
:placeholder (label :t/profile-no-status)
|
||||||
:on-change-text #(dispatch [:set-in [:profile-edit :status] %])
|
:on-change-text #(dispatch [:set-in [:profile-edit :status] %])
|
||||||
:on-blur #(update-profile account profile-edit-data)
|
:on-blur (fn[]
|
||||||
|
(dispatch [:check-status-change new-status])
|
||||||
|
(dispatch [:account-update {:status new-status}]))
|
||||||
:default-value status}]]
|
:default-value status}]]
|
||||||
[view st/menu-items-container
|
[view st/menu-items-container
|
||||||
[menu-item {:name (label :t/profile)
|
[menu-item {:name (label :t/profile)
|
||||||
|
36
src/status_im/components/selectable_field/styles.cljs
Normal file
36
src/status_im/components/selectable_field/styles.cljs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
(ns status-im.components.selectable-field.styles
|
||||||
|
(:require [status-im.utils.platform :refer [platform-specific]]))
|
||||||
|
|
||||||
|
|
||||||
|
(def selectable-field-container
|
||||||
|
{})
|
||||||
|
|
||||||
|
(def label-container
|
||||||
|
{:margin-bottom 13})
|
||||||
|
|
||||||
|
(def label
|
||||||
|
{:color "#838c93"
|
||||||
|
:background-color :transparent
|
||||||
|
:font-size 14})
|
||||||
|
|
||||||
|
(def text-container
|
||||||
|
{:padding 0
|
||||||
|
:margin-bottom 18
|
||||||
|
:margin 0})
|
||||||
|
|
||||||
|
(def text
|
||||||
|
{:font-size 16
|
||||||
|
:color "#555555"
|
||||||
|
:margin-right 16
|
||||||
|
:text-align-vertical :top})
|
||||||
|
|
||||||
|
(defn sized-text
|
||||||
|
[height]
|
||||||
|
(merge text {:height height
|
||||||
|
:margin-bottom 0
|
||||||
|
:margin-top 0
|
||||||
|
:padding-top 0
|
||||||
|
:padding-left 0
|
||||||
|
:margin-left 0
|
||||||
|
:padding-bottom 0}))
|
||||||
|
|
61
src/status_im/components/selectable_field/view.cljs
Normal file
61
src/status_im/components/selectable_field/view.cljs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
(ns status-im.components.selectable-field.view
|
||||||
|
(:require [status-im.components.react :refer [view
|
||||||
|
text-input
|
||||||
|
text]]
|
||||||
|
[reagent.core :as r]
|
||||||
|
[status-im.components.selectable-field.styles :as st]
|
||||||
|
[status-im.i18n :refer [label]]
|
||||||
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
|
(defn- on-press
|
||||||
|
[event component]
|
||||||
|
(log/debug "Pressed " event component)
|
||||||
|
(r/set-state component {:focused? true}))
|
||||||
|
|
||||||
|
(defn- on-selection-change
|
||||||
|
[event component]
|
||||||
|
(let [selection (.-selection (.-nativeEvent event))
|
||||||
|
start (.-start selection)
|
||||||
|
end (.-end selection)]
|
||||||
|
(log/debug "Selection changed: " start end)))
|
||||||
|
|
||||||
|
(defn- on-layout-text
|
||||||
|
[event component]
|
||||||
|
(let [height (.-height (.-layout (.-nativeEvent event)))
|
||||||
|
{:keys [full-height]} (r/state component)]
|
||||||
|
(when (and (pos? height) (not full-height))
|
||||||
|
(r/set-state component {:full-height height
|
||||||
|
:measured? true}))))
|
||||||
|
|
||||||
|
(defn- reagent-render
|
||||||
|
[{:keys [label value props] :as data}]
|
||||||
|
(let [component (r/current-component)
|
||||||
|
{:keys [focused? measured? full-height]} (r/state component)]
|
||||||
|
(log/debug "reagent-render: " data focused? measured? full-height)
|
||||||
|
[view st/selectable-field-container
|
||||||
|
[view st/label-container
|
||||||
|
[text {:style st/label
|
||||||
|
:font :medium} (or label "")]]
|
||||||
|
[view st/text-container
|
||||||
|
(if focused?
|
||||||
|
[text-input {:style (st/sized-text full-height)
|
||||||
|
:multiline true
|
||||||
|
:selectTextOnFocus true
|
||||||
|
:editable true
|
||||||
|
:auto-focus true
|
||||||
|
:on-selection-change #(on-selection-change % component)
|
||||||
|
:on-focus #(log/debug "Focused" %)
|
||||||
|
:on-blur #(r/set-state component {:focused? false})
|
||||||
|
:value value}]
|
||||||
|
[text (merge {:style st/text
|
||||||
|
:on-press #(on-press % component)
|
||||||
|
:onLayout #(on-layout-text % component)
|
||||||
|
:font :default
|
||||||
|
:ellipsizeMode :middle
|
||||||
|
:number-of-lines (if measured? 1 0)} (or props {})) (or value "")])]]))
|
||||||
|
|
||||||
|
(defn selectable-field [{:keys [label value props]}]
|
||||||
|
(let [component-data {:display-name "selectable-field"
|
||||||
|
:reagent-render reagent-render}]
|
||||||
|
(reagent.core/create-class component-data)))
|
||||||
|
|
@ -24,6 +24,7 @@
|
|||||||
[cljs.spec :as s]
|
[cljs.spec :as s]
|
||||||
[status-im.contacts.validations :as v]
|
[status-im.contacts.validations :as v]
|
||||||
[status-im.contacts.styles :as st]
|
[status-im.contacts.styles :as st]
|
||||||
|
[status-im.utils.gfycat.core :refer [generate-gfy]]
|
||||||
[status-im.utils.hex :refer [normalize-hex]]))
|
[status-im.utils.hex :refer [normalize-hex]]))
|
||||||
|
|
||||||
|
|
||||||
@ -38,13 +39,13 @@
|
|||||||
(fn [{:keys [contacts]}]
|
(fn [{:keys [contacts]}]
|
||||||
(if (> (count contacts) 0)
|
(if (> (count contacts) 0)
|
||||||
(let [{:keys [whisper-identity]} (first contacts)
|
(let [{:keys [whisper-identity]} (first contacts)
|
||||||
contact {:name ""
|
contact {:name (generate-gfy)
|
||||||
:address id
|
:address id
|
||||||
:photo-path (identicon whisper-identity)
|
:photo-path (identicon whisper-identity)
|
||||||
:whisper-identity whisper-identity}]
|
:whisper-identity whisper-identity}]
|
||||||
(dispatch [:add-new-contact contact]))
|
(dispatch [:add-new-contact contact]))
|
||||||
(dispatch [:set :new-contact-address-error (label :t/unknown-address)]))))
|
(dispatch [:set :new-contact-address-error (label :t/unknown-address)]))))
|
||||||
(dispatch [:add-new-contact {:name ""
|
(dispatch [:add-new-contact {:name (generate-gfy)
|
||||||
:photo-path (identicon id)
|
:photo-path (identicon id)
|
||||||
:whisper-identity id}])))
|
:whisper-identity id}])))
|
||||||
|
|
||||||
|
@ -78,12 +78,6 @@
|
|||||||
|
|
||||||
(register-handler :show-profile show-profile)
|
(register-handler :show-profile show-profile)
|
||||||
|
|
||||||
(defn show-profile-photo-capture
|
|
||||||
[db _]
|
|
||||||
(push-view db :profile-photo-capture))
|
|
||||||
|
|
||||||
(register-handler :show-profile-photo-capture show-profile-photo-capture)
|
|
||||||
|
|
||||||
(defn navigate-to-clean
|
(defn navigate-to-clean
|
||||||
[db [_ view-id]]
|
[db [_ view-id]]
|
||||||
(-> db
|
(-> db
|
||||||
|
@ -5,45 +5,22 @@
|
|||||||
[status-im.utils.image-processing :refer [img->base64]]
|
[status-im.utils.image-processing :refer [img->base64]]
|
||||||
[status-im.i18n :refer [label]]
|
[status-im.i18n :refer [label]]
|
||||||
[status-im.utils.handlers :as u :refer [get-hashtags]]
|
[status-im.utils.handlers :as u :refer [get-hashtags]]
|
||||||
[status-im.utils.platform :refer [ios?]]
|
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[status-im.profile.validations :as v]
|
[status-im.profile.validations :as v]
|
||||||
[cljs.spec :as s]))
|
[cljs.spec :as s]
|
||||||
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
(defn message-user [identity]
|
(defn message-user [identity]
|
||||||
(when identity
|
(when identity
|
||||||
(dispatch [:navigate-to :chat identity])))
|
(dispatch [:navigate-to :chat identity])))
|
||||||
|
|
||||||
(defn update-profile [{name :name
|
|
||||||
email :email
|
|
||||||
photo-path :photo-path
|
|
||||||
status :status}
|
|
||||||
{new-name :name
|
|
||||||
new-email :email
|
|
||||||
new-status :status
|
|
||||||
new-photo-path :photo-path}]
|
|
||||||
(let [new-name (if (or (not new-name)
|
|
||||||
(not (s/valid? ::v/name new-name)))
|
|
||||||
name
|
|
||||||
new-name)
|
|
||||||
status-updated? (and (not= new-status nil)
|
|
||||||
(not= status new-status))]
|
|
||||||
(when status-updated?
|
|
||||||
(let [hashtags (get-hashtags new-status)]
|
|
||||||
(when-not (empty? hashtags)
|
|
||||||
(dispatch [:broadcast-status new-status hashtags]))))
|
|
||||||
(dispatch [:account-update {:name new-name
|
|
||||||
:email (or new-email email)
|
|
||||||
:status (or new-status status)
|
|
||||||
:photo-path (or new-photo-path photo-path)}])))
|
|
||||||
|
|
||||||
(register-handler :open-image-picker
|
(register-handler :open-image-picker
|
||||||
(u/side-effect!
|
(u/side-effect!
|
||||||
(fn [_ _]
|
(fn [_ _]
|
||||||
(show-image-picker
|
(show-image-picker
|
||||||
(fn [image]
|
(fn [image]
|
||||||
(let [path (get (js->clj image) "path")
|
(let [path (get (js->clj image) "path")
|
||||||
path (if ios? path (subs path 12))
|
_ (log/debug path)
|
||||||
on-success (fn [base64]
|
on-success (fn [base64]
|
||||||
(dispatch [:set-in [:profile-edit :photo-path] (str "data:image/jpeg;base64," base64)]))
|
(dispatch [:set-in [:profile-edit :photo-path] (str "data:image/jpeg;base64," base64)]))
|
||||||
on-error (fn [type error]
|
on-error (fn [type error]
|
||||||
@ -57,7 +34,7 @@
|
|||||||
:options [(label :t/image-source-make-photo) (label :t/image-source-gallery)]
|
:options [(label :t/image-source-make-photo) (label :t/image-source-gallery)]
|
||||||
:callback (fn [index]
|
:callback (fn [index]
|
||||||
(case index
|
(case index
|
||||||
0 (dispatch [:show-profile-photo-capture])
|
0 (dispatch [:navigate-to :profile-photo-capture])
|
||||||
1 (dispatch [:open-image-picker])
|
1 (dispatch [:open-image-picker])
|
||||||
:default))
|
:default))
|
||||||
:cancel-text (label :t/image-source-cancel)}))))
|
:cancel-text (label :t/image-source-cancel)}))))
|
||||||
|
@ -16,15 +16,18 @@
|
|||||||
[status-im.utils.image-processing :refer [img->base64]]
|
[status-im.utils.image-processing :refer [img->base64]]
|
||||||
[status-im.profile.photo-capture.styles :as st]
|
[status-im.profile.photo-capture.styles :as st]
|
||||||
[status-im.i18n :refer [label]]
|
[status-im.i18n :refer [label]]
|
||||||
[reagent.core :as r]))
|
[reagent.core :as r]
|
||||||
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
(defn image-captured [path]
|
(defn image-captured [data]
|
||||||
(let [path (subs path 5)
|
(let [path (.-path data)
|
||||||
|
_ (log/debug "Captured image: " path)
|
||||||
on-success (fn [base64]
|
on-success (fn [base64]
|
||||||
|
(log/debug "Captured success: " base64)
|
||||||
(dispatch [:set-in [:profile-edit :photo-path] (str "data:image/jpeg;base64," base64)])
|
(dispatch [:set-in [:profile-edit :photo-path] (str "data:image/jpeg;base64," base64)])
|
||||||
(dispatch [:navigate-back]))
|
(dispatch [:navigate-back]))
|
||||||
on-error (fn [type error]
|
on-error (fn [type error]
|
||||||
(.log js/console type error))]
|
(log/debug type error))]
|
||||||
(img->base64 path on-success on-error)))
|
(img->base64 path on-success on-error)))
|
||||||
|
|
||||||
(defn profile-photo-capture []
|
(defn profile-photo-capture []
|
||||||
@ -47,7 +50,8 @@
|
|||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(let [camera @camera-ref]
|
(let [camera @camera-ref]
|
||||||
(-> (.capture camera)
|
(-> (.capture camera)
|
||||||
(.then image-captured))))}
|
(.then image-captured)
|
||||||
|
(.catch #(log/debug "Error capturing image: " %)))))}
|
||||||
[view
|
[view
|
||||||
[ion-icon {:name :md-camera
|
[ion-icon {:name :md-camera
|
||||||
:style {:font-size 36}}]]]]]))
|
:style {:font-size 36}}]]]]]))
|
@ -12,24 +12,25 @@
|
|||||||
scroll-view
|
scroll-view
|
||||||
touchable-highlight
|
touchable-highlight
|
||||||
touchable-opacity
|
touchable-opacity
|
||||||
show-image-picker]]
|
show-image-picker
|
||||||
|
dismiss-keyboard!]]
|
||||||
[status-im.components.icons.custom-icons :refer [oct-icon]]
|
[status-im.components.icons.custom-icons :refer [oct-icon]]
|
||||||
[status-im.components.chat-icon.screen :refer [my-profile-icon]]
|
[status-im.components.chat-icon.screen :refer [my-profile-icon]]
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.text-field.view :refer [text-field]]
|
[status-im.components.text-field.view :refer [text-field]]
|
||||||
|
[status-im.components.selectable-field.view :refer [selectable-field]]
|
||||||
[status-im.components.qr-code :refer [qr-code]]
|
[status-im.components.qr-code :refer [qr-code]]
|
||||||
[status-im.utils.handlers :refer [get-hashtags]]
|
|
||||||
[status-im.utils.phone-number :refer [format-phone-number]]
|
[status-im.utils.phone-number :refer [format-phone-number]]
|
||||||
[status-im.utils.image-processing :refer [img->base64]]
|
[status-im.utils.image-processing :refer [img->base64]]
|
||||||
[status-im.utils.platform :refer [platform-specific]]
|
[status-im.utils.platform :refer [platform-specific]]
|
||||||
[status-im.profile.handlers :refer [message-user
|
[status-im.profile.handlers :refer [message-user]]
|
||||||
update-profile]]
|
|
||||||
[status-im.profile.validations :as v]
|
[status-im.profile.validations :as v]
|
||||||
[status-im.profile.styles :as st]
|
[status-im.profile.styles :as st]
|
||||||
|
[status-im.utils.random :refer [id]]
|
||||||
[status-im.i18n :refer [label]]))
|
[status-im.i18n :refer [label]]))
|
||||||
|
|
||||||
(defn toolbar [{:keys [account profile-edit-data edit?]}]
|
(defn toolbar [{:keys [account edit?]}]
|
||||||
(let [profile-edit-data-valid? (s/valid? ::v/profile profile-edit-data)]
|
(let [profile-edit-data-valid? (s/valid? ::v/profile account)]
|
||||||
[view
|
[view
|
||||||
[touchable-highlight {:style st/back-btn-touchable
|
[touchable-highlight {:style st/back-btn-touchable
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
@ -41,20 +42,32 @@
|
|||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(if edit?
|
(if edit?
|
||||||
(when profile-edit-data-valid?
|
(when profile-edit-data-valid?
|
||||||
(update-profile account profile-edit-data)
|
(dismiss-keyboard!)
|
||||||
|
(dispatch [:check-status-change (:status account)])
|
||||||
|
(dispatch [:account-update account])
|
||||||
(dispatch [:set-in [:profile-edit :edit?] false]))
|
(dispatch [:set-in [:profile-edit :edit?] false]))
|
||||||
(dispatch [:set-in [:profile-edit :edit?] true])))}
|
(dispatch [:set :profile-edit (merge account {:edit? true})])))}
|
||||||
[view st/actions-btn-container
|
[view st/actions-btn-container
|
||||||
(if edit?
|
(if edit?
|
||||||
[oct-icon {:name :check
|
[oct-icon {:name :check
|
||||||
:style (st/ok-btn-icon profile-edit-data-valid?)}]
|
:style (st/ok-btn-icon profile-edit-data-valid?)}]
|
||||||
[icon :dots st/edit-btn-icon])]]]))
|
[icon :dots st/edit-btn-icon])]]]))
|
||||||
|
|
||||||
(defn status-image-view [{{address :address
|
(defn- get-text
|
||||||
username :name} :account
|
[word]
|
||||||
{new-name :name} :profile-edit-data
|
(let [props (merge {:key (id)}
|
||||||
photo-path :photo-path
|
(if (str/starts-with? word "#")
|
||||||
status :status
|
{:style st/hashtag}
|
||||||
|
{}))]
|
||||||
|
[text props (str word " ")]))
|
||||||
|
|
||||||
|
(defn- highlight-tags
|
||||||
|
[status]
|
||||||
|
(->>
|
||||||
|
(str/split status #" ")
|
||||||
|
(map get-text)))
|
||||||
|
|
||||||
|
(defn status-image-view [{{:keys [name status photo-path]} :account
|
||||||
edit? :edit?}]
|
edit? :edit?}]
|
||||||
[view st/status-block
|
[view st/status-block
|
||||||
[view st/user-photo-container
|
[view st/user-photo-container
|
||||||
@ -64,27 +77,27 @@
|
|||||||
(dispatch [:open-image-source-selector list-selection-fn])))}
|
(dispatch [:open-image-source-selector list-selection-fn])))}
|
||||||
[view
|
[view
|
||||||
[my-profile-icon {:account {:photo-path photo-path
|
[my-profile-icon {:account {:photo-path photo-path
|
||||||
:name username}
|
:name name}
|
||||||
:edit? edit?}]]]
|
:edit? edit?}]]]
|
||||||
[my-profile-icon {:account {:photo-path photo-path
|
[my-profile-icon {:account {:photo-path photo-path
|
||||||
:name username}
|
:name name}
|
||||||
:edit? edit?}])]
|
:edit? edit?}])]
|
||||||
[text-field
|
[text-field
|
||||||
{:line-color :white
|
{:line-color :white
|
||||||
:focus-line-color :white
|
:focus-line-color :white
|
||||||
:placeholder (label :t/user-anonymous)
|
|
||||||
:editable edit?
|
:editable edit?
|
||||||
:input-style (st/username-input edit? (s/valid? ::v/name (or new-name username)))
|
:input-style (st/username-input edit? (s/valid? ::v/name name))
|
||||||
:wrapper-style st/username-wrapper
|
:wrapper-style st/username-wrapper
|
||||||
:value (if (not= username address)
|
:value name
|
||||||
username)
|
|
||||||
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])}]
|
:on-change-text #(dispatch [:set-in [:profile-edit :name] %])}]
|
||||||
|
(if edit?
|
||||||
[text-input {:style st/status-input
|
[text-input {:style st/status-input
|
||||||
:maxLength 140
|
:maxLength 140
|
||||||
:editable edit?
|
:editable edit?
|
||||||
:placeholder (label :t/profile-no-status)
|
:placeholder (label :t/profile-no-status)
|
||||||
:on-change-text #(dispatch [:set-in [:profile-edit :status] %])
|
:on-change-text #(dispatch [:set-in [:profile-edit :status] %])
|
||||||
:default-value status}]])
|
:default-value status}]
|
||||||
|
[text {:style st/status-text} (highlight-tags status)])])
|
||||||
|
|
||||||
(defview profile []
|
(defview profile []
|
||||||
[{whisper-identity :whisper-identity
|
[{whisper-identity :whisper-identity
|
||||||
@ -149,69 +162,43 @@
|
|||||||
)}
|
)}
|
||||||
[view [text {:style st/report-user-text} (label :t/report-user)]]]]]])
|
[view [text {:style st/report-user-text} (label :t/report-user)]]]]]])
|
||||||
|
|
||||||
(defview my-profile-render []
|
(defview my-profile []
|
||||||
[{public-key :public-key
|
[edit? [:get-in [:profile-edit :edit?]]
|
||||||
address :address
|
current-account [:get-current-account]
|
||||||
username :name
|
changed-account [:get :profile-edit]]
|
||||||
email :email
|
(let [{:keys [phone
|
||||||
photo-path :photo-path
|
address
|
||||||
phone :phone
|
public-key] :as account} (if edit?
|
||||||
status :status
|
changed-account
|
||||||
:as account} [:get-current-account]
|
current-account)]
|
||||||
{edit? :edit?
|
[scroll-view {:style st/profile
|
||||||
new-name :name
|
:keyboardShouldPersistTaps true}
|
||||||
new-email :email
|
|
||||||
new-status :status
|
|
||||||
new-photo-path :photo-path
|
|
||||||
:as profile-edit-data} [:get :profile-edit]]
|
|
||||||
[scroll-view {:style st/profile}
|
|
||||||
[status-bar]
|
[status-bar]
|
||||||
[toolbar {:account account
|
[toolbar {:account account
|
||||||
:profile-edit-data profile-edit-data
|
|
||||||
:edit? edit?}]
|
:edit? edit?}]
|
||||||
|
|
||||||
[status-image-view {:account account
|
[status-image-view {:account account
|
||||||
:profile-edit-data profile-edit-data
|
|
||||||
:photo-path (or new-photo-path photo-path)
|
|
||||||
:status (or new-status status)
|
|
||||||
:edit? edit?}]
|
:edit? edit?}]
|
||||||
|
|
||||||
[scroll-view st/profile-properties-container
|
[scroll-view (merge st/profile-properties-container {:keyboardShouldPersistTaps true})
|
||||||
[text-field
|
[view st/profile-property
|
||||||
{:editable false
|
[selectable-field {:label (label :t/phone-number)
|
||||||
:input-style st/profile-input-text-non-editable
|
|
||||||
:wrapper-style st/profile-input-wrapper
|
|
||||||
:value (if (and phone (not (str/blank? phone)))
|
:value (if (and phone (not (str/blank? phone)))
|
||||||
(format-phone-number phone))
|
(format-phone-number phone)
|
||||||
:label (label :t/phone-number)}]
|
(label :t/not-specified))}]
|
||||||
|
[view st/underline-container]]
|
||||||
|
|
||||||
[text-field
|
[view st/profile-property
|
||||||
{:error (if-not (s/valid? ::v/email new-email)
|
[selectable-field {:label (label :t/address)
|
||||||
(label :t/error-incorrect-email))
|
:value address}]
|
||||||
:error-color "#7099e6"
|
[view st/underline-container]]
|
||||||
:editable edit?
|
|
||||||
:input-style (if edit?
|
[view st/profile-property
|
||||||
st/profile-input-text
|
[selectable-field {:label (label :t/public-key)
|
||||||
st/profile-input-text-non-editable)
|
:value public-key}]]
|
||||||
:wrapper-style st/profile-input-wrapper
|
|
||||||
:value (if (and email (not (str/blank? email)))
|
[view st/underline-container]
|
||||||
email)
|
|
||||||
:label (label :t/email)
|
|
||||||
:on-change-text #(dispatch [:set-in [:profile-edit :email] %])}]
|
|
||||||
|
|
||||||
[view st/qr-code-container
|
[view st/qr-code-container
|
||||||
;; TODO: this public key should be replaced by address
|
|
||||||
[qr-code {:value (str "ethereum:" public-key)
|
[qr-code {:value (str "ethereum:" public-key)
|
||||||
:size 220}]]]])
|
:size 220}]]]]))
|
||||||
|
|
||||||
(defview my-profile []
|
|
||||||
[{username :name
|
|
||||||
email :email} [:get-current-account]]
|
|
||||||
(r/create-class
|
|
||||||
{:component-will-mount
|
|
||||||
(fn []
|
|
||||||
(dispatch [:set :profile-edit {:edit? false
|
|
||||||
:name username
|
|
||||||
:email email}]))
|
|
||||||
:reagent-render
|
|
||||||
my-profile-render}))
|
|
@ -68,20 +68,28 @@
|
|||||||
{:flex-direction "column"
|
{:flex-direction "column"
|
||||||
:align-items "center"
|
:align-items "center"
|
||||||
:justifyContent "center"
|
:justifyContent "center"
|
||||||
:margin-left 100
|
:margin-bottom 38
|
||||||
:margin-right 100})
|
:margin-left 55
|
||||||
|
:margin-right 55})
|
||||||
|
|
||||||
(def status-input
|
(def status-input
|
||||||
{:align-self "stretch"
|
{:align-self "stretch"
|
||||||
:margin-left 16
|
:margin-left 16
|
||||||
:margin-right 16
|
:margin-right 16
|
||||||
:height 40
|
:height 40
|
||||||
:margin-top -4
|
:margin-top 0
|
||||||
:font-size 14
|
:font-size 14
|
||||||
:line-height 20
|
:line-height 20
|
||||||
:text-align :center
|
:text-align :center
|
||||||
:color text2-color})
|
:color text2-color})
|
||||||
|
|
||||||
|
(def status-text
|
||||||
|
{:text-align :center
|
||||||
|
:margin-left 0
|
||||||
|
:margin-right 0
|
||||||
|
:margin-top 10
|
||||||
|
:color text2-color})
|
||||||
|
|
||||||
(def btns-container
|
(def btns-container
|
||||||
{:margin-top 18
|
{:margin-top 18
|
||||||
:flex-direction :row})
|
:flex-direction :row})
|
||||||
@ -114,11 +122,12 @@
|
|||||||
:height 16})
|
:height 16})
|
||||||
|
|
||||||
(def profile-properties-container
|
(def profile-properties-container
|
||||||
{:margin-top 20
|
{:align-items :stretch
|
||||||
:margin-left 16
|
|
||||||
:align-items :stretch
|
|
||||||
:flex-firection :column})
|
:flex-firection :column})
|
||||||
|
|
||||||
|
(def profile-property
|
||||||
|
{:margin-left 16})
|
||||||
|
|
||||||
(def profile-input-wrapper
|
(def profile-input-wrapper
|
||||||
{:margin-bottom 16})
|
{:margin-bottom 16})
|
||||||
|
|
||||||
@ -144,3 +153,12 @@
|
|||||||
{:flex 1
|
{:flex 1
|
||||||
:alignItems :center
|
:alignItems :center
|
||||||
:margin 32})
|
:margin 32})
|
||||||
|
|
||||||
|
(def hashtag
|
||||||
|
{:color "#7099e6"})
|
||||||
|
|
||||||
|
(def underline-container
|
||||||
|
{:background-color "#0000001f"
|
||||||
|
:margin-bottom 18
|
||||||
|
:height 1
|
||||||
|
:align-items :center})
|
||||||
|
@ -18,4 +18,4 @@
|
|||||||
(s/def ::name correct-name?)
|
(s/def ::name correct-name?)
|
||||||
(s/def ::email correct-email?)
|
(s/def ::email correct-email?)
|
||||||
|
|
||||||
(s/def ::profile (s/keys :req-un [::name ::email]))
|
(s/def ::profile (s/keys :req-un [::name]))
|
||||||
|
@ -63,6 +63,7 @@
|
|||||||
:username "Username"
|
:username "Username"
|
||||||
:user-anonymous "Anonymous"
|
:user-anonymous "Anonymous"
|
||||||
:not-specified "Not specified"
|
:not-specified "Not specified"
|
||||||
|
:public-key "Public Key"
|
||||||
:phone-number "Phone number"
|
:phone-number "Phone number"
|
||||||
:email "Email"
|
:email "Email"
|
||||||
:profile-no-status "No status"
|
:profile-no-status "No status"
|
||||||
|
1505
src/status_im/utils/gfycat/adjectives.cljs
Normal file
1505
src/status_im/utils/gfycat/adjectives.cljs
Normal file
File diff suppressed because it is too large
Load Diff
1753
src/status_im/utils/gfycat/animals.cljs
Normal file
1753
src/status_im/utils/gfycat/animals.cljs
Normal file
File diff suppressed because it is too large
Load Diff
16
src/status_im/utils/gfycat/core.cljs
Normal file
16
src/status_im/utils/gfycat/core.cljs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
(ns status-im.utils.gfycat.core
|
||||||
|
(:require [status-im.utils.gfycat.animals :as animals]
|
||||||
|
[status-im.utils.gfycat.adjectives :as adjectives]
|
||||||
|
[clojure.string :as str]))
|
||||||
|
|
||||||
|
(defn- pick-random
|
||||||
|
[vector]
|
||||||
|
(-> (rand-nth vector)
|
||||||
|
str/capitalize))
|
||||||
|
|
||||||
|
(defn generate-gfy
|
||||||
|
[]
|
||||||
|
(let [first-adjective (pick-random adjectives/data)
|
||||||
|
second-adjective (pick-random adjectives/data)
|
||||||
|
animal (pick-random animals/data)]
|
||||||
|
(str first-adjective " " second-adjective " " animal)))
|
@ -1,6 +1,8 @@
|
|||||||
(ns status-im.utils.image-processing
|
(ns status-im.utils.image-processing
|
||||||
(:require [reagent.core :as r]
|
(:require [reagent.core :as r]
|
||||||
[status-im.utils.fs :refer [read-file]]))
|
[status-im.utils.fs :refer [read-file]]
|
||||||
|
[taoensso.timbre :as log]
|
||||||
|
[clojure.string :as str]))
|
||||||
|
|
||||||
(def resizer-class (js/require "react-native-image-resizer"))
|
(def resizer-class (js/require "react-native-image-resizer"))
|
||||||
|
|
||||||
@ -19,7 +21,10 @@
|
|||||||
|
|
||||||
(defn img->base64 [path on-success on-error]
|
(defn img->base64 [path on-success on-error]
|
||||||
(let [on-resized (fn [path]
|
(let [on-resized (fn [path]
|
||||||
(image-base64-encode path on-success on-error))
|
(let [path (str/replace path "file:" "")]
|
||||||
|
(log/debug "Resized: " path)
|
||||||
|
(image-base64-encode path on-success on-error)))
|
||||||
on-error (fn [error]
|
on-error (fn [error]
|
||||||
|
(log/debug "Resized error: " error)
|
||||||
(on-error :resize error))]
|
(on-error :resize error))]
|
||||||
(resize path 150 150 on-resized on-error)))
|
(resize path 150 150 on-resized on-error)))
|
Loading…
x
Reference in New Issue
Block a user