From a33e7f2e90f1ff1ee993b00a417b791bdb94695b Mon Sep 17 00:00:00 2001 From: Mohsen Date: Fri, 16 Feb 2024 16:19:44 +0300 Subject: [PATCH] [#18600] feat: implement set bio screen (#18765) --- src/status_im/common/validation/profile.cljs | 15 +++- src/status_im/constants.cljs | 1 + .../contexts/profile/edit/bio/events.cljs | 22 ++++++ .../profile/edit/bio/events_test.cljs | 15 ++++ .../contexts/profile/edit/bio/style.cljs | 17 +++++ .../contexts/profile/edit/bio/view.cljs | 71 +++++++++++++++++++ .../contexts/profile/edit/list_items.cljs | 8 ++- src/status_im/contexts/profile/events.cljs | 1 + .../profile/settings/header/view.cljs | 2 + src/status_im/navigation/screens.cljs | 5 ++ src/tests/integration_test/profile_test.cljs | 17 +++++ status-go-version.json | 6 +- translations/en.json | 5 ++ 13 files changed, 178 insertions(+), 7 deletions(-) create mode 100644 src/status_im/contexts/profile/edit/bio/events.cljs create mode 100644 src/status_im/contexts/profile/edit/bio/events_test.cljs create mode 100644 src/status_im/contexts/profile/edit/bio/style.cljs create mode 100644 src/status_im/contexts/profile/edit/bio/view.cljs diff --git a/src/status_im/common/validation/profile.cljs b/src/status_im/common/validation/profile.cljs index 13f03cf41c..2272fd6f1e 100644 --- a/src/status_im/common/validation/profile.cljs +++ b/src/status_im/common/validation/profile.cljs @@ -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))) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index 082a3af563..d8f67736d0 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -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) diff --git a/src/status_im/contexts/profile/edit/bio/events.cljs b/src/status_im/contexts/profile/edit/bio/events.cljs new file mode 100644 index 0000000000..b85d8d3244 --- /dev/null +++ b/src/status_im/contexts/profile/edit/bio/events.cljs @@ -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) diff --git a/src/status_im/contexts/profile/edit/bio/events_test.cljs b/src/status_im/contexts/profile/edit/bio/events_test.cljs new file mode 100644 index 0000000000..ef442f07e8 --- /dev/null +++ b/src/status_im/contexts/profile/edit/bio/events_test.cljs @@ -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]))))) diff --git a/src/status_im/contexts/profile/edit/bio/style.cljs b/src/status_im/contexts/profile/edit/bio/style.cljs new file mode 100644 index 0000000000..ab1b92cc9d --- /dev/null +++ b/src/status_im/contexts/profile/edit/bio/style.cljs @@ -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}) diff --git a/src/status_im/contexts/profile/edit/bio/view.cljs b/src/status_im/contexts/profile/edit/bio/view.cljs new file mode 100644 index 0000000000..ed1ded70f7 --- /dev/null +++ b/src/status_im/contexts/profile/edit/bio/view.cljs @@ -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)]]]]))) diff --git a/src/status_im/contexts/profile/edit/list_items.cljs b/src/status_im/contexts/profile/edit/list_items.cljs index 1328fc9a8b..39d12bc50f 100644 --- a/src/status_im/contexts/profile/edit/list_items.cljs +++ b/src/status_im/contexts/profile/edit/list_items.cljs @@ -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) diff --git a/src/status_im/contexts/profile/events.cljs b/src/status_im/contexts/profile/events.cljs index a2b8f4df5d..7938be6738 100644 --- a/src/status_im/contexts/profile/events.cljs +++ b/src/status_im/contexts/profile/events.cljs @@ -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] diff --git a/src/status_im/contexts/profile/settings/header/view.cljs b/src/status_im/contexts/profile/settings/header/view.cljs index 07a4fe597c..32b79b6006 100644 --- a/src/status_im/contexts/profile/settings/header/view.cljs +++ b/src/status_im/contexts/profile/settings/header/view.cljs @@ -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)) diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 95c1f0ccb1..b7fd909b87 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -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 diff --git a/src/tests/integration_test/profile_test.cljs b/src/tests/integration_test/profile_test.cljs index b59f06ae56..29c7bd0dbb 100644 --- a/src/tests/integration_test/profile_test.cljs +++ b/src/tests/integration_test/profile_test.cljs @@ -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])))))))) diff --git a/status-go-version.json b/status-go-version.json index fcb954a6ec..5cf9022ca4 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -3,7 +3,7 @@ "_comment": "Instead use: scripts/update-status-go.sh ", "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" } diff --git a/translations/en.json b/translations/en.json index f1acc4560e..ae88702076 100644 --- a/translations/en.json +++ b/translations/en.json @@ -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",