diff --git a/resources/images/icons2/120x120/no-contacts@2x.png b/resources/images/icons2/120x120/no-contacts@2x.png new file mode 100644 index 0000000000..42b0454dab Binary files /dev/null and b/resources/images/icons2/120x120/no-contacts@2x.png differ diff --git a/resources/images/icons2/120x120/no-contacts@3x.png b/resources/images/icons2/120x120/no-contacts@3x.png new file mode 100644 index 0000000000..8e5c8f881d Binary files /dev/null and b/resources/images/icons2/120x120/no-contacts@3x.png differ diff --git a/src/quo2/components/icons/icons.clj b/src/quo2/components/icons/icons.clj index 09eb83d22b..730961da7c 100644 --- a/src/quo2/components/icons/icons.clj +++ b/src/quo2/components/icons/icons.clj @@ -41,4 +41,5 @@ (get-icons 16) (get-icons 20) (get-icons 24) - (get-icons 32))) + (get-icons 32) + (get-icons 120))) diff --git a/src/quo2/components/list_items/menu_item.cljs b/src/quo2/components/list_items/menu_item.cljs index a269a1e17e..670a4b7142 100644 --- a/src/quo2/components/list_items/menu_item.cljs +++ b/src/quo2/components/list_items/menu_item.cljs @@ -15,22 +15,24 @@ :text-color (theme-colors colors/danger-50 colors/danger-60)})) (defn menu-item - [{:keys [type title accessibility-label icon on-press] + [{:keys [type title accessibility-label icon on-press style-props subtitle subtitle-color] :or {type :main}}] (let [{:keys [icon-color text-color background]} (themes type)] [rn/touchable-opacity (merge {:accessibility-label accessibility-label - :style {:background-color background - :height 48 - :flex-direction :row - :align-items :center}} + :style (merge style-props + {:background-color background + :height 48 + :flex-direction :row + :align-items :center})} (when on-press {:on-press on-press})) [rn/view {:style {:flex-direction :row :flex-grow 0 :flex-shrink 1 - :padding-horizontal 20}} + :padding-horizontal 20 + :align-items :center}} [rn/view {:style {:width 20 :height 20 @@ -38,10 +40,19 @@ :justify-content :center :margin-right 12}} [icons/icon icon {:color icon-color}]] - [text/text - {:weight :medium - :style {:color text-color} - :ellipsize-mode :tail - :number-of-lines 1 - :size :paragraph-1} - title]]])) + [rn/view + [text/text + {:weight :medium + :style {:color text-color} + :ellipsize-mode :tail + :number-of-lines 1 + :size :paragraph-1} + title] + (when subtitle + [text/text + {:weight :medium + :style {:color subtitle-color} + :ellipsize-mode :tail + :number-of-lines 1 + :size :paragraph-1} + subtitle])]]])) diff --git a/src/quo2/components/selectors/selectors.cljs b/src/quo2/components/selectors/selectors.cljs index ae1ccc8f5a..43bef3b4d5 100644 --- a/src/quo2/components/selectors/selectors.cljs +++ b/src/quo2/components/selectors/selectors.cljs @@ -2,26 +2,8 @@ (:require [quo2.components.icon :as icons] [quo2.foundations.colors :as colors] [react-native.core :as rn] - [reagent.core :as reagent])) - -(defn- get-color - [checked? disabled? blurred-background?] - (cond - checked? - (colors/custom-color-by-theme - :primary - 50 - 60 - (when disabled? 30) - (when disabled? 30)) - blurred-background? - (colors/theme-colors - (colors/alpha colors/neutral-80 (if disabled? 0.05 0.1)) - (colors/alpha colors/white (if disabled? 0.05 0.1))) - :else - (colors/theme-colors - (colors/alpha colors/neutral-20 (if disabled? 0.4 1)) - (colors/alpha colors/neutral-70 (if disabled? 0.3 1))))) + [reagent.core :as reagent] + [quo2.components.selectors.styles :as style])) (defn- handle-press [disabled? on-change checked?] @@ -69,44 +51,29 @@ (defn checkbox [{:keys [default-checked?]}] (let [checked? (reagent/atom (or default-checked? false))] - (fn [{:keys [on-change disabled? blurred-background? container-style accessibility-label]}] - [rn/touchable-without-feedback - {:accessibility-label accessibility-label - :on-press (handle-press disabled? on-change checked?)} - [rn/view - {:style (merge - container-style - {:height 20 - :width 20})} - [rn/view - {:style {:flex 1 - :border-radius 6 - :border-width (if @checked? 0 1) - :background-color (cond - @checked? - (get-color @checked? disabled? blurred-background?) - blurred-background? - (colors/theme-colors - colors/white-opa-5 - colors/white-opa-10) - :else - (colors/theme-colors - colors/white - colors/neutral-80-opa-40)) - :border-color (if @checked? - :none - (get-color @checked? disabled? blurred-background?))} - :accessibility-label (str "checkbox-" (if @checked? "on" "off")) - :accessibility-role :checkbox - :testID "checkbox-component"} - (when @checked? - [rn/view - {:style - {:height 20 - :width 20}} - [icons/icon :i/check-small - {:size 20 - :color colors/white}]])]]]))) + @(reagent/track + (fn [{:keys [on-change disabled? blurred-background? container-style]}] + [rn/touchable-without-feedback + {:on-press (handle-press disabled? on-change checked?)} + [rn/view + {:style (merge + container-style + {:height 20 + :width 20})} + [rn/view + {:style (style/checkbox-toggle checked? disabled? blurred-background?) + :accessibility-label (str "checkbox-" (if @checked? "on" "off")) + :accessibility-role :checkbox + :testID "checkbox-component"} + (when @checked? + [rn/view + {:style + {:height 20 + :width 20}} + [icons/icon :i/check-small + {:size 20 + :color colors/white}]])]]]) + checked?))) (defn radio [{:keys [default-checked?]}] @@ -121,7 +88,9 @@ :width 20 :border-radius 20 :border-width 1 - :border-color (get-color @checked? disabled? blurred-background?) + :border-color (style/get-color @checked? + disabled? + blurred-background?) :background-color (when-not blurred-background? (colors/theme-colors colors/white (colors/alpha colors/neutral-80 @@ -135,7 +104,7 @@ {:margin-left :auto :height 14 :width 14 - :background-color (when @checked? (get-color @checked? disabled? blurred-background?)) + :background-color (when @checked? (style/get-color @checked? disabled? blurred-background?)) :border-radius 20 :margin-right :auto :margin-top :auto @@ -153,7 +122,9 @@ {:height 20 :width 30 :border-radius 20 - :background-color (get-color @checked? disabled? blurred-background?)}) + :background-color (style/get-color @checked? + disabled? + blurred-background?)}) :accessibility-label (str "toggle-" (if @checked? "on" "off")) :accessibility-role :checkbox :testID "toggle-component"} diff --git a/src/quo2/components/selectors/styles.cljs b/src/quo2/components/selectors/styles.cljs new file mode 100644 index 0000000000..6202a49823 --- /dev/null +++ b/src/quo2/components/selectors/styles.cljs @@ -0,0 +1,41 @@ +(ns quo2.components.selectors.styles + (:require [quo2.foundations.colors :as colors])) + +(defn get-color + [checked? disabled? blurred-background?] + (cond + checked? + (colors/custom-color-by-theme + :primary + 50 + 60 + (when disabled? 30) + (when disabled? 30)) + blurred-background? + (colors/theme-colors + (colors/alpha colors/neutral-80 (if disabled? 0.05 0.1)) + (colors/alpha colors/white (if disabled? 0.05 0.1))) + :else + (colors/theme-colors + (colors/alpha colors/neutral-20 (if disabled? 0.4 1)) + (colors/alpha colors/neutral-70 (if disabled? 0.3 1))))) + +(defn checkbox-toggle + [checked? disabled? blurred-background?] + {:flex 1 + :border-radius 6 + :border-width (if @checked? 0 1) + :background-color (cond + @checked? + (get-color @checked? disabled? blurred-background?) + blurred-background? + (colors/theme-colors + colors/white-opa-5 + colors/white-opa-10) + :else + (colors/theme-colors + colors/white + colors/neutral-80-opa-40)) + :border-color (if @checked? + :none + (get-color @checked? disabled? blurred-background?))}) \ No newline at end of file diff --git a/src/status_im/ui/components/search_input/view.cljs b/src/status_im/ui/components/search_input/view.cljs index 9b0e5bccef..98dd9535c3 100644 --- a/src/status_im/ui/components/search_input/view.cljs +++ b/src/status_im/ui/components/search_input/view.cljs @@ -93,4 +93,4 @@ (let [^js native-event (.-nativeEvent ^js e) text (.-text native-event)] (when on-change - (on-change text))))}]))) \ No newline at end of file + (on-change text))))}]))) diff --git a/src/status_im/ui/components/topbar.cljs b/src/status_im/ui/components/topbar.cljs index 20f5fc8358..46b334c3ea 100644 --- a/src/status_im/ui/components/topbar.cljs +++ b/src/status_im/ui/components/topbar.cljs @@ -1,15 +1,15 @@ (ns status-im.ui.components.topbar - (:require [quo.core :as quo] - [quo2.foundations.colors :as quo2.colors] - [re-frame.core :as re-frame])) + (:require [re-frame.core :as re-frame] + [quo.core :as quo] + [quo2.foundations.colors :as quo2.colors])) (def default-button-width 48) (defn default-navigation [modal? {:keys [on-press label icon]}] - (cond-> {:icon (if modal? :main-icons/close :main-icons/arrow-left) + (cond-> {:icon (if modal? :i/close :i/arrow-left) :accessibility-label :back-button - :on-press #(re-frame/dispatch [:navigate-back])} + :on-press #(re-frame/dispatch [:navigate-back :bottom-sheet/hide])} on-press (assoc :on-press on-press) @@ -46,4 +46,4 @@ {:right-accessories right-accessories}) (when new-ui? {:background (quo2.colors/theme-colors quo2.colors/neutral-5 - quo2.colors/neutral-95)}))])])) \ No newline at end of file + quo2.colors/neutral-95)}))])])) diff --git a/src/status_im/ui/screens/bottom_sheets/views.cljs b/src/status_im/ui/screens/bottom_sheets/views.cljs index 408a75b5f6..1a9e01ef74 100644 --- a/src/status_im/ui/screens/bottom_sheets/views.cljs +++ b/src/status_im/ui/screens/bottom_sheets/views.cljs @@ -27,6 +27,12 @@ (= view :add-new) (merge home.sheet/add-new) + (= view :new-chat-bottom-sheet) + (merge home.sheet/new-chat-bottom-sheet-comp) + + (= view :start-a-new-chat) + (merge home.sheet/start-a-new-chat) + (= view :keycard.login/more) (merge keycard/more-sheet) diff --git a/src/status_im/ui/screens/group/styles.cljs b/src/status_im/ui/screens/group/styles.cljs index 988a2d0f34..b92c8e8462 100644 --- a/src/status_im/ui/screens/group/styles.cljs +++ b/src/status_im/ui/screens/group/styles.cljs @@ -12,13 +12,6 @@ :text-align :center :color colors/gray}) -(def toolbar-header-container - {:align-items :center}) - -(defn toolbar-sub-header - [] - {:color colors/gray}) - (def no-contacts {:flex 1 :justify-content :center diff --git a/src/status_im/ui/screens/home/sheet/styles.cljs b/src/status_im/ui/screens/home/sheet/styles.cljs new file mode 100644 index 0000000000..6fc7cc7201 --- /dev/null +++ b/src/status_im/ui/screens/home/sheet/styles.cljs @@ -0,0 +1,7 @@ +(ns status-im.ui.screens.home.sheet.styles) +(def add-new-view-wrapper + {:style {:flex-direction :row + :padding-left 16 + :padding-right 8 + :justify-content :space-between + :align-items :center}}) \ No newline at end of file diff --git a/src/status_im/ui/screens/home/sheet/views.cljs b/src/status_im/ui/screens/home/sheet/views.cljs index 5775232860..36bf6e35e4 100644 --- a/src/status_im/ui/screens/home/sheet/views.cljs +++ b/src/status_im/ui/screens/home/sheet/views.cljs @@ -1,26 +1,25 @@ (ns status-im.ui.screens.home.sheet.views (:require [quo.core :as quo] - [re-frame.core :as re-frame] + [quo2.foundations.colors :as colors] + [re-frame.core :as rf] [status-im.i18n.i18n :as i18n] [status-im.qr-scanner.core :as qr-scanner] [status-im.ui.components.invite.views :as invite] - [status-im.ui.components.react :as react] - [status-im.utils.config :as config])) + [status-im.ui.components.react :as rn] + [status-im.ui2.screens.chat.components.new-chat.view :as new-chat-aio] + [status-im.utils.config :as config] + [quo2.core :as quo2] + [status-im.ui.screens.home.sheet.styles :as style])) (defn hide-sheet-and-dispatch [event] - (re-frame/dispatch [:bottom-sheet/hide]) - (re-frame/dispatch event)) + (rf/dispatch [:bottom-sheet/hide]) + (rf/dispatch event)) (defn add-new-view [] - [react/view - [react/view - {:style {:flex-direction :row - :padding-left 16 - :padding-right 8 - :justify-content :space-between - :align-items :center}} + [rn/view + [rn/view style/add-new-view-wrapper [quo/text {:size :large :weight :bold} @@ -52,7 +51,7 @@ :accessibility-label :join-public-chat-button :icon :main-icons/public-chat :on-press #(hide-sheet-and-dispatch [:open-modal :new-public-chat])}] - (when @(re-frame/subscribe [:communities/enabled?]) + (when @(rf/subscribe [:communities/enabled?]) [quo/list-item {:theme :accent :title (i18n/label :t/communities-alpha) @@ -62,5 +61,44 @@ [invite/list-item {:accessibility-label :chats-menu-invite-friends-button}]]) +(defn new-chat-bottom-sheet + [] + [rn/view + [quo2/menu-item + {:theme :main + :title (i18n/label :t/new-chat) + :icon-bg-color :transparent + :container-padding-vertical 12 + :title-column-style {:margin-left 2} + :icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40) + :accessibility-label :start-a-new-chat + :icon :i/new-message + :on-press #(hide-sheet-and-dispatch [:bottom-sheet/show-sheet + :start-a-new-chat])}] + [quo2/menu-item + {:theme :main + :title (i18n/label :t/add-a-contact) + :icon-bg-color :transparent + :icon-container-style {:padding-horizontal 0} + :container-padding-horizontal {:padding-horizontal 4} + :style-props {:margin-top 18 + :margin-bottom 9} + :container-padding-vertical 12 + :title-column-style {:margin-left 2} + :icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40) + :accessibility-label :add-a-contact + :subtitle (i18n/label :t/enter-a-chat-key) + :subtitle-color colors/neutral-50 + :icon :i/add-user + :on-press #(hide-sheet-and-dispatch [:open-modal :new-contact])}]]) + + +(def new-chat-bottom-sheet-comp + {:content new-chat-bottom-sheet}) + +;; Deprecated (def add-new {:content add-new-view}) + +(def start-a-new-chat + {:content new-chat-aio/contact-selection-list}) diff --git a/src/status_im/ui/screens/home/views.cljs b/src/status_im/ui/screens/home/views.cljs index fb013faf4f..646a0a6227 100644 --- a/src/status_im/ui/screens/home/views.cljs +++ b/src/status_im/ui/screens/home/views.cljs @@ -263,7 +263,7 @@ (views/letsubs [logging-in? [:multiaccounts/login]] [components.plus-button/plus-button-old {:on-press (when-not logging-in? - #(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}])) + #(re-frame/dispatch [:bottom-sheet/show-sheet :start-a-new-chat {}])) :loading logging-in? :accessibility-label :new-chat-button}])) @@ -272,7 +272,7 @@ (views/letsubs [logging-in? [:multiaccounts/login]] [components.plus-button/plus-button-old {:on-press (when-not logging-in? - #(re-frame/dispatch [:bottom-sheet/show-sheet :add-new {}])) + #(re-frame/dispatch [:bottom-sheet/show-sheet :start-a-new-chat {}])) :loading logging-in? :accessibility-label :new-chat-button}])) diff --git a/src/status_im/ui/screens/screens.cljs b/src/status_im/ui/screens/screens.cljs index e8edea8a29..bcb14e509e 100644 --- a/src/status_im/ui/screens/screens.cljs +++ b/src/status_im/ui/screens/screens.cljs @@ -108,7 +108,8 @@ [status-im.ui.screens.wallet.swap.views :as wallet.swap] [status-im.ui.screens.wallet.transactions.views :as wallet-transactions] [status-im.ui2.screens.chat.group-details.view :as group-details] - [status-im.ui2.screens.chat.photo-selector.view :as photo-selector])) + [status-im.ui2.screens.chat.photo-selector.view :as photo-selector] + [status-im.ui2.screens.chat.components.new-chat.view :as new-chat-aio])) (defn right-button-options [id icon] @@ -587,11 +588,17 @@ :options {:topBar {:visible false}} :component contact/nickname} - ;[Group chat] Edit group chat name - {:name :edit-group-chat-name + {:name :new-chat-aio + :on-focus [::new-chat.events/new-chat-focus] + ;;TODO accessories + :options {:topBar {:visible false}} + :component new-chat-aio/contact-selection-list} + + ;[Chat] New Public chat + {:name :new-public-chat :insets {:bottom true} - :options {:topBar {:title {:text (i18n/label :t/edit-group)}}} - :component group-chat/edit-group-chat-name} + :options {:topBar {:title {:text (i18n/label :t/new-public-group-chat)}}} + :component new-public-chat/new-public-chat} ;[Group chat] Add participants {:name :add-participants-toggle-list diff --git a/src/status_im/ui2/screens/chat/components/new_chat/styles.cljs b/src/status_im/ui2/screens/chat/components/new_chat/styles.cljs new file mode 100644 index 0000000000..1fb851749f --- /dev/null +++ b/src/status_im/ui2/screens/chat/components/new_chat/styles.cljs @@ -0,0 +1,16 @@ +(ns status-im.ui2.screens.chat.components.new-chat.styles) +(def contact-selection-heading + {:style {:flex-direction :row + :justify-content :space-between + :align-items :flex-end + :padding-horizontal 20 + :margin-bottom 16}}) + +(def contact-selection-close + {:width 32 + :height 32 + :border-radius 10 + :margin-left 20 + :margin-bottom 36 + :justify-content :center + :align-items :center}) \ No newline at end of file diff --git a/src/status_im/ui2/screens/chat/components/new_chat/view.cljs b/src/status_im/ui2/screens/chat/components/new_chat/view.cljs new file mode 100644 index 0000000000..fbb142710d --- /dev/null +++ b/src/status_im/ui2/screens/chat/components/new_chat/view.cljs @@ -0,0 +1,119 @@ +(ns status-im.ui2.screens.chat.components.new-chat.view + (:require [quo2.components.buttons.button :as button] + [quo2.core :as quo2] + [quo2.foundations.colors :as quo2.colors] + [re-frame.core :as re-frame] + [reagent.core :as reagent] + [status-im.constants :as constants] + [status-im.i18n.i18n :as i18n] + [status-im.ui.components.react :as react] + [utils.re-frame :as rf] + [status-im.ui.screens.chat.sheets :refer [hide-sheet-and-dispatch]] + [status-im.ui.components.toolbar :as toolbar] + [status-im.ui2.screens.common.contact-list.view :as contact-list] + [quo2.components.markdown.text :as text] + [status-im.ui.components.invite.events :as invite.events] + [status-im.ui2.screens.chat.components.new-chat.styles :as style])) + +(defn- on-toggle + [allow-new-users? checked? public-key] + (cond + checked? + (re-frame/dispatch [:deselect-contact public-key allow-new-users?]) + ;; Only allow new users if not reached the maximum + (and (not checked?) + allow-new-users?) + (re-frame/dispatch [:select-contact public-key allow-new-users?]))) + +(defn- no-contacts-view + [] + [react/view + {:style {:justify-content :center + :align-items :center + :margin-top 120}} + [quo2/icon :i/no-contacts + {:size 120 + :no-color true}] + [text/text + {:weight :semi-bold + :size :paragraph-1 + :style {:margin-bottom 2 + :margin-top 20}} + "You have no contacts"] + [text/text + {:weight :regular + :size :label + :style {:margin-bottom 20}} + "Invite your friends and family to Status"] + [quo2/button + {:type :primary + :style {:margin-bottom 12} + :on-press #(rf/dispatch [::invite.events/share-link nil])} + "Invite friends"] + [quo2/button + {:type :grey + :on-press #(hide-sheet-and-dispatch [:open-modal :new-contact])} + "Add a contact"]]) + +(defn contact-selection-list + [] + (let [contacts (rf/sub + [:contacts/sorted-and-grouped-by-first-letter]) + selected-contacts-count (rf/sub [:selected-contacts-count]) + window-height (rf/sub [:dimensions/window-height]) + one-contact-selected? (= selected-contacts-count 1) + contacts-selected? (pos? selected-contacts-count) + {:keys [names public-key]} (-> contacts first :data first) + added? (reagent/atom '()) + {:keys [nickname ens-name three-words-name]} names + first-username (or ens-name nickname three-words-name) + no-contacts? (empty? contacts)] + [react/view {:style {:height (* window-height 0.95)}} + [quo2/button + {:type :grey + :icon true + :on-press #(rf/dispatch [:bottom-sheet/hide]) + :style style/contact-selection-close + :override-background-color (quo2.colors/theme-colors quo2.colors/neutral-10 + quo2.colors/neutral-90)} + :i/close] + [react/view style/contact-selection-heading + [quo2/text + {:weight :semi-bold + :size :heading-1 + :style {:color (quo2.colors/theme-colors quo2.colors/neutral-100 quo2.colors/white)}} + (i18n/label :t/new-chat)] + (when-not no-contacts? + [quo2/text + {:size :paragraph-2 + :weight :regular + :style {:color (quo2.colors/theme-colors quo2.colors/neutral-40 quo2.colors/neutral-50)}} + (i18n/label :t/selected-count-from-max + {:selected (inc selected-contacts-count) + :max constants/max-group-chat-participants})])] + [react/view + {:style {:height 430 + :margin-bottom -20}} + (if no-contacts? + [no-contacts-view] + [contact-list/contact-list + {:icon :check + :group nil + :added? added? + :search? false + :start-a-new-chat? true + :on-toggle on-toggle}])] + (when contacts-selected? + [toolbar/toolbar + {:show-border? false + :center [button/button + {:type :primary + :accessibility-label :next-button + :on-press #(do + (if one-contact-selected? + (hide-sheet-and-dispatch [:chat.ui/start-chat + public-key]) + (hide-sheet-and-dispatch [:navigate-to :new-group])))} + (if one-contact-selected? + (i18n/label :t/chat-with {:selected-user first-username}) + (i18n/label :t/setup-group-chat))]}])])) diff --git a/src/status_im/ui2/screens/common/contact_list/view.cljs b/src/status_im/ui2/screens/common/contact_list/view.cljs index f67b783428..6e5b4eee69 100644 --- a/src/status_im/ui2/screens/common/contact_list/view.cljs +++ b/src/status_im/ui2/screens/common/contact_list/view.cljs @@ -9,8 +9,10 @@ [quo/divider-label {:label title}]) (defn contact-list - [data] - (let [contacts (rf/sub [:contacts/filtered-active-sections])] + [{:keys [start-a-new-chat?] :as data}] + (let [contacts (if start-a-new-chat? + (rf/sub [:contacts/sorted-and-grouped-by-first-letter]) + (rf/sub [:contacts/filtered-active-sections]))] [rn/section-list {:key-fn :title :sticky-section-headers-enabled false diff --git a/src/status_im2/common/contact_list_item/view.cljs b/src/status_im2/common/contact_list_item/view.cljs index 357925b390..60558169c1 100644 --- a/src/status_im2/common/contact_list_item/view.cljs +++ b/src/status_im2/common/contact_list_item/view.cljs @@ -3,6 +3,7 @@ [quo2.foundations.colors :as colors] [react-native.core :as rn] [react-native.platform :as platform] + [reagent.core :as reagent] [status-im2.common.home.actions.view :as actions] [status-im2.contexts.chat.home.chat-list-item.style :as style] [utils.address :as utils.address] @@ -19,38 +20,53 @@ (rf/dispatch [:search/home-filter-changed nil])))) (defn action-icon - [{:keys [public-key] :as item} {:keys [icon group added] :as extra-data}] + [{:keys [public-key] :as item} {:keys [icon start-a-new-chat? group added] :as extra-data} + user-selected? on-toggle] (let [{:keys [contacts]} group - member? (contains? contacts public-key)] + member? (contains? contacts public-key) + checked? (reagent/atom (if start-a-new-chat? + user-selected? + member?))] [rn/touchable-opacity {:on-press #(rf/dispatch [:bottom-sheet/show-sheet {:content (fn [] [actions/actions item extra-data])}]) :style {:position :absolute :right 20}} (if (= icon :options) - [quo/icon :i/options {:size 20 :color (colors/theme-colors colors/neutral-50 colors/neutral-40)}] - [quo/checkbox - {:default-checked? member? - :on-change (fn [selected] - (if selected - (swap! added conj public-key) - (reset! added (remove #(= % public-key) @added))))}])])) + [quo/icon :i/options + {:size 20 + :color (colors/theme-colors colors/neutral-50 colors/neutral-40)}] + @(reagent/track! + (fn [] + [quo/checkbox + {:default-checked? @checked? + :on-change (fn [selected] + (if start-a-new-chat? + (on-toggle true @checked? public-key) + (if selected + (swap! added conj public-key) + (reset! added (remove #(= % public-key) @added)))))}]) + checked?))])) (defn contact-list-item - [item _ _ extra-data] + [item _ _ {:keys [group start-a-new-chat? on-toggle] :as extra-data}] (let [{:keys [public-key ens-verified added? images]} item display-name (first (rf/sub [:contacts/contact-two-names-by-identity public-key])) photo-path (when (seq images) (rf/sub [:chats/photo-path public-key])) - current-pk (rf/sub [:multiaccount/public-key])] + current-pk (rf/sub [:multiaccount/public-key]) + user-selected? (rf/sub [:is-contact-selected? public-key])] [rn/touchable-opacity (merge {:style (style/container) :active-opacity 1 - :on-press #(open-chat public-key) - :on-long-press #(rf/dispatch [:bottom-sheet/show-sheet - {:content (fn [] [actions/actions item extra-data])}])}) + :on-press #(if start-a-new-chat? + (on-toggle true user-selected? public-key) + (open-chat public-key)) + :on-long-press #(when (some? group) + (rf/dispatch [:bottom-sheet/show-sheet + {:content (fn [] [actions/actions item extra-data])}]))}) [quo/user-avatar {:full-name display-name :profile-picture photo-path @@ -62,11 +78,17 @@ [rn/view {:style {:flex-direction :row}} [quo/text {:weight :semi-bold} display-name] (if ens-verified - [rn/view {:style {:margin-left 5 :margin-top 4}} + [rn/view + {:style {:margin-left 5 + :margin-top 4}} [quo/icon :i/verified - {:no-color true :size 12 :color (colors/theme-colors colors/success-50 colors/success-60)}]] + {:no-color true + :size 12 + :color (colors/theme-colors colors/success-50 colors/success-60)}]] (when added? - [rn/view {:style {:margin-left 5 :margin-top 4}} + [rn/view + {:style {:margin-left 5 + :margin-top 4}} [quo/icon :i/contact {:no-color true :size 12 @@ -76,4 +98,4 @@ :style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}} (utils.address/get-shortened-address public-key)]] (when-not (= current-pk public-key) - [action-icon item extra-data])])) + [:f> action-icon item extra-data user-selected? on-toggle])])) diff --git a/src/status_im2/contexts/chat/home/view.cljs b/src/status_im2/contexts/chat/home/view.cljs index ff1992621a..63fd2fe9aa 100644 --- a/src/status_im2/contexts/chat/home/view.cljs +++ b/src/status_im2/contexts/chat/home/view.cljs @@ -96,6 +96,6 @@ [common.home/top-nav {:type :default}] [common.home/title-column {:label (i18n/label :t/messages) - :handler #(rf/dispatch [:bottom-sheet/show-sheet :add-new {}]) + :handler #(rf/dispatch [:bottom-sheet/show-sheet :new-chat-bottom-sheet {}]) :accessibility-label :new-chat-button}] [tabs]]) diff --git a/src/status_im2/subs/contact.cljs b/src/status_im2/subs/contact.cljs index eb5c8b027c..ba3430184c 100644 --- a/src/status_im2/subs/contact.cljs +++ b/src/status_im2/subs/contact.cljs @@ -7,7 +7,8 @@ [status-im.multiaccounts.core :as multiaccounts] [status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils] [status-im.utils.gfycat.core :as gfycat] - [status-im.utils.image-server :as image-server])) + [status-im.utils.image-server :as image-server] + [status-im.constants :as constants])) (re-frame/reg-sub ::query-current-chat-contacts @@ -91,6 +92,23 @@ sort vals))) +(re-frame/reg-sub + :contacts/sorted-and-grouped-by-first-letter + :<- [:contacts/active] + :<- [:selected-contacts-count] + (fn [[contacts selected-contacts-count]] + (->> contacts + (filter :mutual?) + (map #(assoc % + :allow-new-users? + (< selected-contacts-count + (dec constants/max-group-chat-participants)))) + (group-by (comp (fnil string/upper-case "") first :alias)) + (sort-by (fn [[title]] title)) + (map (fn [[title data]] + {:title title + :data data}))))) + (re-frame/reg-sub :contacts/sorted-contacts :<- [:contacts/active] diff --git a/translations/en.json b/translations/en.json index d478bcf9ed..d7cec06f1e 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1478,6 +1478,8 @@ "set-custom-fee": "Set custom fee", "not-enough-snt": "Not enough SNT", "add-new-contact": "Add new contact", + "add-a-contact": "Add a contact", + "enter-a-chat-key": "Enter a chat key or scan a QR", "you-dont-have-contacts": "You don’t have any contacts yet.", "set-max": "Set max", "continue-anyway": "Continue anyway", @@ -1915,5 +1917,11 @@ "instruction-after-qr-generated": "On your other device, navigate to the Syncing screen and select “Scan sync”", "show-existing-keys": "Show Existing Keys", "scan-sync-code": "Scan Sync Code", - "confirm-selection": "Confirm selection" + "confirm-selection": "Confirm selection", + "chat-with": "Chat with {{selected-user}}", + "setup-group-chat": "Setup group chat", + "search-contacts": "Search contacts", + "who-are-you-looking-for": "Who are you looking for ?", + "close-contact-search": "Close contact search", + "selected-count-from-max": "{{selected}}/{{max}}" }