parent
54d9e5ebeb
commit
a33e7f2e90
|
@ -1,11 +1,11 @@
|
|||
(ns status-im.common.validation.profile
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
;; NOTE - validation should match with Desktop
|
||||
;; https://github.com/status-im/status-desktop/blob/2ba96803168461088346bf5030df750cb226df4c/ui/imports/utils/Constants.qml#L468
|
||||
(def min-length 5)
|
||||
(def max-length 24)
|
||||
|
||||
(def emoji-regex
|
||||
#"(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])")
|
||||
|
@ -22,7 +22,9 @@
|
|||
|
||||
(defn name-too-short? [s] (< (count (string/trim (str s))) min-length))
|
||||
|
||||
(defn name-too-long? [s] (> (count (string/trim (str s))) max-length))
|
||||
(defn name-too-long? [s] (> (count (string/trim (str s))) constants/profile-name-max-length))
|
||||
|
||||
(defn bio-too-long? [s] (> (count (string/trim (str s))) constants/profile-bio-max-length))
|
||||
|
||||
(defn validation-name
|
||||
[s]
|
||||
|
@ -39,3 +41,12 @@
|
|||
{:check (i18n/label :t/special-characters)})
|
||||
(name-too-short? s) (i18n/label :t/minimum-characters {:min-chars min-length})
|
||||
(name-too-long? s) (i18n/label :t/profile-name-is-too-long)))
|
||||
|
||||
(defn validation-bio
|
||||
[s]
|
||||
(cond
|
||||
(or (= s nil) (= s "")) nil
|
||||
(has-emojis? s) (i18n/label :t/are-not-allowed {:check (i18n/label :t/emojis)})
|
||||
(has-special-characters? s) (i18n/label :t/are-not-allowed
|
||||
{:check (i18n/label :t/special-characters)})
|
||||
(bio-too-long? s) (i18n/label :t/bio-is-too-long)))
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
|
||||
(def ^:const profile-default-color :blue)
|
||||
(def ^:const profile-name-max-length 24)
|
||||
(def ^:const profile-bio-max-length 240)
|
||||
(def ^:const profile-default-currency :usd)
|
||||
|
||||
(def ^:const profile-pictures-show-to-contacts-only 1)
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
(ns status-im.contexts.profile.edit.bio.events
|
||||
(:require [utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-event-fx :profile/edit-profile-bio-success
|
||||
(fn [_]
|
||||
{:fx [[:dispatch [:navigate-back]]
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text (i18n/label :t/bio-added)}]]]}))
|
||||
|
||||
(defn edit-profile-bio
|
||||
[{:keys [db]} [bio]]
|
||||
{:db (assoc-in db [:profile/profile :bio] bio)
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wakuext_setBio"
|
||||
:params [bio]
|
||||
:on-success [:profile/edit-profile-bio-success]}]]]})
|
||||
|
||||
(rf/reg-event-fx :profile/edit-bio edit-profile-bio)
|
|
@ -0,0 +1,15 @@
|
|||
(ns status-im.contexts.profile.edit.bio.events-test
|
||||
(:require [cljs.test :refer [deftest is]]
|
||||
matcher-combinators.test
|
||||
[status-im.contexts.profile.edit.bio.events :as sut]))
|
||||
|
||||
(deftest edit-bio-test
|
||||
(let [new-bio "New Bio text"
|
||||
cofx {:db {:profile/profile {:bio "Old Bio text"}}}
|
||||
expected {:db {:profile/profile {:bio new-bio}}
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wakuext_setBio"
|
||||
:params [new-bio]
|
||||
:on-success [:profile/edit-profile-bio-success]}]]]}]
|
||||
(is (match? expected
|
||||
(sut/edit-profile-bio cofx [new-bio])))))
|
|
@ -0,0 +1,17 @@
|
|||
(ns status-im.contexts.profile.edit.bio.style)
|
||||
|
||||
(defn page-wrapper
|
||||
[insets]
|
||||
{:padding-top (:top insets)
|
||||
:padding-bottom (:bottom insets)
|
||||
:padding-horizontal 1
|
||||
:flex 1})
|
||||
|
||||
(def screen-container
|
||||
{:flex 1
|
||||
:padding-top 14
|
||||
:padding-horizontal 20
|
||||
:justify-content :space-between})
|
||||
|
||||
(def button-wrapper
|
||||
{:margin-vertical 12})
|
|
@ -0,0 +1,71 @@
|
|||
(ns status-im.contexts.profile.edit.bio.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.validation.profile :as profile-validator]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.profile.edit.bio.style :as style]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [insets (safe-area/get-insets)
|
||||
profile (rf/sub [:profile/profile-with-image])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
profile-bio (:bio profile)
|
||||
unsaved-bio (reagent/atom profile-bio)
|
||||
error-msg (reagent/atom nil)
|
||||
typing? (reagent/atom false)
|
||||
validate-bio (debounce/debounce (fn [bio]
|
||||
(reset! error-msg
|
||||
(profile-validator/validation-bio bio))
|
||||
(reset! typing? false))
|
||||
300)
|
||||
on-change-text (fn [s]
|
||||
(reset! typing? true)
|
||||
(reset! unsaved-bio s)
|
||||
(validate-bio s))]
|
||||
(fn []
|
||||
[quo/overlay
|
||||
{:type :shell
|
||||
:container-style (style/page-wrapper insets)}
|
||||
[quo/page-nav
|
||||
{:key :header
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:key :content
|
||||
:style style/screen-container}
|
||||
[rn/view {:style {:gap 22}}
|
||||
[quo/text-combinations {:title (i18n/label :t/bio)}]
|
||||
[quo/input
|
||||
{:theme :dark
|
||||
:blur? true
|
||||
:multiline? true
|
||||
:error? (not (string/blank? @error-msg))
|
||||
:container-style {:margin-bottom -11}
|
||||
:default-value @unsaved-bio
|
||||
:auto-focus true
|
||||
:char-limit constants/profile-bio-max-length
|
||||
:label (i18n/label :t/profile-bio)
|
||||
:placeholder (i18n/label :t/something-about-you)
|
||||
:on-change-text on-change-text}]
|
||||
(when-not (string/blank? @error-msg)
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
@error-msg])]
|
||||
[rn/view {:style style/button-wrapper}
|
||||
[quo/button
|
||||
{:type :primary
|
||||
:customization-color customization-color
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:profile/edit-bio @unsaved-bio]))
|
||||
:disabled? (boolean (or @typing? (not (string/blank? @error-msg))))}
|
||||
(i18n/label :t/save-bio)]]]])))
|
|
@ -1,5 +1,6 @@
|
|||
(ns status-im.contexts.profile.edit.list-items
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
(:require [legacy.status-im.utils.core :as utils]
|
||||
[quo.foundations.colors :as colors]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.contexts.profile.edit.style :as style]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
|
@ -10,6 +11,7 @@
|
|||
[theme]
|
||||
(let [profile (rf/sub [:profile/profile-with-image])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
bio (:bio profile)
|
||||
full-name (profile.utils/displayed-name profile)]
|
||||
[{:label (i18n/label :t/profile)
|
||||
:items [{:title (i18n/label :t/name)
|
||||
|
@ -20,8 +22,10 @@
|
|||
:action :arrow
|
||||
:container-style style/item-container}
|
||||
{:title (i18n/label :t/bio)
|
||||
:on-press not-implemented/alert
|
||||
:on-press #(rf/dispatch [:open-modal :edit-bio])
|
||||
:blur? true
|
||||
:label :text
|
||||
:label-props (utils/truncate-str bio 15)
|
||||
:action :arrow
|
||||
:container-style style/item-container}
|
||||
{:title (i18n/label :t/accent-colour)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.contexts.profile.edit.accent-colour.events]
|
||||
[status-im.contexts.profile.edit.bio.events]
|
||||
[status-im.contexts.profile.edit.header.events]
|
||||
[status-im.contexts.profile.edit.name.events]
|
||||
[status-im.contexts.profile.login.events :as profile.login]
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
[:visibility-status-updates/visibility-status-update
|
||||
public-key])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
bio (:bio profile)
|
||||
full-name (profile.utils/displayed-name profile)
|
||||
profile-picture (profile.utils/photo profile)
|
||||
emoji-string (string/join emoji-hash)
|
||||
|
@ -53,6 +54,7 @@
|
|||
{:title-accessibility-label :username
|
||||
:container-style style/title-container
|
||||
:emoji-hash emoji-string
|
||||
:description bio
|
||||
:title full-name}]]))
|
||||
|
||||
(def view (quo.theme/with-theme f-view))
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
[status-im.contexts.preview.quo.main :as quo.preview]
|
||||
[status-im.contexts.preview.status-im.main :as status-im-preview]
|
||||
[status-im.contexts.profile.edit.accent-colour.view :as edit-accent-colour]
|
||||
[status-im.contexts.profile.edit.bio.view :as edit-bio]
|
||||
[status-im.contexts.profile.edit.name.view :as edit-name]
|
||||
[status-im.contexts.profile.edit.view :as edit-profile]
|
||||
[status-im.contexts.profile.profiles.view :as profiles]
|
||||
|
@ -191,6 +192,10 @@
|
|||
:options options/transparent-modal-screen-options
|
||||
:component edit-name/view}
|
||||
|
||||
{:name :edit-bio
|
||||
:options options/transparent-modal-screen-options
|
||||
:component edit-bio/view}
|
||||
|
||||
{:name :new-to-status
|
||||
:options {:theme :dark
|
||||
:layout options/onboarding-transparent-layout
|
||||
|
|
|
@ -56,3 +56,20 @@
|
|||
(is (nil? (:image profile))))
|
||||
(h/logout)
|
||||
(rf-test/wait-for [::logout/logout-method])))))))
|
||||
|
||||
(deftest edit-profile-bio-test
|
||||
(h/log-headline :edit-profile-bio-test)
|
||||
(let [new-bio "New bio text"]
|
||||
(rf-test/run-test-async
|
||||
(h/with-app-initialized
|
||||
(h/with-account
|
||||
(rf/dispatch [:profile/edit-bio new-bio])
|
||||
(rf-test/wait-for
|
||||
[:navigate-back]
|
||||
(rf-test/wait-for
|
||||
[:toasts/upsert]
|
||||
(let [profile (rf/sub [:profile/profile])
|
||||
bio (:bio profile)]
|
||||
(is (= new-bio bio)))
|
||||
(h/logout)
|
||||
(rf-test/wait-for [::logout/logout-method]))))))))
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.174.6",
|
||||
"commit-sha1": "f95dd35d131f68645b7c4dc5fbcea955c16e25bd",
|
||||
"src-sha256": "188chrifz4h3j6fpsrqq83v2vcnpp8y4282k9lhlrkkknfgwz5v2"
|
||||
"version": "v0.174.8",
|
||||
"commit-sha1": "8a3e71378f7208f75bd688c02b0ae5c43ca600f2",
|
||||
"src-sha256": "10wn93xn6xnkg2d8slyygy9rfrwiargm49738bdjj1g4b81220bq"
|
||||
}
|
||||
|
|
|
@ -67,6 +67,8 @@
|
|||
"balance": "Balance",
|
||||
"begin-set-up": "Begin setup",
|
||||
"bio": "Bio",
|
||||
"bio-added": "Bio added",
|
||||
"bio-is-too-long": "Bio is too long",
|
||||
"biometric-auth-android-sensor-desc": "Touch sensor",
|
||||
"biometric-auth-android-sensor-error-desc": "Failed",
|
||||
"biometric-auth-android-title": "Authentication Required",
|
||||
|
@ -1183,6 +1185,7 @@
|
|||
"processing": "Just a moment",
|
||||
"product-information": "Product Information",
|
||||
"profile": "Profile",
|
||||
"profile-bio": "Profile bio",
|
||||
"profile-details": "Profile details",
|
||||
"profile-name": "Profile name",
|
||||
"profile-name-is-too-long": "Profile name is too long",
|
||||
|
@ -1248,6 +1251,7 @@
|
|||
"revoke-access": "Revoke access",
|
||||
"rpc-url": "RPC URL",
|
||||
"save": "Save",
|
||||
"save-bio": "Save bio",
|
||||
"save-colour": "Save colour",
|
||||
"save-name": "Save name",
|
||||
"save-password": "Save password",
|
||||
|
@ -1318,6 +1322,7 @@
|
|||
"signing": "Signing",
|
||||
"signing-a-message": "Signing a message",
|
||||
"signing-phrase": "Signing phrase",
|
||||
"something-about-you": "Something about you",
|
||||
"something-went-wrong": "Something went wrong",
|
||||
"soon": "Soon",
|
||||
"special-characters": "Special characters",
|
||||
|
|
Loading…
Reference in New Issue