From 6f07e8022e28a42d1044ac484f7edad1182f67bb Mon Sep 17 00:00:00 2001 From: flexsurfer Date: Fri, 22 Mar 2024 14:10:51 +0100 Subject: [PATCH] Allow user to select a color for the group chat #18982 (#19088) --- src/legacy/status_im/data_store/chats.cljs | 8 +- .../status_im/data_store/chats_test.cljs | 4 +- src/legacy/status_im/group_chats/core.cljs | 10 -- src/legacy/status_im/ui/screens/screens.cljs | 5 - .../components/avatars/group_avatar/view.cljs | 2 +- .../components/colors/color_picker/view.cljs | 5 +- src/react_native/core.cljs | 24 ++-- .../common/floating_button_page/view.cljs | 3 +- .../password_input/view.cljs | 1 - src/status_im/common/validation/profile.cljs | 6 +- src/status_im/constants.cljs | 1 + src/status_im/contexts/chat/events.cljs | 15 +- .../contexts/chat/group_create/events.cljs | 34 +++++ .../contexts/chat/group_create/style.cljs | 22 +++ .../contexts/chat/group_create/view.cljs | 132 ++++++++++++++++++ .../contexts/chat/group_details/view.cljs | 6 +- .../contexts/chat/home/new_chat/view.cljs | 2 +- .../contexts/preview/quo/preview.cljs | 56 +++++--- .../contexts/wallet/create_account/view.cljs | 5 +- src/status_im/navigation/screens.cljs | 6 + src/status_im/navigation/view.cljs | 31 ++-- src/utils/emojilib.cljs | 3 + test/appium/views/chat_view.py | 2 +- test/appium/views/home_view.py | 4 +- test/appium/views/sign_in_view.py | 8 +- translations/en.json | 2 + 26 files changed, 298 insertions(+), 99 deletions(-) create mode 100644 src/status_im/contexts/chat/group_create/events.cljs create mode 100644 src/status_im/contexts/chat/group_create/style.cljs create mode 100644 src/status_im/contexts/chat/group_create/view.cljs diff --git a/src/legacy/status_im/data_store/chats.cljs b/src/legacy/status_im/data_store/chats.cljs index 79f59d66da..d104f00e72 100644 --- a/src/legacy/status_im/data_store/chats.cljs +++ b/src/legacy/status_im/data_store/chats.cljs @@ -1,6 +1,7 @@ (ns legacy.status-im.data-store.chats (:require [clojure.set :as set] + [clojure.string :as string] [legacy.status-im.data-store.messages :as messages] [legacy.status-im.utils.deprecated-types :as types] [re-frame.core :as re-frame] @@ -59,6 +60,10 @@ :admins #{} :members-joined #{}))) +(defn <-color + [value] + (if (string/starts-with? value "#") value (keyword value))) + (defn <-rpc [chat] (-> chat @@ -79,13 +84,14 @@ rpc->type unmarshal-members (update :last-message #(when % (messages/<-rpc %))) + (update :color <-color) (dissoc :members))) (defn <-rpc-js [^js chat] (-> {:name (.-name chat) :description (.-description chat) - :color (.-color chat) + :color (<-color (.-color chat)) :emoji (.-emoji chat) :timestamp (.-timestamp chat) :alias (.-alias chat) diff --git a/src/legacy/status_im/data_store/chats_test.cljs b/src/legacy/status_im/data_store/chats_test.cljs index 75d6813869..5d8a9c2246 100644 --- a/src/legacy/status_im/data_store/chats_test.cljs +++ b/src/legacy/status_im/data_store/chats_test.cljs @@ -5,7 +5,7 @@ (deftest normalize-chat-test (let [chat {:id "chat-id" - :color "color" + :color "yellow" :name "name" :chatType 3 :members [{:id "a" @@ -26,7 +26,7 @@ :timestamp 2} expected-chat {:public? false :group-chat true - :color "color" + :color :yellow :chat-name "name" :contacts #{"a" "b" "c" "d"} :chat-type 3 diff --git a/src/legacy/status_im/group_chats/core.cljs b/src/legacy/status_im/group_chats/core.cljs index 20002d7272..212f18c176 100644 --- a/src/legacy/status_im/group_chats/core.cljs +++ b/src/legacy/status_im/group_chats/core.cljs @@ -64,16 +64,6 @@ :js-response true :on-success #(re-frame/dispatch [:chat-updated %])}]}) -(rf/defn create - {:events [:group-chats.ui/create-pressed] - :interceptors [(re-frame/inject-cofx :random-guid-generator)]} - [{:keys [db] :as cofx} group-name] - (let [selected-contacts (:group/selected-contacts db)] - {:json-rpc/call [{:method "wakuext_createGroupChatWithMembers" - :params [nil group-name (into [] selected-contacts)] - :js-response true - :on-success #(re-frame/dispatch [:chat-updated %])}]})) - (rf/defn create-from-link {:events [:group-chats/create-from-link]} [cofx {:keys [chat-id invitation-admin chat-name]}] diff --git a/src/legacy/status_im/ui/screens/screens.cljs b/src/legacy/status_im/ui/screens/screens.cljs index dd47c52192..16c9a583f5 100644 --- a/src/legacy/status_im/ui/screens/screens.cljs +++ b/src/legacy/status_im/ui/screens/screens.cljs @@ -91,11 +91,6 @@ :options {:insets {:top? true}} :component stickers/pack} - {:name :new-group - :options {:insets {:top? true}} - ;;TODO custom subtitle - :component group-chat/new-group} - {:name :currency-settings :options {:topBar (topbar-options :t/main-currency) :insets {:top? true}} diff --git a/src/quo/components/avatars/group_avatar/view.cljs b/src/quo/components/avatars/group_avatar/view.cljs index d248881e7f..f3a585123d 100644 --- a/src/quo/components/avatars/group_avatar/view.cljs +++ b/src/quo/components/avatars/group_avatar/view.cljs @@ -25,7 +25,7 @@ :or {size :size-20 customization-color :blue picture nil - icon-name :i/group}}] + icon-name :i/members}}] (let [container-size (get-in sizes [size :container]) icon-size (get-in sizes [size :icon])] [rn/view diff --git a/src/quo/components/colors/color_picker/view.cljs b/src/quo/components/colors/color_picker/view.cljs index 11b22381b1..5db7bae5b3 100644 --- a/src/quo/components/colors/color_picker/view.cljs +++ b/src/quo/components/colors/color_picker/view.cljs @@ -3,7 +3,8 @@ [quo.components.colors.color.constants :as constants] [quo.components.colors.color.view :as color] [quo.foundations.colors :as colors] - [react-native.core :as rn])) + [react-native.core :as rn] + [react-native.gesture :as gesture])) (defn get-item-layout [_ index] @@ -52,7 +53,7 @@ :index index :viewPosition 0.5}))))) 50))) - [rn/flat-list + [gesture/flat-list {:ref on-ref ;; TODO: using :feng-shui? temporarily while b & w is being developed. ;; https://github.com/status-im/status-mobile/discussions/16676 diff --git a/src/react_native/core.cljs b/src/react_native/core.cljs index ef122682c3..e1327f0e2f 100644 --- a/src/react_native/core.cljs +++ b/src/react_native/core.cljs @@ -156,17 +156,19 @@ (defn get-js-deps [deps] (if deps - (let [prev-state (use-ref-atom {:value false :deps nil}) - prev-deps (:deps @prev-state) - prev-value (:value @prev-state)] - (if (and (not (nil? prev-deps)) (not= (count deps) (count prev-deps))) - (throw (js/Error. "Hooks can't have a different number of dependencies across re-renders")) - (if (not= deps prev-deps) - (let [new-value (not prev-value)] - (reset! prev-state {:value new-value - :deps deps}) - #js [new-value]) - #js [prev-value]))) + (if (empty? deps) + #js [true] + (let [prev-state (use-ref-atom {:value false :deps nil}) + prev-deps (:deps @prev-state) + prev-value (:value @prev-state)] + (if (and (not (nil? prev-deps)) (not= (count deps) (count prev-deps))) + (throw (js/Error. "Hooks can't have a different number of dependencies across re-renders")) + (if (not= deps prev-deps) + (let [new-value (not prev-value)] + (reset! prev-state {:value new-value + :deps deps}) + #js [new-value]) + #js [prev-value])))) js/undefined)) (defn use-effect diff --git a/src/status_im/common/floating_button_page/view.cljs b/src/status_im/common/floating_button_page/view.cljs index cab1e3ebfd..5c4819c57d 100644 --- a/src/status_im/common/floating_button_page/view.cljs +++ b/src/status_im/common/floating_button_page/view.cljs @@ -3,6 +3,7 @@ [oops.core :as oops] [quo.core :as quo] [react-native.core :as rn] + [react-native.gesture :as gesture] [react-native.platform :as platform] [react-native.safe-area :as safe-area] [reagent.core :as reagent] @@ -90,7 +91,7 @@ {:on-layout set-header-height :style header-container-style} header] - [rn/scroll-view + [gesture/scroll-view {:on-scroll set-content-y-scroll :scroll-event-throttle 64 :content-container-style {:flex-grow 1}} diff --git a/src/status_im/common/standard_authentication/password_input/view.cljs b/src/status_im/common/standard_authentication/password_input/view.cljs index 8b8a796b51..21abc3fc89 100644 --- a/src/status_im/common/standard_authentication/password_input/view.cljs +++ b/src/status_im/common/standard_authentication/password_input/view.cljs @@ -89,4 +89,3 @@ :i/face-id])] (when error? [error-info error-message processing shell?])])) - diff --git a/src/status_im/common/validation/profile.cljs b/src/status_im/common/validation/profile.cljs index 4b3454e03f..daea4d0d81 100644 --- a/src/status_im/common/validation/profile.cljs +++ b/src/status_im/common/validation/profile.cljs @@ -1,20 +1,18 @@ (ns status-im.common.validation.profile (:require [clojure.string :as string] [status-im.constants :as constants] + utils.emojilib [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 emoji-regex - #"(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])") - (def status-regex #"^[a-zA-Z0-9\-_ ]+$") (def common-names ["Ethereum" "Bitcoin"]) -(defn has-emojis? [s] (boolean (re-find emoji-regex s))) +(defn has-emojis? [s] (boolean (re-find utils.emojilib/emoji-regex s))) (defn has-common-names? [s] (pos? (count (filter #(string/includes? s %) common-names)))) diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index 74777a7caa..b5d189f960 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -122,6 +122,7 @@ (def ^:const min-password-length 6) (def ^:const max-group-chat-participants 20) +(def ^:const max-group-chat-name-length 24) (def ^:const default-number-of-messages 20) (def ^:const default-number-of-pin-messages 3) diff --git a/src/status_im/contexts/chat/events.cljs b/src/status_im/contexts/chat/events.cljs index fd99460691..f54dd1f0df 100644 --- a/src/status_im/contexts/chat/events.cljs +++ b/src/status_im/contexts/chat/events.cljs @@ -9,6 +9,7 @@ [status-im.constants :as constants] [status-im.contexts.chat.contacts.events :as contacts-store] status-im.contexts.chat.effects + status-im.contexts.chat.group-create.events [status-im.contexts.chat.messenger.composer.link-preview.events :as link-preview] status-im.contexts.chat.messenger.messages.content.reactions.events [status-im.contexts.chat.messenger.messages.delete-message-for-me.events :as delete-for-me] @@ -78,17 +79,10 @@ :invitation-admin (:invitation-admin chat))))) -(rf/defn leave-removed-chat - {:events [:chat/leave-removed-chat]} - [{{:keys [view-id current-chat-id chats]} :db - :as cofx}] - (when (and (= view-id :chat) - (not (contains? chats current-chat-id))) - (navigation/navigate-back cofx))) - (defn ensure-chats [{:keys [db] :as cofx} [chats]] - (let [{:keys [all-chats chats-home-list removed-chats]} + (let [{:keys [view-id current-chat-id]} db + {:keys [all-chats chats-home-list removed-chats]} (reduce (fn [acc {:keys [chat-id profile-public-key timeline? community-id active muted] :as chat}] (if (not (or active muted)) @@ -109,7 +103,8 @@ (update :chats-home-list set/difference removed-chats)) :fx [(when (not-empty removed-chats) [:effects/push-notifications-clear-message-notifications removed-chats]) - [:dispatch [:chat/leave-removed-chat]]]})) + (when (and (= view-id :chat) (removed-chats current-chat-id)) + [:dispatch [:navigate-back]])]})) (re-frame/reg-event-fx :chat/ensure-chats ensure-chats) diff --git a/src/status_im/contexts/chat/group_create/events.cljs b/src/status_im/contexts/chat/group_create/events.cljs new file mode 100644 index 0000000000..f5224d0afe --- /dev/null +++ b/src/status_im/contexts/chat/group_create/events.cljs @@ -0,0 +1,34 @@ +(ns status-im.contexts.chat.group-create.events + (:require [legacy.status-im.data-store.chats :as data-store.chats] + [oops.core :as oops] + [re-frame.core :as rf])) + +(rf/reg-event-fx :group-chat/create + (fn [{:keys [db]} [group-name color image]] + (let [selected-contacts (:group/selected-contacts db)] + {:json-rpc/call [{:method "wakuext_createGroupChatWithMembers" + :params [nil group-name (into [] selected-contacts)] + :js-response true + :on-success (fn [response] + (let [chat-id (-> (oops/oget response :chats) + first + (oops/oget :id))] + (rf/dispatch [:chat-updated response]) + (rf/dispatch [:group-chat/edit + {:chat-id chat-id + :group-name group-name + :color color + :image image}])))}]}))) + +(rf/reg-event-fx :group-chat/edit-success + (fn [{:keys [db]} [{:keys [chat-id name color image]}]] + (let [new-chat {:name name :color color :image image}] + {:db (update-in db [:chats chat-id] #(merge % new-chat))}))) + +(rf/reg-event-fx :group-chat/edit + (fn [_ [{:keys [chat-id group-name color image]}]] + {:json-rpc/call [{:method "chat_editChat" + :params ["" chat-id group-name (name color) image] + :js-response true + :on-success #(rf/dispatch [:group-chat/edit-success + (data-store.chats/<-rpc-js %)])}]})) diff --git a/src/status_im/contexts/chat/group_create/style.cljs b/src/status_im/contexts/chat/group_create/style.cljs new file mode 100644 index 0000000000..4fcf949756 --- /dev/null +++ b/src/status_im/contexts/chat/group_create/style.cljs @@ -0,0 +1,22 @@ +(ns status-im.contexts.chat.group-create.style + (:require [quo.foundations.colors :as colors])) + +(def avatar {:width 88 :margin-top 12 :margin-left 20}) + +(def hole + {:y (- 80 32) + :x (+ (- 80 32) 8) + :width 32 + :height 32 + :borderRadius 10}) + +(def camera {:position :absolute :right 0 :bottom 0}) + +(defn color-label + [theme] + {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme) + :padding-horizontal 20}) + +(def tags {:flex-direction :row :flex-wrap :wrap :padding-horizontal 20 :padding-top 12}) + +(def tag {:margin-right 8 :margin-bottom 8}) diff --git a/src/status_im/contexts/chat/group_create/view.cljs b/src/status_im/contexts/chat/group_create/view.cljs new file mode 100644 index 0000000000..0ace3ef2ce --- /dev/null +++ b/src/status_im/contexts/chat/group_create/view.cljs @@ -0,0 +1,132 @@ +(ns status-im.contexts.chat.group-create.view + (:require [clojure.string :as string] + [quo.core :as quo] + [quo.foundations.colors :as colors] + [quo.theme] + [react-native.core :as rn] + [status-im.common.floating-button-page.view :as floating-button-page] + [status-im.constants :as constants] + [status-im.contexts.chat.group-create.style :as style] + [status-im.contexts.profile.utils :as profile.utils] + [utils.debounce :as debounce] + utils.emojilib + [utils.i18n :as i18n] + [utils.re-frame :as rf] + [utils.responsiveness :as responsiveness])) + +(defn avatar + [{:keys [customization-color]}] + [rn/pressable {:style style/avatar} + ;;NOTE with hole-view group-avatar doesn't change it's background color + #_[hole-view/hole-view + {:holes [style/hole]}] + [quo/group-avatar + {:customization-color customization-color + :size :size-80}] + [quo/button + {:on-press (fn [] + #_(rf/dispatch + [:show-bottom-sheet + {:content (fn [] + [profile-picture-picker/view + {:update-profile-pic-callback on-change-profile-pic + :has-picture? has-picture?}]) + :theme :dark + :shell? true}])) + :container-style style/camera + :icon-only? true + :type :grey + :background :photo + :size 32} + :i/camera]]) + +(defn view + [] + (let [theme (quo.theme/use-theme-value) + {window-width :width} (rn/get-window) + profile (rf/sub [:profile/profile-with-image]) + contacts (rf/sub [:selected-group-contacts]) + contacts-count (count contacts) + default-value (rn/use-memo + (fn [] + (let [contact-string (string/join ", " + (map + profile.utils/displayed-name + contacts))] + (subs contact-string + 0 + (min (count contact-string) + constants/max-group-chat-name-length)))) + []) + [group-name set-group-name] (rn/use-state default-value) + [error-message + set-error-message] (rn/use-state nil) + group-name-empty? (not (and (string? group-name) (not-empty group-name))) + [group-color set-group-color] (rn/use-state (rand-nth colors/account-colors)) + create-group-on-press (rn/use-callback #(debounce/throttle-and-dispatch + [:group-chat/create group-name group-color] + 300) + [group-name group-color]) + back-on-press (rn/use-callback #(rf/dispatch [:navigate-back])) + on-change-text (rn/use-callback + (fn [text] + (if (boolean (re-find utils.emojilib/emoji-regex text)) + (set-error-message (i18n/label :t/are-not-allowed + {:check (i18n/label + :t/emojis)})) + (set-error-message nil)) + (set-group-name text)))] + [floating-button-page/view + {:customization-color group-color + :gradient-cover? true + :header-container-style {:margin-top 8} + :header [quo/page-nav + {:background :photo + :type :no-title + :icon-name :i/arrow-left + :on-press back-on-press}] + :footer [quo/button + {:customization-color group-color + :disabled? (boolean (or group-name-empty? error-message)) + :on-press create-group-on-press} + (i18n/label :t/create-group-chat)]} + [:<> + [avatar {:customization-color group-color}] + [quo/title-input + {:on-change-text on-change-text + :default-value default-value + :container-style {:padding-horizontal 20 :padding-top 12 :padding-bottom (if error-message 0 16)} + :placeholder (i18n/label :t/name-your-group) + :max-length constants/max-group-chat-name-length}] + (when error-message + [quo/info-message + {:type :error + :icon :i/info + :size :default + :style {:margin-top 8 :margin-left 20 :margin-bottom 16}} + error-message]) + [quo/divider-line] + [rn/view + {:style {:padding-vertical 7}} + [quo/text + {:size :paragraph-2 + :weight :medium + :style (style/color-label theme)} + (i18n/label :t/accent-colour)] + [quo/color-picker + {:default-selected group-color + :on-change set-group-color + :container-style {:padding-top 15 + :padding-bottom 9 + :padding-left (responsiveness/iphone-11-Pro-20-pixel-from-width + window-width)}}]] + [quo/divider-label + (i18n/label :t/n-m-people {:n (inc contacts-count) :m constants/max-group-chat-participants})] + [rn/view {:style style/tags} + (for [contact (conj contacts profile)] + ^{:key contact} + [quo/context-tag + {:container-style style/tag + :size 24 + :profile-picture (profile.utils/photo contact) + :full-name (profile.utils/displayed-name contact)}])]]])) diff --git a/src/status_im/contexts/chat/group_details/view.cljs b/src/status_im/contexts/chat/group_details/view.cljs index 510032c7eb..a04004b742 100644 --- a/src/status_im/contexts/chat/group_details/view.cljs +++ b/src/status_im/contexts/chat/group_details/view.cljs @@ -135,7 +135,7 @@ {:container-style style/actions-view :actions [{:accessibility-label :pinned-messages :label (i18n/label :t/pinned-messages) - :color color + :customization-color color :icon :i/pin :counter-value (count pinned-messages) :on-press (fn [] @@ -143,14 +143,14 @@ (rf/dispatch [:pin-message/show-pins-bottom-sheet chat-id]))} {:accessibility-label :toggle-mute - :color color + :customization-color color :icon (if muted :i/muted :i/activity-center) :label (i18n/label (if muted :unmute-group :mute-group)) :on-press #(rf/dispatch [:chat.ui/mute chat-id (not muted) (when-not muted constants/mute-till-unmuted)])} {:accessibility-label :manage-members - :color color + :customization-color color :icon :i/add-user :label (i18n/label (if admin? :t/manage-members :t/add-members)) :counter-value (count contacts) diff --git a/src/status_im/contexts/chat/home/new_chat/view.cljs b/src/status_im/contexts/chat/home/new_chat/view.cljs index ff14da6fc9..40dfbad60f 100644 --- a/src/status_im/contexts/chat/home/new_chat/view.cljs +++ b/src/status_im/contexts/chat/home/new_chat/view.cljs @@ -148,7 +148,7 @@ :on-press (fn [] (if one-contact-selected? (rf/dispatch [:chat.ui/start-chat public-key]) - (rf/dispatch [:navigate-to :new-group])))} + (rf/dispatch [:open-modal :group-create])))} (if one-contact-selected? (i18n/label :t/chat-with {:selected-user primary-name}) (i18n/label :t/setup-group-chat))]])])) diff --git a/src/status_im/contexts/preview/quo/preview.cljs b/src/status_im/contexts/preview/quo/preview.cljs index 0819b38e2e..ea0745bd43 100644 --- a/src/status_im/contexts/preview/quo/preview.cljs +++ b/src/status_im/contexts/preview/quo/preview.cljs @@ -8,6 +8,7 @@ [quo.theme :as quo.theme] [re-frame.core :as rf] [react-native.blur :as blur] + [react-native.clipboard :as clipboard] [react-native.core :as rn] [react-native.safe-area :as safe-area] [reagent.core :as reagent] @@ -340,29 +341,38 @@ {:style (style/panel-basic) :shows-vertical-scroll-indicator false :content-container-style (when full-screen? {:flex 1})} - [rn/pressable - {:style (when full-screen? {:flex 1}) - :on-press rn/dismiss-keyboard!} - (when descriptor - [rn/view {:style style/customizer-container} - [customizer state descriptor]]) - (if blur? - [rn/view {:style (merge style/component-container component-container-style)} - (into [blur-view - {:theme theme - :show-blur-background? show-blur-background? - :height blur-height - :style (merge {:width "100%" - :flex-grow 1} - (when-not show-blur-background? - {:padding-horizontal 0 - :top 0}) - blur-container-style) - :blur-view-props (merge {:blur-type theme} - blur-view-props)}] - children)] - (into [rn/view {:style (merge style/component-container component-container-style)}] - children))]]])) + [:<> + [rn/pressable + {:style (when full-screen? {:flex 1}) + :on-press rn/dismiss-keyboard!} + (when descriptor + [rn/view {:style style/customizer-container} + [customizer state descriptor]]) + (if blur? + [rn/view {:style (merge style/component-container component-container-style)} + (into [blur-view + {:theme theme + :show-blur-background? show-blur-background? + :height blur-height + :style (merge {:width "100%" + :flex-grow 1} + (when-not show-blur-background? + {:padding-horizontal 0 + :top 0}) + blur-container-style) + :blur-view-props (merge {:blur-type theme} + blur-view-props)}] + children)] + (into [rn/view {:style (merge style/component-container component-container-style)}] + children))] + (when state + (let [decr-state (if descriptor (select-keys @state (mapv :key (flatten descriptor))) @state) + state-str (with-out-str (cljs.pprint/pprint decr-state))] + [rn/view {:style {:margin 50}} + [quo/text {:style {:margin-bottom 10}} "State map (click on map to copy)"] + [rn/pressable + {:on-press #(clipboard/set-string state-str)} + [quo/text state-str]]]))]]])) (defn preview-container [& args] diff --git a/src/status_im/contexts/wallet/create_account/view.cljs b/src/status_im/contexts/wallet/create_account/view.cljs index 524113eb76..fa0a461716 100644 --- a/src/status_im/contexts/wallet/create_account/view.cljs +++ b/src/status_im/contexts/wallet/create_account/view.cljs @@ -16,7 +16,7 @@ [status-im.contexts.wallet.sheets.account-origin.view :as account-origin] [utils.i18n :as i18n] [utils.re-frame :as rf] - [utils.responsiveness :refer [iphone-11-Pro-20-pixel-from-width]] + [utils.responsiveness :as responsiveness] [utils.security.core :as security] [utils.string])) @@ -143,7 +143,8 @@ {:default-selected @account-color :on-change #(reset! account-color %) :container-style {:padding-vertical 12 - :padding-left (iphone-11-Pro-20-pixel-from-width window-width)}}]] + :padding-left (responsiveness/iphone-11-Pro-20-pixel-from-width + window-width)}}]] [quo/divider-line] [quo/category {:list-type :settings diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 10effc27e0..ec6459d4ca 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -5,6 +5,7 @@ [status-im.common.emoji-picker.view :as emoji-picker] [status-im.common.lightbox.view :as lightbox] [status-im.config :as config] + [status-im.contexts.chat.group-create.view :as group-create] [status-im.contexts.chat.group-details.view :as group-details] [status-im.contexts.chat.home.add-new-contact.scan.scan-profile-qr-page :as scan-profile-qr-page] [status-im.contexts.chat.home.add-new-contact.views :as add-new-contact] @@ -116,6 +117,11 @@ :options {:sheet? true} :component group-details/add-manage-members} + {:name :group-create + :options {:sheet? true + :skip-background? true} + :component group-create/view} + {:name :community-requests-to-join :options {:sheet? true} :component join-menu/view} diff --git a/src/status_im/navigation/view.cljs b/src/status_im/navigation/view.cljs index d3bcbc3764..62b94ccba8 100644 --- a/src/status_im/navigation/view.cljs +++ b/src/status_im/navigation/view.cljs @@ -57,20 +57,21 @@ (reagent.core/reactify-component (fn [] - (let [screen-details (get (if js/goog.DEBUG - (get-screens) - screens) - (keyword screen-key)) - qualified-screen-details (get (if js/goog.DEBUG - (get-screens) - screens) - (keyword "screen" screen-key)) - {:keys [component options]} (or qualified-screen-details screen-details) - {:keys [insets sheet? theme]} options - user-theme (theme/get-theme) - alert-banners-top-margin (rf/sub [:alert-banners/top-margin]) - background-color (or (get-in options [:layout :backgroundColor]) - (when sheet? :transparent))] + (let [screen-details (get (if js/goog.DEBUG + (get-screens) + screens) + (keyword screen-key)) + qualified-screen-details (get (if js/goog.DEBUG + (get-screens) + screens) + (keyword "screen" screen-key)) + {:keys [component options]} (or qualified-screen-details screen-details) + {:keys [insets sheet? theme + skip-background?]} options + user-theme (theme/get-theme) + alert-banners-top-margin (rf/sub [:alert-banners/top-margin]) + background-color (or (get-in options [:layout :backgroundColor]) + (when sheet? :transparent))] ^{:key (str "root" screen-key @reloader/cnt)} [theme/provider {:theme (or theme user-theme)} [rn/view @@ -80,7 +81,7 @@ :alert-banners-top-margin alert-banners-top-margin))} [inactive] (if sheet? - [bottom-sheet-screen/view {:content component}] + [bottom-sheet-screen/view {:content component :skip-background? skip-background?}] [component])] (when js/goog.DEBUG [:<> diff --git a/src/utils/emojilib.cljs b/src/utils/emojilib.cljs index 1b86698815..c5f2e9ee2b 100644 --- a/src/utils/emojilib.cljs +++ b/src/utils/emojilib.cljs @@ -3,6 +3,9 @@ [goog.object :as object] utils.string)) +(def emoji-regex + #"(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])") + (def lib (.-lib emojis)) (defn get-char diff --git a/test/appium/views/chat_view.py b/test/appium/views/chat_view.py index f36c777bb8..c5fcadecc7 100644 --- a/test/appium/views/chat_view.py +++ b/test/appium/views/chat_view.py @@ -834,7 +834,7 @@ class ChatView(BaseView): self.edit_group_chat_name_button = Button(self.driver, accessibility_id="edit-button") self.edit_group_chat_name_edit_box = EditBox(self.driver, accessibility_id="new-chat-name") self.done_button = Button(self.driver, accessibility_id="done") - self.create_button = Button(self.driver, accessibility_id="create-group-chat-button") + self.create_group_chat_button = Button(self.driver, accessibility_id="Create group chat") ## Group invites self.group_invite_button = Button(self.driver, accessibility_id="invite-chat-button") self.group_invite_link_text = Text(self.driver, diff --git a/test/appium/views/home_view.py b/test/appium/views/home_view.py index 6cde0f88e7..a1678a8c52 100644 --- a/test/appium/views/home_view.py +++ b/test/appium/views/home_view.py @@ -442,8 +442,8 @@ class HomeView(BaseView): "User with the name '%s' is not in contacts list so can't create a group chat" % user_name) check_box.click_until_presence_of_element(chat.get_username_checkbox(user_name, state_on=True)) self.setup_chat_button.click() - chat.chat_name_editbox.send_keys(group_chat_name) - chat.create_button.click() + self.get_sign_in_view().profile_title_input.send_keys(group_chat_name) + chat.create_group_chat_button.click() self.driver.info("## Group chat %s is created successfully!" % group_chat_name, device=False) return chat diff --git a/test/appium/views/sign_in_view.py b/test/appium/views/sign_in_view.py index 6b30674e9e..fa1c90141b 100644 --- a/test/appium/views/sign_in_view.py +++ b/test/appium/views/sign_in_view.py @@ -187,7 +187,7 @@ class SignInView(BaseView): # New onboarding self.generate_keys_button = Button(self.driver, translation_id="lets-go") - self.profile_your_name_edit_box = EditBox(self.driver, accessibility_id="profile-title-input") + self.profile_title_input = EditBox(self.driver, accessibility_id="profile-title-input") self.profile_continue_button = Button(self.driver, accessibility_id="submit-create-profile-button") self.profile_password_edit_box = EditBox(self.driver, translation_id="password-creation-placeholder-1") self.profile_repeat_password_edit_box = EditBox(self.driver, translation_id="password-creation-placeholder-2") @@ -213,7 +213,7 @@ class SignInView(BaseView): self.profile_confirm_password_button.click() def set_profile(self, username: str, set_image=False): - self.profile_your_name_edit_box.send_keys(username) + self.profile_title_input.send_keys(username) self.profile_continue_button.click_until_presence_of_element(self.profile_password_edit_box) if set_image: pass @@ -231,7 +231,7 @@ class SignInView(BaseView): self.show_profiles_button.click() self.plus_profiles_button.click() self.create_new_profile_button.click() - self.generate_keys_button.click_until_presence_of_element(self.profile_your_name_edit_box) + self.generate_keys_button.click_until_presence_of_element(self.profile_title_input) self.set_profile(username) self.set_password(password) if self.enable_biometric_maybe_later_button.is_element_displayed(10): @@ -270,7 +270,7 @@ class SignInView(BaseView): self.create_new_profile_button.click() self.use_recovery_phrase_button.click() self.passphrase_edit_box.send_keys(passphrase) - self.continue_button.click_until_presence_of_element(self.profile_your_name_edit_box) + self.continue_button.click_until_presence_of_element(self.profile_title_input) self.set_profile(username, set_image) self.set_password(password) if self.enable_biometric_maybe_later_button.is_element_displayed(10): diff --git a/translations/en.json b/translations/en.json index 298368e6d6..e80a712544 100644 --- a/translations/en.json +++ b/translations/en.json @@ -312,6 +312,7 @@ "create-a-pin": "Create a 6-digit passcode", "create-a-puk": "Create a 12-digit PUK", "create-group-chat": "Create group chat", + "name-your-group": "Name your group", "create-multiaccount": "Generate keys", "create-new-key": "Get new keys", "create-pin": "Create 6-digit passcode", @@ -2411,6 +2412,7 @@ "no-other-accounts": "No other accounts", "here-is-a-cat-in-a-box-instead": "Here’s a cat in a box instead", "accounts-count": "{{count}} accounts", + "n-m-people": "{{n}}/{{m}} people", "enter-eth": "Enter any ETH address or ENS name.", "eth-or-ens": "ETH address or ENS name.", "type-pairing-code": "Type or paste pairing code",