moving drawer local state to db and fixing bug
This commit is contained in:
parent
d5981c65a1
commit
ab98de0be5
|
@ -1,5 +1,5 @@
|
||||||
(ns status-im.components.drawer.view
|
(ns status-im.components.drawer.view
|
||||||
(:require-macros [status-im.utils.views :refer [defview]])
|
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||||
(:require [cljs.spec.alpha :as s]
|
(:require [cljs.spec.alpha :as s]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[reagent.core :as r]
|
[reagent.core :as r]
|
||||||
|
@ -30,64 +30,73 @@
|
||||||
[status-im.utils.money :as money]))
|
[status-im.utils.money :as money]))
|
||||||
|
|
||||||
(defonce drawer-atom (atom nil))
|
(defonce drawer-atom (atom nil))
|
||||||
(defn open-drawer [] (.openDrawer @drawer-atom))
|
(defn open-drawer! [] (.openDrawer @drawer-atom))
|
||||||
(defn close-drawer [] (.closeDrawer @drawer-atom))
|
(defn close-drawer! [] (.closeDrawer @drawer-atom))
|
||||||
|
|
||||||
|
;; the save-event subscription is here because no save action would
|
||||||
|
;; be dispatched when the user presses a screen changing zone while
|
||||||
|
;; editing the name or status field
|
||||||
|
|
||||||
|
(defn save-profile! []
|
||||||
|
(when-let [save-event @(rf/subscribe [:my-profile.drawer/save-event])]
|
||||||
|
(rf/dispatch [save-event])))
|
||||||
|
|
||||||
|
(defn navigate-to-profile []
|
||||||
|
(close-drawer!)
|
||||||
|
(save-profile!)
|
||||||
|
(rf/dispatch [:navigate-to :my-profile]))
|
||||||
|
|
||||||
|
(defn navigate-to-accounts []
|
||||||
|
(close-drawer!)
|
||||||
|
(save-profile!)
|
||||||
|
(rf/dispatch [:navigate-to :accounts]))
|
||||||
|
|
||||||
(defview profile-picture []
|
(defview profile-picture []
|
||||||
[account [:get-current-account]]
|
(letsubs [account [:get-current-account]]
|
||||||
[touchable-opacity {:on-press #(rf/dispatch [:navigate-to :my-profile])
|
[touchable-opacity {:on-press navigate-to-profile
|
||||||
:style st/user-photo-container}
|
:style st/user-photo-container}
|
||||||
[view
|
[view
|
||||||
[ci/chat-icon (:photo-path account) {:size 52
|
[ci/chat-icon (:photo-path account) {:size 52
|
||||||
:accessibility-label :drawer-profile-icon}]]])
|
:accessibility-label :drawer-profile-icon}]]]))
|
||||||
|
|
||||||
(defview name-input []
|
(defview name-input []
|
||||||
[account [:get-current-account]
|
(letsubs [profile-name [:my-profile.drawer/get :name]
|
||||||
name-text (r/atom nil)]
|
valid-name? [:my-profile.drawer/valid-name?]
|
||||||
(let [previous-name (:name account)
|
placeholder [:get :my-profile/default-name]]
|
||||||
public-key (:public-key account)
|
|
||||||
placeholder (gfycat/generate-gfy public-key)]
|
|
||||||
[view st/name-input-wrapper
|
[view st/name-input-wrapper
|
||||||
[text-input
|
[text-input
|
||||||
{:placeholder placeholder
|
{:placeholder placeholder
|
||||||
:style (st/name-input-text (s/valid? ::profile.db/name @name-text))
|
:style (st/name-input-text valid-name?)
|
||||||
:font :medium
|
:font :medium
|
||||||
:default-value (or @name-text previous-name)
|
:default-value profile-name
|
||||||
:on-change-text #(reset! name-text %)
|
:on-focus #(rf/dispatch [:my-profile.drawer/edit-name])
|
||||||
:on-end-editing #(if (s/valid? ::profile.db/name @name-text)
|
:on-change-text #(rf/dispatch [:my-profile.drawer/update-name %])
|
||||||
(rf/dispatch [:account-update {:name (utils/clean-text (or @name-text placeholder))}])
|
:on-end-editing #(rf/dispatch [:my-profile.drawer/save-name])}]]))
|
||||||
(reset! name-text previous-name))}]]))
|
|
||||||
|
|
||||||
(defview status-input []
|
(defview status-input []
|
||||||
[account [:get-current-account]
|
(letsubs [edit-status? [:my-profile.drawer/get :edit-status?]
|
||||||
status-edit? (r/atom false)
|
status [:my-profile.drawer/get :status]]
|
||||||
status-text (r/atom nil)]
|
(let [placeholder (i18n/label :t/update-status)]
|
||||||
(let [placeholder (i18n/label :t/update-status)
|
[view st/status-container
|
||||||
previous-status (:status account)]
|
(if edit-status?
|
||||||
[view st/status-container
|
[text-input {:style st/status-input-view
|
||||||
(if @status-edit?
|
:multiline true
|
||||||
[text-input {:style st/status-input-view
|
:auto-focus true
|
||||||
:multiline true
|
:focus edit-status?
|
||||||
:auto-focus true
|
:max-length 140
|
||||||
:focus @status-edit?
|
:accessibility-label :drawer-status-input
|
||||||
:max-length 140
|
:placeholder placeholder
|
||||||
:accessibility-label :drawer-status-input
|
:default-value status
|
||||||
:placeholder placeholder
|
:on-change-text #(rf/dispatch [:my-profile.drawer/update-status %])
|
||||||
:default-value previous-status
|
:on-end-editing #(when edit-status?
|
||||||
:on-change-text #(let [new-status (utils/clean-text %)]
|
(rf/dispatch [:my-profile.drawer/save-status]))}]
|
||||||
(reset! status-text new-status)
|
|
||||||
(when (str/includes? % "\n")
|
|
||||||
(reset! status-edit? false)
|
|
||||||
(rf/dispatch [:my-profile/update-status new-status])))
|
|
||||||
:on-blur #(do (reset! status-edit? false)
|
|
||||||
(rf/dispatch [:my-profile/update-status @status-text]))}]
|
|
||||||
|
|
||||||
[status-view/status-view {:style (st/status-view (str/blank? previous-status))
|
[status-view/status-view {:style (st/status-view (str/blank? status))
|
||||||
:on-press #(reset! status-edit? true)
|
:number-of-lines 3
|
||||||
:number-of-lines 3
|
:status (if (str/blank? status)
|
||||||
:status (if (str/blank? previous-status)
|
placeholder
|
||||||
placeholder
|
status)
|
||||||
previous-status)}])]))
|
:on-press #(rf/dispatch [:my-profile.drawer/edit-status])}])])))
|
||||||
|
|
||||||
(defview transaction-list-item [{:keys [to value timestamp] :as transaction}]
|
(defview transaction-list-item [{:keys [to value timestamp] :as transaction}]
|
||||||
[recipient [:contact-by-address to]]
|
[recipient [:contact-by-address to]]
|
||||||
|
@ -144,17 +153,13 @@
|
||||||
(defn options-btn []
|
(defn options-btn []
|
||||||
[view {:style st/options-button}
|
[view {:style st/options-button}
|
||||||
[touchable-highlight
|
[touchable-highlight
|
||||||
{:on-press (fn []
|
{:on-press navigate-to-profile}
|
||||||
(close-drawer)
|
|
||||||
(rf/dispatch [:navigate-to :my-profile]))}
|
|
||||||
[view [vi/icon :icons/options]]]])
|
[view [vi/icon :icons/options]]]])
|
||||||
|
|
||||||
(defn switch-account []
|
(defn switch-account []
|
||||||
[view st/switch-account-container
|
[view st/switch-account-container
|
||||||
[touchable-highlight
|
[touchable-highlight
|
||||||
{:on-press (fn []
|
{:on-press navigate-to-accounts}
|
||||||
(close-drawer)
|
|
||||||
(rf/dispatch [:navigate-to :accounts]))}
|
|
||||||
[view
|
[view
|
||||||
[text {:style st/switch-account-text
|
[text {:style st/switch-account-text
|
||||||
:font (if platform/android? :medium :default)
|
:font (if platform/android? :medium :default)
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
[status-im.components.renderers.renderers :as renderers]
|
[status-im.components.renderers.renderers :as renderers]
|
||||||
[status-im.components.react :as react]
|
[status-im.components.react :as react]
|
||||||
[status-im.components.native-action-button :refer [native-action-button]]
|
[status-im.components.native-action-button :refer [native-action-button]]
|
||||||
[status-im.components.drawer.view :refer [open-drawer]]
|
[status-im.components.drawer.view :as drawer]
|
||||||
[status-im.components.styles :refer [color-blue]]
|
[status-im.components.styles :refer [color-blue]]
|
||||||
[status-im.components.status-bar :refer [status-bar]]
|
[status-im.components.status-bar :refer [status-bar]]
|
||||||
[status-im.components.toolbar-new.view :as toolbar]
|
[status-im.components.toolbar-new.view :as toolbar]
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
(defn toolbar-view []
|
(defn toolbar-view []
|
||||||
[toolbar/toolbar2 {}
|
[toolbar/toolbar2 {}
|
||||||
[toolbar/nav-button (act/hamburger open-drawer)]
|
[toolbar/nav-button (act/hamburger open-drawer!)]
|
||||||
[toolbar/content-title (i18n/label :t/chats)]
|
[toolbar/content-title (i18n/label :t/chats)]
|
||||||
[toolbar/actions
|
[toolbar/actions
|
||||||
(if ios?
|
(if ios?
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
native-action-button-item]]
|
native-action-button-item]]
|
||||||
[status-im.components.toolbar-new.view :as toolbar]
|
[status-im.components.toolbar-new.view :as toolbar]
|
||||||
[status-im.components.toolbar-new.actions :as act]
|
[status-im.components.toolbar-new.actions :as act]
|
||||||
[status-im.components.drawer.view :refer [open-drawer]]
|
[status-im.components.drawer.view :as drawer]
|
||||||
[status-im.components.icons.custom-icons :refer [ion-icon]]
|
[status-im.components.icons.custom-icons :refer [ion-icon]]
|
||||||
[status-im.components.contact.contact :refer [contact-view]]
|
[status-im.components.contact.contact :refer [contact-view]]
|
||||||
[status-im.utils.platform :refer [platform-specific ios? android?]]
|
[status-im.utils.platform :refer [platform-specific ios? android?]]
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
(defn toolbar-view []
|
(defn toolbar-view []
|
||||||
[toolbar/toolbar2 {}
|
[toolbar/toolbar2 {}
|
||||||
[toolbar/nav-button (act/hamburger open-drawer)]
|
[toolbar/nav-button (act/hamburger open-drawer!)]
|
||||||
[toolbar/content-title (label :t/contacts)]
|
[toolbar/content-title (label :t/contacts)]
|
||||||
[toolbar/actions
|
[toolbar/actions
|
||||||
(toolbar-actions)]])
|
(toolbar-actions)]])
|
||||||
|
@ -44,9 +44,9 @@
|
||||||
|
|
||||||
(defn contact-options [{:keys [unremovable?] :as contact} group]
|
(defn contact-options [{:keys [unremovable?] :as contact} group]
|
||||||
(let [delete-contact-opt {:value #(u/show-confirmation
|
(let [delete-contact-opt {:value #(u/show-confirmation
|
||||||
(str (label :t/delete-contact) "?") (label :t/delete-contact-confirmation)
|
(str (label :t/delete-contact) "?") (label :t/delete-contact-confirmation)
|
||||||
(label :t/delete)
|
(label :t/delete)
|
||||||
(fn [] (dispatch [:hide-contact contact])))
|
(fn [] (dispatch [:hide-contact contact])))
|
||||||
:text (label :t/delete-contact)
|
:text (label :t/delete-contact)
|
||||||
:destructive? true}
|
:destructive? true}
|
||||||
options (if unremovable? [] [delete-contact-opt])]
|
options (if unremovable? [] [delete-contact-opt])]
|
||||||
|
@ -70,17 +70,17 @@
|
||||||
[view st/contacts-list
|
[view st/contacts-list
|
||||||
[common/list-footer]
|
[common/list-footer]
|
||||||
(doall
|
(doall
|
||||||
(map (fn [contact]
|
(map (fn [contact]
|
||||||
^{:key contact}
|
^{:key contact}
|
||||||
[view
|
[view
|
||||||
[contact-view
|
[contact-view
|
||||||
{:contact contact
|
{:contact contact
|
||||||
:extended? edit?
|
:extended? edit?
|
||||||
:on-press #(dispatch [:open-chat-with-contact %])
|
:on-press #(dispatch [:open-chat-with-contact %])
|
||||||
:extend-options (contact-options contact group)}]
|
:extend-options (contact-options contact group)}]
|
||||||
(when-not (= contact (last contacts))
|
(when-not (= contact (last contacts))
|
||||||
[common/list-separator])])
|
[common/list-separator])])
|
||||||
contacts))]
|
contacts))]
|
||||||
(when (< contacts-limit contacts-count)
|
(when (< contacts-limit contacts-count)
|
||||||
[view
|
[view
|
||||||
[common/list-separator]
|
[common/list-separator]
|
||||||
|
|
|
@ -27,11 +27,6 @@
|
||||||
:current-chat-id console-chat-id
|
:current-chat-id console-chat-id
|
||||||
:loading-allowed true
|
:loading-allowed true
|
||||||
:selected-participants #{}
|
:selected-participants #{}
|
||||||
:my-profile/edit {:edit? false
|
|
||||||
:name nil
|
|
||||||
:email nil
|
|
||||||
:status nil
|
|
||||||
:photo-path nil}
|
|
||||||
:discoveries {}
|
:discoveries {}
|
||||||
:discover-search-tags '()
|
:discover-search-tags '()
|
||||||
:tags []
|
:tags []
|
||||||
|
@ -105,7 +100,9 @@
|
||||||
:accounts/current-account-id
|
:accounts/current-account-id
|
||||||
:accounts/recover
|
:accounts/recover
|
||||||
:accounts/login
|
:accounts/login
|
||||||
:my-profile/edit]
|
:my-profile/drawer
|
||||||
|
:my-profile/profile
|
||||||
|
:my-profile/default-name]
|
||||||
:opt-un
|
:opt-un
|
||||||
[::current-public-key
|
[::current-public-key
|
||||||
::modal
|
::modal
|
||||||
|
|
|
@ -1,23 +1,23 @@
|
||||||
(ns status-im.ui.screens.discover.views
|
(ns status-im.ui.screens.discover.views
|
||||||
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
(:require-macros [status-im.utils.views :refer [defview letsubs]])
|
||||||
(:require
|
(:require
|
||||||
[re-frame.core :refer [dispatch subscribe]]
|
[re-frame.core :refer [dispatch subscribe]]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[status-im.components.react :refer [view
|
[status-im.components.react :refer [view
|
||||||
scroll-view
|
scroll-view
|
||||||
text
|
text
|
||||||
text-input]]
|
text-input]]
|
||||||
[status-im.components.icons.vector-icons :as vi]
|
[status-im.components.icons.vector-icons :as vi]
|
||||||
[status-im.components.toolbar-new.view :refer [toolbar-with-search]]
|
[status-im.components.toolbar-new.view :refer [toolbar-with-search]]
|
||||||
[status-im.components.toolbar-new.actions :as act]
|
[status-im.components.toolbar-new.actions :as act]
|
||||||
[status-im.components.drawer.view :refer [open-drawer]]
|
[status-im.components.drawer.view :as drawer]
|
||||||
[status-im.components.carousel.carousel :refer [carousel]]
|
[status-im.components.carousel.carousel :refer [carousel]]
|
||||||
[status-im.ui.screens.discover.views.popular-list :refer [discover-popular-list]]
|
[status-im.ui.screens.discover.views.popular-list :refer [discover-popular-list]]
|
||||||
[status-im.ui.screens.discover.views.discover-list-item :refer [discover-list-item]]
|
[status-im.ui.screens.discover.views.discover-list-item :refer [discover-list-item]]
|
||||||
[status-im.utils.platform :refer [platform-specific]]
|
[status-im.utils.platform :refer [platform-specific]]
|
||||||
[status-im.i18n :refer [label]]
|
[status-im.i18n :refer [label]]
|
||||||
[status-im.ui.screens.discover.styles :as st]
|
[status-im.ui.screens.discover.styles :as st]
|
||||||
[status-im.ui.screens.contacts.styles :as contacts-st]))
|
[status-im.ui.screens.contacts.styles :as contacts-st]))
|
||||||
|
|
||||||
(defn get-hashtags [status]
|
(defn get-hashtags [status]
|
||||||
(let [hashtags (map #(str/lower-case (str/replace % #"#" "")) (re-seq #"[^ !?,;:.]+" status))]
|
(let [hashtags (map #(str/lower-case (str/replace % #"#" "")) (re-seq #"[^ !?,;:.]+" status))]
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
:search-key :discover
|
:search-key :discover
|
||||||
:title (label :t/discover)
|
:title (label :t/discover)
|
||||||
:search-placeholder (label :t/search-tags)
|
:search-placeholder (label :t/search-tags)
|
||||||
:nav-action (act/hamburger open-drawer)
|
:nav-action (act/hamburger drawer/open-drawer!)
|
||||||
:on-search-submit (fn [text]
|
:on-search-submit (fn [text]
|
||||||
(when-not (str/blank? text)
|
(when-not (str/blank? text)
|
||||||
(let [hashtags (get-hashtags text)]
|
(let [hashtags (get-hashtags text)]
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.utils.homoglyph :as homoglyph]))
|
[status-im.utils.homoglyph :as homoglyph]))
|
||||||
|
|
||||||
|
(def account-profile-keys [:name :photo-path :status])
|
||||||
|
|
||||||
(defn correct-name? [username]
|
(defn correct-name? [username]
|
||||||
(when-let [username (some-> username (string/trim))]
|
(when-let [username (some-> username (string/trim))]
|
||||||
(every? false?
|
(every? false?
|
||||||
|
@ -24,22 +26,13 @@
|
||||||
(or (string/starts-with? photo-path "data:image/jpeg;base64,")
|
(or (string/starts-with? photo-path "data:image/jpeg;base64,")
|
||||||
(string/starts-with? photo-path "data:image/png;base64,")))
|
(string/starts-with? photo-path "data:image/png;base64,")))
|
||||||
|
|
||||||
|
(spec/def :profile/name correct-name?)
|
||||||
(spec/def :profile/name (spec/nilable correct-name?))
|
(spec/def :profile/status (spec/nilable string?))
|
||||||
|
(spec/def :profile/photo-path (spec/nilable base64-encoded-image-path?))
|
||||||
(spec/def ::profile (spec/keys :req-un [:profile/name]))
|
|
||||||
|
|
||||||
|
|
||||||
(spec/def ::name (spec/or :name correct-name?
|
|
||||||
:empty-string string/blank?))
|
|
||||||
(spec/def ::email (spec/nilable correct-email?))
|
|
||||||
(spec/def ::edit? boolean?)
|
|
||||||
(spec/def ::status (spec/nilable string?))
|
|
||||||
(spec/def ::photo-path (spec/nilable base64-encoded-image-path?))
|
|
||||||
(spec/def ::edit-status? boolean?)
|
|
||||||
|
|
||||||
|
|
||||||
;; EDIT PROFILE
|
;; EDIT PROFILE
|
||||||
(spec/def :my-profile/edit (allowed-keys
|
(spec/def :my-profile/default-name string?)
|
||||||
:req-un [::email ::edit? ::name ::status ::photo-path]
|
(spec/def :my-profile/profile (spec/keys :opt-un [::name :profile/status :profile/photo-path
|
||||||
:opt-un [::edit-status?]))
|
::edit-status? ::valid-name?]))
|
||||||
|
(spec/def :my-profile/drawer (spec/keys :opt-un [::name :profile/status
|
||||||
|
::edit-status? ::valid-name?]))
|
||||||
|
|
|
@ -24,11 +24,15 @@
|
||||||
:actions [{:image :blank}]}])
|
:actions [{:image :blank}]}])
|
||||||
|
|
||||||
(defview profile-name-input []
|
(defview profile-name-input []
|
||||||
(letsubs [new-profile-name [:get-in [:my-profile/edit :name]]]
|
(letsubs [profile-name [:my-profile/get :name]
|
||||||
|
placeholder [:get :my-profile/default-name]]
|
||||||
[react/view
|
[react/view
|
||||||
[text-input-with-label {:label (label :t/name)
|
[text-input-with-label
|
||||||
:default-value new-profile-name
|
{:label (label :t/name)
|
||||||
:on-change-text #(dispatch [:set-in [:my-profile/edit :name] %])}]]))
|
:default-value profile-name
|
||||||
|
:on-focus #(dispatch [:my-profile/edit-profile])
|
||||||
|
:on-change-text #(dispatch [:my-profile/update-name %])}]]))
|
||||||
|
|
||||||
|
|
||||||
(def profile-icon-options
|
(def profile-icon-options
|
||||||
[{:text (label :t/image-source-gallery)
|
[{:text (label :t/image-source-gallery)
|
||||||
|
@ -39,9 +43,10 @@
|
||||||
[:camera :write-external-storage]
|
[:camera :write-external-storage]
|
||||||
(fn []
|
(fn []
|
||||||
(camera/request-access
|
(camera/request-access
|
||||||
#(if % (dispatch [:navigate-to :profile-photo-capture])
|
#(if %
|
||||||
(utils/show-popup (label :t/error)
|
(dispatch [:navigate-to :profile-photo-capture])
|
||||||
(label :t/camera-access-error)))))]))}])
|
(utils/show-popup (label :t/error)
|
||||||
|
(label :t/camera-access-error)))))]))}])
|
||||||
|
|
||||||
(defn edit-profile-badge [contact]
|
(defn edit-profile-badge [contact]
|
||||||
[react/view styles/edit-profile-badge
|
[react/view styles/edit-profile-badge
|
||||||
|
@ -54,24 +59,21 @@
|
||||||
[react/view styles/edit-profile-name-container
|
[react/view styles/edit-profile-name-container
|
||||||
[profile-name-input]]])
|
[profile-name-input]]])
|
||||||
|
|
||||||
(defn edit-profile-status [{:keys [status edit-status?]}]
|
(defview edit-profile-status []
|
||||||
(let [input-ref (reagent/atom nil)]
|
(letsubs [edit-status? [:my-profile/get :edit-status?]
|
||||||
|
status [:my-profile/get :status]]
|
||||||
[react/view styles/edit-profile-status
|
[react/view styles/edit-profile-status
|
||||||
[react/scroll-view
|
[react/scroll-view
|
||||||
(if edit-status?
|
(if edit-status?
|
||||||
[react/text-input
|
[react/text-input
|
||||||
{:ref #(reset! input-ref %)
|
{:auto-focus (if edit-status? true false)
|
||||||
:auto-focus edit-status?
|
|
||||||
:multiline true
|
:multiline true
|
||||||
:max-length 140
|
:max-length 140
|
||||||
:placeholder (label :t/status)
|
:placeholder (label :t/status)
|
||||||
:style styles/profile-status-input
|
:style styles/profile-status-input
|
||||||
:on-change-text #(dispatch [:set-in [:my-profile/edit :status] (clean-text %)])
|
:on-change-text #(dispatch [:my-profile/update-status %])
|
||||||
:on-blur #(dispatch [:set-in [:my-profile/edit :edit-status?] false])
|
|
||||||
:blur-on-submit true
|
|
||||||
:on-submit-editing #(.blur @input-ref)
|
|
||||||
:default-value status}]
|
:default-value status}]
|
||||||
[react/touchable-highlight {:on-press #(dispatch [:set-in [:my-profile/edit :edit-status?] true])}
|
[react/touchable-highlight {:on-press #(dispatch [:my-profile/edit-profile :status])}
|
||||||
[react/view
|
[react/view
|
||||||
(if (string/blank? status)
|
(if (string/blank? status)
|
||||||
[react/text {:style styles/add-a-status}
|
[react/text {:style styles/add-a-status}
|
||||||
|
@ -86,19 +88,16 @@
|
||||||
(colorize-status-hashtags (label :t/status-prompt))]]))
|
(colorize-status-hashtags (label :t/status-prompt))]]))
|
||||||
|
|
||||||
(defview edit-my-profile []
|
(defview edit-my-profile []
|
||||||
(letsubs [current-account [:get-current-account]
|
(letsubs [current-account [:get-current-account]
|
||||||
changed-account [:get :my-profile/edit]]
|
changed-account [:get :my-profile/profile]
|
||||||
{:component-will-unmount #(dispatch [:set-in [:my-profile/edit :edit-status?] false])}
|
profile-changed? [:my-profile/changed?]
|
||||||
(let [profile-edit-data-valid? (spec/valid? ::db/profile changed-account)
|
valid-name? [:my-profile/valid-name?]]
|
||||||
profile-edit-data-changed? (or (not= (:name current-account) (:name changed-account))
|
[react/keyboard-avoiding-view {:style styles/profile}
|
||||||
(not= (:status current-account) (:status changed-account))
|
[status-bar]
|
||||||
(not= (:photo-path current-account) (:photo-path changed-account)))]
|
[edit-my-profile-toolbar]
|
||||||
[react/keyboard-avoiding-view {:style styles/profile}
|
[react/view styles/edit-my-profile-form
|
||||||
[status-bar]
|
[edit-profile-badge changed-account]
|
||||||
[edit-my-profile-toolbar]
|
[edit-profile-status]
|
||||||
[react/view styles/edit-my-profile-form
|
[status-prompt changed-account]]
|
||||||
[edit-profile-badge changed-account]
|
(when (and valid-name? profile-changed?)
|
||||||
[edit-profile-status changed-account]
|
[sticky-button (label :t/save) #(dispatch [:my-profile/save-profile])])]))
|
||||||
[status-prompt changed-account]]
|
|
||||||
(when (and profile-edit-data-changed? profile-edit-data-valid?)
|
|
||||||
[sticky-button (label :t/save) #(dispatch [:my-profile/save-changes])])])))
|
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
(ns status-im.ui.screens.profile.events
|
(ns status-im.ui.screens.profile.events
|
||||||
(:require [clojure.string :as string]
|
(:require [clojure.spec.alpha :as spec]
|
||||||
|
[clojure.string :as string]
|
||||||
[re-frame.core :as re-frame :refer [reg-fx]]
|
[re-frame.core :as re-frame :refer [reg-fx]]
|
||||||
[status-im.components.react :refer [show-image-picker]]
|
[status-im.components.react :refer [show-image-picker]]
|
||||||
[status-im.constants :refer [console-chat-id]]
|
[status-im.constants :refer [console-chat-id]]
|
||||||
|
[status-im.ui.screens.profile.db :as db]
|
||||||
[status-im.ui.screens.profile.navigation]
|
[status-im.ui.screens.profile.navigation]
|
||||||
|
[status-im.utils.gfycat.core :as gfycat]
|
||||||
[status-im.utils.handlers :as handlers]
|
[status-im.utils.handlers :as handlers]
|
||||||
[status-im.utils.image-processing :refer [img->base64]]
|
[status-im.utils.image-processing :refer [img->base64]]
|
||||||
|
[status-im.utils.utils :as utils]
|
||||||
[taoensso.timbre :as log]))
|
[taoensso.timbre :as log]))
|
||||||
|
|
||||||
(def account-profile-keys [:name :photo-path :status])
|
|
||||||
|
|
||||||
(reg-fx
|
(reg-fx
|
||||||
:open-image-picker
|
:open-image-picker
|
||||||
;; the image picker is only used here for now, this effect can be use in other scenarios as well
|
;; the image picker is only used here for now, this effect can be use in other scenarios as well
|
||||||
|
@ -38,26 +40,6 @@
|
||||||
(when identity
|
(when identity
|
||||||
{:dispatch [:navigation-replace :chat identity]})))
|
{:dispatch [:navigation-replace :chat identity]})))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
|
||||||
:my-profile/edit
|
|
||||||
(fn [{:keys [db]} [_ edit-type edit-value]]
|
|
||||||
(let [current-account-id (:accounts/current-account-id db)
|
|
||||||
current-account (-> db
|
|
||||||
(get-in [:accounts/accounts current-account-id])
|
|
||||||
(select-keys account-profile-keys))
|
|
||||||
new-db (-> db
|
|
||||||
(update-in [:my-profile/edit] merge current-account)
|
|
||||||
(assoc-in [:my-profile/edit :edit-status?] (= edit-type :status true)))]
|
|
||||||
{:db new-db
|
|
||||||
:dispatch [:navigate-to :edit-my-profile]})))
|
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
|
||||||
:my-profile/update-status
|
|
||||||
(fn [_ [_ new-status]]
|
|
||||||
(when-not (string/blank? new-status)
|
|
||||||
{:dispatch-n [[:check-status-change new-status]
|
|
||||||
[:account-update {:status new-status}]]})))
|
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:my-profile/update-phone-number
|
:my-profile/update-phone-number
|
||||||
;; Switch user to the console issuing the !phone command automatically to let him change his phone number.
|
;; Switch user to the console issuing the !phone command automatically to let him change his phone number.
|
||||||
|
@ -66,16 +48,119 @@
|
||||||
{:dispatch-n [[:navigate-to :chat console-chat-id]
|
{:dispatch-n [[:navigate-to :chat console-chat-id]
|
||||||
[:select-chat-input-command {:name "phone"}]]}))
|
[:select-chat-input-command {:name "phone"}]]}))
|
||||||
|
|
||||||
|
(defn get-current-account [{:keys [:accounts/current-account-id] :as db}]
|
||||||
|
(get-in db [:accounts/accounts current-account-id]))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:my-profile.drawer/edit-name
|
||||||
|
(fn [{:keys [db]} _]
|
||||||
|
(let [{:my-profile/keys [default-name edit auto-save]} db
|
||||||
|
{:keys [name public-key]} (get-current-account db)]
|
||||||
|
{:db (cond-> db
|
||||||
|
(not default-name) (assoc :my-profile/default-name (gfycat/generate-gfy public-key))
|
||||||
|
:always (assoc-in [:my-profile/drawer :name] name))})))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:my-profile.drawer/edit-status
|
||||||
|
(fn [{:keys [db]} _]
|
||||||
|
(let [{:keys [status]} (get-current-account db)]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:my-profile/drawer :status] status)
|
||||||
|
(assoc-in [:my-profile/drawer :edit-status?] true))})))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:my-profile/edit-profile
|
||||||
|
(fn [{:keys [db]} [_ edit-status?]]
|
||||||
|
(let [new-db (-> db
|
||||||
|
(assoc-in [:my-profile/profile :edit-status?] edit-status?)
|
||||||
|
(update-in [:my-profile/profile]
|
||||||
|
#(merge (select-keys (get-current-account db) db/account-profile-keys) %)))]
|
||||||
|
{:db new-db
|
||||||
|
:dispatch [:navigate-to :edit-my-profile]})))
|
||||||
|
|
||||||
|
(defn valid-name? [name]
|
||||||
|
(spec/valid? :profile/name name))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:my-profile.drawer/update-name
|
||||||
|
(fn [{:keys [db]} [_ name]]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:my-profile/drawer :valid-name?] (valid-name? name))
|
||||||
|
(assoc-in [:my-profile/drawer :name] name))}))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:my-profile.drawer/update-status
|
||||||
|
(fn [{:keys [db]} [_ status]]
|
||||||
|
(let [linebreak? (string/includes? status "\n")
|
||||||
|
new-db (if linebreak?
|
||||||
|
(-> db
|
||||||
|
(assoc-in [:my-profile/drawer :edit-status?] nil)
|
||||||
|
(assoc-in [:my-profile/drawer :status] (utils/clean-text status)))
|
||||||
|
(assoc-in db [:my-profile/drawer :status] status))]
|
||||||
|
(if linebreak?
|
||||||
|
{:db new-db
|
||||||
|
:dispatch [:my-profile.drawer/save-status]}
|
||||||
|
{:db new-db}))))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:my-profile/update-name
|
||||||
|
(fn [{:keys [db]} [_ name]]
|
||||||
|
{:db (-> db
|
||||||
|
(assoc-in [:my-profile/profile :valid-name?] (valid-name? name))
|
||||||
|
(assoc-in [:my-profile/profile :name] name))}))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:my-profile/update-status
|
||||||
|
(fn [{:keys [db]} [_ status]]
|
||||||
|
{:db (if (string/includes? status "\n")
|
||||||
|
(-> db
|
||||||
|
(assoc-in [:my-profile/profile :edit-status?] nil)
|
||||||
|
(assoc-in [:my-profile/profile :status] (utils/clean-text status)))
|
||||||
|
(assoc-in db [:my-profile/profile :status] status))}))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:my-profile/update-picture
|
:my-profile/update-picture
|
||||||
(fn [{:keys [db]} [this-event base64-image]]
|
(fn [{:keys [db]} [this-event base64-image]]
|
||||||
(if base64-image
|
(if base64-image
|
||||||
{:db (assoc-in db [:my-profile/edit :photo-path] (str "data:image/jpeg;base64," base64-image))}
|
{:db (assoc-in db [:my-profile/profile :photo-path] (str "data:image/jpeg;base64," base64-image))}
|
||||||
{:open-image-picker this-event})))
|
{:open-image-picker this-event})))
|
||||||
|
|
||||||
|
(defn clean-name [{:accounts/keys [current-account-id] :as db} edit-view]
|
||||||
|
(let [name (get-in db [edit-view :name])]
|
||||||
|
(if (valid-name? name)
|
||||||
|
name
|
||||||
|
(get-in db [:accounts/accounts current-account-id :name]))))
|
||||||
|
|
||||||
|
(defn clear-profile [db]
|
||||||
|
(dissoc db :my-profile/profile :my-profile/drawer :my-profile/default-name))
|
||||||
|
|
||||||
(handlers/register-handler-fx
|
(handlers/register-handler-fx
|
||||||
:my-profile/save-changes
|
:my-profile.drawer/save-name
|
||||||
(fn [{:keys [db]} _]
|
(fn [{:keys [db]} _]
|
||||||
(let [{:keys [:my-profile/edit]} db]
|
(let [cleaned-name (clean-name db :my-profile/drawer)]
|
||||||
{:dispatch-n [[:check-status-change (:status edit)]
|
{:db (clear-profile db)
|
||||||
[:account-update (select-keys edit account-profile-keys)]]})))
|
:dispatch [:account-update {:name cleaned-name}]})))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:my-profile.drawer/save-status
|
||||||
|
(fn [{:keys [db]} _]
|
||||||
|
(let [status (get-in db [:my-profile/drawer :status])
|
||||||
|
new-db (clear-profile db)]
|
||||||
|
(if (string/blank? status)
|
||||||
|
{:db new-db}
|
||||||
|
{:db new-db
|
||||||
|
:dispatch-n [[:check-status-change status]
|
||||||
|
[:account-update {:status status}]]}))))
|
||||||
|
|
||||||
|
(handlers/register-handler-fx
|
||||||
|
:my-profile/save-profile
|
||||||
|
(fn [{:keys [db]} _]
|
||||||
|
(let [{:keys [status photo-path]} (:my-profile/profile db)
|
||||||
|
cleaned-name (clean-name db :my-profile/profile)
|
||||||
|
cleaned-edit {:name cleaned-name
|
||||||
|
:status status
|
||||||
|
:photo-path photo-path}]
|
||||||
|
{:db (clear-profile db)
|
||||||
|
:dispatch-n [[:check-status-change status]
|
||||||
|
[:account-update cleaned-edit]
|
||||||
|
[:navigate-back]]})))
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
_ (log/debug "Captured image: " path)
|
_ (log/debug "Captured image: " path)
|
||||||
on-success (fn [base64]
|
on-success (fn [base64]
|
||||||
(log/debug "Captured success: " base64)
|
(log/debug "Captured success: " base64)
|
||||||
(dispatch [:set-in [:my-profile/edit :photo-path] (str "data:image/jpeg;base64," base64)])
|
(dispatch [:my-profile/update-picture base64])
|
||||||
(dispatch [:navigate-back]))
|
(dispatch [:navigate-back]))
|
||||||
on-error (fn [type error]
|
on-error (fn [type error]
|
||||||
(log/debug type error))]
|
(log/debug type error))]
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
(ns status-im.ui.screens.profile.subs
|
||||||
|
(:require [re-frame.core :refer [reg-sub subscribe]]
|
||||||
|
[clojure.string :as string]
|
||||||
|
[status-im.ui.screens.profile.db :refer [account-profile-keys]]))
|
||||||
|
|
||||||
|
(defn get-in-profile [profile current-account k]
|
||||||
|
(or (get profile k)
|
||||||
|
(get current-account k)))
|
||||||
|
|
||||||
|
(reg-sub :my-profile/get
|
||||||
|
:<- [:get-current-account]
|
||||||
|
:<- [:get :my-profile/profile]
|
||||||
|
(fn [[current-account profile] [_ k]]
|
||||||
|
(get-in-profile profile current-account k)))
|
||||||
|
|
||||||
|
(reg-sub :my-profile.drawer/get
|
||||||
|
:<- [:get-current-account]
|
||||||
|
:<- [:get :my-profile/drawer]
|
||||||
|
(fn [[current-account profile] [_ k]]
|
||||||
|
(get-in-profile profile current-account k)))
|
||||||
|
|
||||||
|
(reg-sub :my-profile/valid-name?
|
||||||
|
:<- [:get :my-profile/profile]
|
||||||
|
(fn [profile]
|
||||||
|
(get profile :valid-name? true)))
|
||||||
|
|
||||||
|
(reg-sub :my-profile.drawer/valid-name?
|
||||||
|
:<- [:get :my-profile/drawer]
|
||||||
|
(fn [profile]
|
||||||
|
(or (string/blank? (:name profile))
|
||||||
|
(get profile :valid-name? true))))
|
||||||
|
|
||||||
|
(reg-sub :my-profile/changed?
|
||||||
|
:<- [:get-current-account]
|
||||||
|
:<- [:get :my-profile/profile]
|
||||||
|
(fn [[current-account profile]]
|
||||||
|
(not= (select-keys current-account account-profile-keys)
|
||||||
|
(select-keys profile account-profile-keys))))
|
||||||
|
|
||||||
|
(reg-sub :my-profile.drawer/save-event
|
||||||
|
:<- [:get-current-account]
|
||||||
|
:<- [:get :my-profile/drawer]
|
||||||
|
(fn [[{:keys [name status]} {new-name :name new-status :status}]]
|
||||||
|
(cond
|
||||||
|
(and new-name
|
||||||
|
(not= name new-name))
|
||||||
|
:my-profile.drawer/save-name
|
||||||
|
|
||||||
|
(and status
|
||||||
|
(not= status new-status))
|
||||||
|
:my-profile.drawer/save-status)))
|
|
@ -24,8 +24,8 @@
|
||||||
(:require-macros [status-im.utils.views :refer [defview]]))
|
(:require-macros [status-im.utils.views :refer [defview]]))
|
||||||
|
|
||||||
(defn my-profile-toolbar []
|
(defn my-profile-toolbar []
|
||||||
[toolbar/toolbar {:actions [(actions/opts [{:value #(dispatch [:my-profile/edit])
|
[toolbar/toolbar {:actions [(actions/opts [{:value #(dispatch [:my-profile/edit-profile])
|
||||||
:text (label :t/edit)}])]}])
|
:text (label :t/edit)}])]}])
|
||||||
|
|
||||||
(defn profile-toolbar [contact]
|
(defn profile-toolbar [contact]
|
||||||
[toolbar/toolbar
|
[toolbar/toolbar
|
||||||
|
@ -172,12 +172,12 @@
|
||||||
(defn profile-status [status & [edit?]]
|
(defn profile-status [status & [edit?]]
|
||||||
[react/view styles/profile-status-container
|
[react/view styles/profile-status-container
|
||||||
(if (or (nil? status) (string/blank? status))
|
(if (or (nil? status) (string/blank? status))
|
||||||
[react/touchable-highlight {:on-press #(dispatch [:my-profile/edit :status])}
|
[react/touchable-highlight {:on-press #(dispatch [:my-profile/edit-profile :edit-status])}
|
||||||
[react/view
|
[react/view
|
||||||
[react/text {:style styles/add-a-status}
|
[react/text {:style styles/add-a-status}
|
||||||
(label :t/add-a-status)]]]
|
(label :t/add-a-status)]]]
|
||||||
[react/scroll-view
|
[react/scroll-view
|
||||||
[react/touchable-highlight {:on-press (when edit? #(dispatch [:my-profile/edit :status]))}
|
[react/touchable-highlight {:on-press (when edit? #(dispatch [:my-profile/edit-profile :edit-status]))}
|
||||||
[react/view
|
[react/view
|
||||||
[react/text {:style styles/profile-status-text}
|
[react/text {:style styles/profile-status-text}
|
||||||
(colorize-status-hashtags status)]]]])])
|
(colorize-status-hashtags status)]]]])])
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
status-im.ui.screens.discover.subs
|
status-im.ui.screens.discover.subs
|
||||||
status-im.ui.screens.contacts.subs
|
status-im.ui.screens.contacts.subs
|
||||||
status-im.ui.screens.group.subs
|
status-im.ui.screens.group.subs
|
||||||
|
status-im.ui.screens.profile.subs
|
||||||
status-im.ui.screens.wallet.subs
|
status-im.ui.screens.wallet.subs
|
||||||
status-im.transactions.subs
|
status-im.transactions.subs
|
||||||
status-im.bots.subs))
|
status-im.bots.subs))
|
||||||
|
@ -39,4 +40,4 @@
|
||||||
(fn [[search-mode? chats-edit-mode? contacts-edit-mode? view-id]]
|
(fn [[search-mode? chats-edit-mode? contacts-edit-mode? view-id]]
|
||||||
(or search-mode?
|
(or search-mode?
|
||||||
(and (= view-id :chat-list) chats-edit-mode?)
|
(and (= view-id :chat-list) chats-edit-mode?)
|
||||||
(and (= view-id :contact-list) contacts-edit-mode?))))
|
(and (= view-id :contact-list) contacts-edit-mode?))))
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
|
|
||||||
(defn toolbar-view []
|
(defn toolbar-view []
|
||||||
[toolbar/toolbar2 {:style wallet-styles/toolbar}
|
[toolbar/toolbar2 {:style wallet-styles/toolbar}
|
||||||
[toolbar/nav-button (act/hamburger-white drawer/open-drawer)]
|
[toolbar/nav-button (act/hamburger-white drawer/open-drawer!)]
|
||||||
[toolbar-title]
|
[toolbar-title]
|
||||||
[toolbar/actions
|
[toolbar/actions
|
||||||
[(assoc (act/opts [{:text (i18n/label :t/wallet-settings) :value show-not-implemented!}]) :icon-opts {:color :white})
|
[(assoc (act/opts [{:text (i18n/label :t/wallet-settings) :value show-not-implemented!}]) :icon-opts {:color :white})
|
||||||
|
|
|
@ -29,26 +29,28 @@
|
||||||
(run-test-sync
|
(run-test-sync
|
||||||
(test-fixtures)
|
(test-fixtures)
|
||||||
(let [accounts (rf/subscribe [:get-accounts])
|
(let [accounts (rf/subscribe [:get-accounts])
|
||||||
address (:address new-account)
|
address (:address new-account)]
|
||||||
new-status "It's a new status!"]
|
|
||||||
(rf/dispatch [:initialize-db])
|
(rf/dispatch [:initialize-db])
|
||||||
(rf/dispatch [:add-account new-account])
|
(rf/dispatch [:add-account new-account])
|
||||||
(rf/dispatch [:set-current-account address])
|
(rf/dispatch [:set-current-account address])
|
||||||
(testing "Setting status"
|
|
||||||
(is (= (:status new-account) (-> @accounts
|
(testing "Setting status from edit profile screen"
|
||||||
(get address)
|
(let [new-status "New edit profile status"]
|
||||||
:status)))
|
(is (= (:status new-account) (-> @accounts
|
||||||
(rf/dispatch [:my-profile/update-status new-status])
|
(get address)
|
||||||
(is (= new-status (-> @accounts
|
:status)))
|
||||||
(get address)
|
(rf/dispatch [:my-profile/edit-profile :edit-status])
|
||||||
:status))))
|
(rf/dispatch [:my-profile/update-status new-status])
|
||||||
(testing "Setting phone number"
|
(rf/dispatch [:my-profile/save-profile])
|
||||||
(is (nil? (-> @accounts
|
(is (= new-status (-> @accounts
|
||||||
(get address)
|
(get address)
|
||||||
:phone)))
|
:status)))))
|
||||||
(rf/dispatch [:set-in [:my-profile/edit :edit-status?] true])
|
|
||||||
(rf/dispatch [:set-in [:my-profile/edit :name] "It's my new name"])
|
(testing "Setting status from drawer"
|
||||||
(rf/dispatch [:my-profile/save-changes])
|
(let [new-status "New drawer status"]
|
||||||
(is (= "It's my new name" (-> @accounts
|
(rf/dispatch [:my-profile.drawer/edit-status])
|
||||||
(get address)
|
(rf/dispatch [:my-profile.drawer/update-status new-status])
|
||||||
:name)))))))
|
(rf/dispatch [:my-profile.drawer/save-status])
|
||||||
|
(is (= new-status (-> @accounts
|
||||||
|
(get address)
|
||||||
|
:status))))))))
|
||||||
|
|
Loading…
Reference in New Issue