feat: group details screen (3.3) (#14654)

* feat: group details screen (3)
This commit is contained in:
Omar Basem 2022-12-30 18:14:24 +04:00 committed by GitHub
parent 13e59635c7
commit b85eb4184a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 263 additions and 161 deletions

View File

@ -24,7 +24,9 @@
:align-items :center :align-items :center
:justify-content :center :justify-content :center
:border-radius (/ container-size 2) :border-radius (/ container-size 2)
:background-color (colors/custom-color-by-theme color 50 60)} ;:background-color (colors/custom-color-by-theme color 50 60) ; TODO: this is temporary only.
;Issue: https://github.com/status-im/status-mobile/issues/14566
:background-color color}
[icon/icon :i/group [icon/icon :i/group
{:size icon-size {:size icon-size
:color colors/white-opa-70}]]))) :color colors/white-opa-70}]])))

View File

@ -5,6 +5,26 @@
[reagent.core :as reagent] [reagent.core :as reagent]
[quo2.components.selectors.styles :as style])) [quo2.components.selectors.styles :as style]))
(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- handle-press (defn- handle-press
[disabled? on-change checked?] [disabled? on-change checked?]
(when (not disabled?) (when (not disabled?)
@ -48,32 +68,75 @@
(colors/alpha colors/neutral-100 (if disabled? 0.3 1)) (colors/alpha colors/neutral-100 (if disabled? 0.3 1))
(colors/alpha colors/white (if disabled? 0.3 1)))}]])]]))) (colors/alpha colors/white (if disabled? 0.3 1)))}]])]])))
(defn checkbox (defn checkbox
[{:keys [default-checked?]}] [{:keys [default-checked?]}]
(let [checked? (reagent/atom (or default-checked? false))] (let [checked? (reagent/atom (or default-checked? false))]
@(reagent/track (fn [{:keys [on-change disabled? blurred-background? container-style]}]
(fn [{:keys [on-change disabled? blurred-background? container-style]}] [rn/touchable-without-feedback
[rn/touchable-without-feedback {:on-press (handle-press disabled? on-change checked?)}
{:on-press (handle-press disabled? on-change checked?)} [rn/view
[rn/view {:style (merge
{:style (merge container-style
container-style {:height 20
{:height 20 :width 20})}
:width 20})} [rn/view
[rn/view {:style {:flex 1
{:style (style/checkbox-toggle checked? disabled? blurred-background?) :border-radius 6
:accessibility-label (str "checkbox-" (if @checked? "on" "off")) :border-width (if @checked? 0 1)
:accessibility-role :checkbox :background-color (cond
:testID "checkbox-component"} @checked?
(when @checked? (get-color @checked? disabled? blurred-background?)
[rn/view blurred-background?
{:style (colors/theme-colors
{:height 20 colors/white-opa-5
:width 20}} colors/white-opa-10)
[icons/icon :i/check-small :else
{:size 20 (colors/theme-colors
:color colors/white}]])]]]) colors/white
checked?))) 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}]])]]])))
;; TODO (Omar): issue https://github.com/status-im/status-mobile/issues/14681
;(defn checkbox
; [{:keys [default-checked?]}]
; (let [checked? (reagent/atom (or default-checked? false))]
; @(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 (defn radio
[{:keys [default-checked?]}] [{:keys [default-checked?]}]

View File

@ -39,7 +39,16 @@
{:json-rpc/call [{:method "wakuext_removeMemberFromGroupChat" {:json-rpc/call [{:method "wakuext_removeMemberFromGroupChat"
:params [nil chat-id member] :params [nil chat-id member]
:js-response true :js-response true
:on-success #(re-frame/dispatch [:chat-updated % do-not-navigate?])}]}) :on-success #(re-frame/dispatch [:chat-updated % true])}]})
(rf/defn remove-members
{:events [:group-chats.ui/remove-members-pressed]}
[{{:keys [current-chat-id] :group-chat/keys [deselected-members]} :db :as cofx}]
{:json-rpc/call [{:method "wakuext_removeMembersFromGroupChat"
:params [nil current-chat-id deselected-members]
:js-response true
:on-success #(re-frame/dispatch [:chat-updated % true])
:on-error #()}]})
(rf/defn join-chat (rf/defn join-chat
{:events [:group-chats.ui/join-pressed]} {:events [:group-chats.ui/join-pressed]}
@ -79,11 +88,11 @@
(rf/defn add-members (rf/defn add-members
"Add members to a group chat" "Add members to a group chat"
{:events [:group-chats.ui/add-members-pressed]} {:events [:group-chats.ui/add-members-pressed]}
[{{:keys [current-chat-id selected-participants]} :db :as cofx}] [{{:keys [current-chat-id] :group-chat/keys [selected-participants]} :db :as cofx}]
{:json-rpc/call [{:method "wakuext_addMembersToGroupChat" {:json-rpc/call [{:method "wakuext_addMembersToGroupChat"
:params [nil current-chat-id selected-participants] :params [nil current-chat-id selected-participants]
:js-response true :js-response true
:on-success #(re-frame/dispatch [:chat-updated %])}]}) :on-success #(re-frame/dispatch [:chat-updated % true])}]})
(rf/defn add-members-from-invitation (rf/defn add-members-from-invitation
"Add members to a group chat" "Add members to a group chat"
@ -179,6 +188,16 @@
:type :type
(= constants/invitation-state-removed))) (= constants/invitation-state-removed)))
(rf/defn deselect-member
{:events [:deselect-member]}
[{:keys [db]} id]
{:db (update db :group-chat/deselected-members conj id)})
(rf/defn undo-deselect-member
{:events [:undo-deselect-member]}
[{:keys [db]} id]
{:db (update db :group-chat/deselected-members disj id)})
(rf/defn deselect-contact (rf/defn deselect-contact
{:events [:deselect-contact]} {:events [:deselect-contact]}
[{:keys [db]} id] [{:keys [db]} id]
@ -192,17 +211,22 @@
(rf/defn deselect-participant (rf/defn deselect-participant
{:events [:deselect-participant]} {:events [:deselect-participant]}
[{:keys [db]} id] [{:keys [db]} id]
{:db (update db :selected-participants disj id)}) {:db (update db :group-chat/selected-participants disj id)})
(rf/defn select-participant (rf/defn select-participant
{:events [:select-participant]} {:events [:select-participant]}
[{:keys [db]} id] [{:keys [db]} id]
{:db (update db :selected-participants conj id)}) {:db (update db :group-chat/selected-participants conj id)})
(rf/defn add-participants-toggle-list (rf/defn clear-added-participants
{:events [:group/add-participants-toggle-list]} {:events [:group/clear-added-participants]}
[{db :db}] [{db :db}]
{:db (assoc db :selected-participants #{})}) {:db (assoc db :group-chat/selected-participants #{})})
(rf/defn clear-removed-members
{:events [:group/clear-removed-members]}
[{db :db}]
{:db (assoc db :group-chat/deselected-members #{})})
(rf/defn show-group-chat-profile (rf/defn show-group-chat-profile
{:events [:show-group-chat-profile]} {:events [:show-group-chat-profile]}

View File

@ -107,7 +107,7 @@
[status-im.ui.screens.wallet.settings.views :as wallet-settings] [status-im.ui.screens.wallet.settings.views :as wallet-settings]
[status-im.ui.screens.wallet.swap.views :as wallet.swap] [status-im.ui.screens.wallet.swap.views :as wallet.swap]
[status-im.ui.screens.wallet.transactions.views :as wallet-transactions] [status-im.ui.screens.wallet.transactions.views :as wallet-transactions]
[status-im.ui2.screens.chat.group-details.view :as group-details] [status-im2.contexts.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])) [status-im.ui2.screens.chat.components.new-chat.view :as new-chat-aio]))

View File

@ -9,15 +9,15 @@
[quo/divider-label {:label title}]) [quo/divider-label {:label title}])
(defn contact-list (defn contact-list
[{:keys [start-a-new-chat?] :as data}] [data]
(let [contacts (if start-a-new-chat? (let [contacts (if (:group data)
(rf/sub [:contacts/sorted-and-grouped-by-first-letter]) (rf/sub [:contacts/add-members-sections])
(rf/sub [:contacts/filtered-active-sections]))] (rf/sub [:contacts/filtered-active-sections]))]
[rn/section-list [rn/section-list
{:key-fn :title {:key-fn :title
:sticky-section-headers-enabled false :sticky-section-headers-enabled false
:sections contacts :sections contacts
:render-section-header-fn contacts-section-header :render-section-header-fn contacts-section-header
:content-container-style {:padding-bottom 120} :content-container-style {:padding-bottom 20}
:render-data data :render-data data
:render-fn contact-list-item/contact-list-item}])) :render-fn contact-list-item/contact-list-item}]))

View File

@ -3,11 +3,11 @@
[quo2.foundations.colors :as colors] [quo2.foundations.colors :as colors]
[react-native.core :as rn] [react-native.core :as rn]
[react-native.platform :as platform] [react-native.platform :as platform]
[reagent.core :as reagent]
[status-im2.common.home.actions.view :as actions] [status-im2.common.home.actions.view :as actions]
[status-im2.contexts.chat.home.chat-list-item.style :as style] [status-im2.contexts.chat.home.chat-list-item.style :as style]
[utils.address :as utils.address] [utils.address :as utils.address]
[utils.re-frame :as rf])) [utils.re-frame :as rf]
[reagent.core :as reagent]))
(defn open-chat (defn open-chat
[chat-id] [chat-id]
@ -20,33 +20,36 @@
(rf/dispatch [:search/home-filter-changed nil])))) (rf/dispatch [:search/home-filter-changed nil]))))
(defn action-icon (defn action-icon
[{:keys [public-key] :as item} {:keys [icon start-a-new-chat? group added] :as extra-data} [{:keys [public-key] :as item} {:keys [icon start-a-new-chat? group] :as extra-data}
user-selected? on-toggle] user-selected? on-toggle]
(let [{:keys [contacts]} group (let [{:keys [contacts admins]} group
member? (contains? contacts public-key) member? (contains? contacts public-key)
checked? (reagent/atom (if start-a-new-chat? current-pk (rf/sub [:multiaccount/public-key])
user-selected? admin? (get admins current-pk)
member?))] checked? (reagent/atom (if start-a-new-chat?
user-selected?
member?))]
[rn/touchable-opacity [rn/touchable-opacity
{:on-press #(rf/dispatch [:bottom-sheet/show-sheet {:on-press #(rf/dispatch [:bottom-sheet/show-sheet
{:content (fn [] [actions/actions item extra-data])}]) {:content (fn [] [actions/actions item extra-data])}])
:style {:position :absolute :style {:position :absolute
:right 20}} :right 20}}
(if (= icon :options) (if (= icon :options)
[quo/icon :i/options [quo/icon :i/options {:size 20 :color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]
{:size 20 [quo/checkbox
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}] {:default-checked? @checked?
@(reagent/track! :accessibility-label :contact-toggle-check
(fn [] :disabled? (and member? (not admin?))
[quo/checkbox :on-change (fn [selected]
{:default-checked? @checked? (if start-a-new-chat?
:on-change (fn [selected] (on-toggle true @checked? public-key)
(if start-a-new-chat? (if-not member?
(on-toggle true @checked? public-key) (if selected
(if selected (rf/dispatch [:select-participant public-key true])
(swap! added conj public-key) (rf/dispatch [:deselect-participant public-key true]))
(reset! added (remove #(= % public-key) @added)))))}]) (if selected
checked?))])) (rf/dispatch [:undo-deselect-member public-key true])
(rf/dispatch [:deselect-member public-key true])))))}])]))
(defn contact-list-item (defn contact-list-item
[item _ _ {:keys [group start-a-new-chat? on-toggle] :as extra-data}] [item _ _ {:keys [group start-a-new-chat? on-toggle] :as extra-data}]
@ -57,38 +60,36 @@
photo-path (when (seq images) photo-path (when (seq images)
(rf/sub [:chats/photo-path public-key])) (rf/sub [:chats/photo-path public-key]))
current-pk (rf/sub [:multiaccount/public-key]) current-pk (rf/sub [:multiaccount/public-key])
online? (rf/sub [:visibility-status-updates/online?
public-key])
user-selected? (rf/sub [:is-contact-selected? public-key])] user-selected? (rf/sub [:is-contact-selected? public-key])]
[rn/touchable-opacity [rn/touchable-opacity
(merge {:style (style/container) (merge
:active-opacity 1 {:style (style/container)
:on-press #(if start-a-new-chat? :accessibility-label :contact
(on-toggle true user-selected? public-key) :active-opacity 1
(open-chat public-key)) :on-press #(if start-a-new-chat?
:on-long-press #(when (some? group) (on-toggle true user-selected? public-key)
(rf/dispatch [:bottom-sheet/show-sheet (open-chat public-key))
{:content (fn [] [actions/actions item extra-data])}]))}) :on-long-press #(when (some? group)
(rf/dispatch [:bottom-sheet/show-sheet
{:content (fn [] [actions/actions item extra-data])}]))})
[quo/user-avatar [quo/user-avatar
{:full-name display-name {:full-name display-name
:profile-picture photo-path :profile-picture photo-path
:status-indicator? true :status-indicator? true
:online? true :online? online?
:size :small :size :small
:ring? false}] :ring? false}]
[rn/view {:style {:margin-left 8}} [rn/view {:style {:margin-left 8}}
[rn/view {:style {:flex-direction :row}} [rn/view {:style {:flex-direction :row}}
[quo/text {:weight :semi-bold} display-name] [quo/text {:weight :semi-bold} display-name]
(if ens-verified (if ens-verified
[rn/view [rn/view {:style {:margin-left 5 :margin-top 4}}
{:style {:margin-left 5
:margin-top 4}}
[quo/icon :i/verified [quo/icon :i/verified
{:no-color true {:no-color true :size 12 :color (colors/theme-colors colors/success-50 colors/success-60)}]]
:size 12
:color (colors/theme-colors colors/success-50 colors/success-60)}]]
(when added? (when added?
[rn/view [rn/view {:style {:margin-left 5 :margin-top 4}}
{:style {:margin-left 5
:margin-top 4}}
[quo/icon :i/contact [quo/icon :i/contact
{:no-color true {:no-color true
:size 12 :size 12
@ -98,4 +99,4 @@
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}} :style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
(utils.address/get-shortened-address public-key)]] (utils.address/get-shortened-address public-key)]]
(when-not (= current-pk public-key) (when-not (= current-pk public-key)
[:f> action-icon item extra-data user-selected? on-toggle])])) [action-icon item extra-data user-selected? on-toggle])]))

View File

@ -1,5 +1,6 @@
(ns status-im.ui2.screens.chat.group-details.style (ns status-im2.contexts.chat.group-details.style
(:require [quo2.foundations.colors :as colors])) (:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]))
(defn actions-view (defn actions-view
[] []
@ -33,12 +34,13 @@
:align-items :center :align-items :center
:margin-bottom 24}) :margin-bottom 24})
(def bottom-container (defn bottom-container
{:position :absolute [safe-area]
:padding-horizontal 20 {:padding-horizontal 20
:padding-vertical 12 :padding-vertical 12
:padding-bottom 33 :padding-bottom (+ 33 (:bottom safe-area))
:width "100%" :width "100%"
:background-color colors/white :background-color colors/white
:flex-direction :row :flex-direction :row
:bottom 0}) :margin-bottom (if platform/ios? 0 70)})

View File

@ -1,13 +1,11 @@
(ns status-im.ui2.screens.chat.group-details.view (ns status-im2.contexts.chat.group-details.view
(:require [i18n.i18n :as i18n] (:require [i18n.i18n :as i18n]
[oops.core :refer [oget]]
[quo.components.safe-area :as safe-area] [quo.components.safe-area :as safe-area]
[quo2.core :as quo2] [quo2.core :as quo2]
[quo2.foundations.colors :as colors] [quo2.foundations.colors :as colors]
[react-native.core :as rn] [react-native.core :as rn]
[reagent.core :as reagent]
[status-im.chat.models :as chat.models] [status-im.chat.models :as chat.models]
[status-im.ui2.screens.chat.group-details.style :as style] [status-im2.contexts.chat.group-details.style :as style]
[status-im.ui2.screens.common.contact-list.view :as contact-list] [status-im.ui2.screens.common.contact-list.view :as contact-list]
[status-im2.common.contact-list-item.view :as contact-list-item] [status-im2.common.contact-list-item.view :as contact-list-item]
[status-im2.common.home.actions.view :as actions] [status-im2.common.home.actions.view :as actions]
@ -46,8 +44,10 @@
[back-button] [options-button]]) [back-button] [options-button]])
(defn count-container (defn count-container
[count] [count accessibility-label]
[rn/view {:style (style/count-container)} [rn/view
{:style (style/count-container)
:accessibility-label accessibility-label}
[quo2/text [quo2/text
{:size :label {:size :label
:weight :medium :weight :medium
@ -66,44 +66,41 @@
:weight :medium :weight :medium
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}} title]]) :style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}} title]])
(def added (reagent/atom ())) (defn add-members-sheet
[group admin?]
(defn contact-requests-sheet [:f>
[group] (fn []
(let [added (reagent/atom ())] (let [{window-height :height} (rn/use-window-dimensions)
(fn [] safe-area (safe-area/use-safe-area)
[:f> selected-participants (rf/sub [:group-chat/selected-participants])
(fn [] deselected-members (rf/sub [:group-chat/deselected-members])]
(let [{window-height :height} (rn/use-window-dimensions) [rn/view {:style {:height (- window-height (:top safe-area))}}
safe-area (safe-area/use-safe-area)] [rn/touchable-opacity
[rn/view {:style {:height (- window-height (:top safe-area))}} {:on-press #(rf/dispatch [:bottom-sheet/hide])
[rn/touchable-opacity :accessibility-label :close-manage-members
{:on-press #(rf/dispatch [:bottom-sheet/hide]) :style (style/close-icon)}
:style (style/close-icon)} [quo2/icon :i/close {:color (colors/theme-colors colors/neutral-100 colors/white)}]]
[quo2/icon :i/close {:color (colors/theme-colors colors/neutral-100 colors/white)}]] [quo2/text
[quo2/text {:size :heading-1
{:size :heading-1 :weight :semi-bold
:weight :semi-bold :style {:margin-left 20}}
:style {:margin-left 20}} (i18n/label (if admin? :t/manage-members :t/add-members))]
(i18n/label :t/add-members)] [contact-list/contact-list
[rn/text-input {:icon :check
{:placeholder (str (i18n/label :t/search) "...") :group group
:style {:height 32 :search? true}]
:padding-horizontal 20 [rn/view {:style (style/bottom-container safe-area)}
:margin-vertical 12} [quo2/button
:on-change (fn [e] {:style {:flex 1}
(rf/dispatch [:contacts/set-search-query (oget e "nativeEvent.text")]))}] :accessibility-label :save
[contact-list/contact-list :on-press (fn []
{:icon :check (rf/dispatch [:group-chats.ui/add-members-pressed])
:group group (js/setTimeout #(rf/dispatch [:group-chats.ui/remove-members-pressed])
:added added 500)
:search? true}] (rf/dispatch [:bottom-sheet/hide]))
[rn/view {:style style/bottom-container} :disabled (and (zero? (count selected-participants))
[quo2/button (zero? (count deselected-members)))}
{:style {:flex 1} (i18n/label :t/save)]]]))])
:on-press #(rf/dispatch [:bottom-sheet/hide])
:disabled (zero? (count @added))}
(i18n/label :t/save)]]]))])))
(defn group-details (defn group-details
[] []
@ -136,33 +133,39 @@
{:size 20 :color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]]] {:size 20 :color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]]]
[rn/view {:style (style/actions-view)} [rn/view {:style (style/actions-view)}
[rn/touchable-opacity [rn/touchable-opacity
{:style (style/action-container color) {:style (style/action-container color)
:on-press (fn [] :accessibility-label :pinned-messages
(rf/dispatch [:bottom-sheet/show-sheet :pinned-messages-list chat-id]))} :on-press (fn []
(rf/dispatch [:bottom-sheet/show-sheet :pinned-messages-list chat-id]))}
[rn/view [rn/view
{:style {:flex-direction :row {:style {:flex-direction :row
:justify-content :space-between}} :justify-content :space-between}}
[quo2/icon :i/pin {:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}] [quo2/icon :i/pin {:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}]
[count-container (count pinned-messages)]] [count-container (count pinned-messages) :pinned-count]]
[quo2/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium} [quo2/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium}
(i18n/label :t/pinned-messages)]] (i18n/label :t/pinned-messages)]]
[rn/touchable-opacity [rn/touchable-opacity
{:style (style/action-container color) {:style (style/action-container color)
:on-press #(rf/dispatch [::chat.models/mute-chat-toggled chat-id (not muted)])} :accessibility-label :toggle-mute
:on-press #(rf/dispatch [::chat.models/mute-chat-toggled chat-id (not muted)])}
[quo2/icon (if muted :i/muted :i/activity-center) [quo2/icon (if muted :i/muted :i/activity-center)
{:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}] {:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}]
[quo2/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium} [quo2/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium}
(i18n/label (if muted :unmute-group :mute-group))]] (i18n/label (if muted :unmute-group :mute-group))]]
[rn/touchable-opacity [rn/touchable-opacity
{:style (style/action-container color) {:style (style/action-container color)
:on-press #(rf/dispatch :accessibility-label :manage-members
[:bottom-sheet/show-sheet :on-press (fn []
{:content (fn [] [contact-requests-sheet group])}])} (rf/dispatch [:group/clear-added-participants])
(rf/dispatch [:group/clear-removed-members])
(rf/dispatch
[:bottom-sheet/show-sheet
{:content (fn [] [add-members-sheet group admin?])}]))}
[rn/view [rn/view
{:style {:flex-direction :row {:style {:flex-direction :row
:justify-content :space-between}} :justify-content :space-between}}
[quo2/icon :i/add-user {:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}] [quo2/icon :i/add-user {:size 20 :color (colors/theme-colors colors/neutral-100 colors/white)}]
[count-container (count contacts)]] [count-container (count contacts) :members-count]]
[quo2/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium} [quo2/text {:style {:margin-top 16} :size :paragraph-1 :weight :medium}
(i18n/label (if admin? :t/manage-members :t/add-members))]]] (i18n/label (if admin? :t/manage-members :t/add-members))]]]
[rn/section-list [rn/section-list

View File

@ -23,7 +23,7 @@
(fn [c] (fn [c]
{:key c {:key c
:value c}) :value c})
(keys colors/customization))}]) ["#ff0000" "#0000ff"])}]) ; TODO: this is temporary only. Issue: https://github.com/status-im/status-mobile/issues/14566
(defn cool-preview (defn cool-preview
[] []

View File

@ -13,7 +13,8 @@
:group/selected-contacts #{} :group/selected-contacts #{}
:chats {} :chats {}
:current-chat-id nil :current-chat-id nil
:selected-participants #{} :group-chat/selected-participants #{}
:group-chat/deselected-members #{}
:sync-state :done :sync-state :done
:link-previews-whitelist [] :link-previews-whitelist []
:app-state "active" :app-state "active"

View File

@ -8,7 +8,7 @@
[status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils] [status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils]
[status-im.utils.gfycat.core :as gfycat] [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])) [utils.collection]))
(re-frame/reg-sub (re-frame/reg-sub
::query-current-chat-contacts ::query-current-chat-contacts
@ -93,21 +93,20 @@
vals))) vals)))
(re-frame/reg-sub (re-frame/reg-sub
:contacts/sorted-and-grouped-by-first-letter :contacts/add-members-sections
:<- [:contacts/current-chat-contacts]
:<- [:contacts/active] :<- [:contacts/active]
:<- [:selected-contacts-count] (fn [[members contacts]]
(fn [[contacts selected-contacts-count]] (-> (reduce
(->> contacts (fn [acc contact]
(filter :mutual?) (let [first-char (first (:alias contact))]
(map #(assoc % (if (get acc first-char)
:allow-new-users? (update-in acc [first-char :data] #(conj % contact))
(< selected-contacts-count (assoc acc first-char {:title first-char :data [contact]}))))
(dec constants/max-group-chat-participants)))) {}
(group-by (comp (fnil string/upper-case "") first :alias)) (utils.collection/distinct-by :public-key (concat members contacts)))
(sort-by (fn [[title]] title)) sort
(map (fn [[title data]] vals)))
{:title title
:data data})))))
(re-frame/reg-sub (re-frame/reg-sub
:contacts/sorted-contacts :contacts/sorted-contacts
@ -312,4 +311,3 @@
(seq offline) (assoc :offline {:title (i18n/label :t/offline) :data offline})))))) (seq offline) (assoc :offline {:title (i18n/label :t/offline) :data offline}))))))

View File

@ -217,7 +217,7 @@
(re-frame/reg-sub (re-frame/reg-sub
:is-participant-selected? :is-participant-selected?
:<- [:selected-participants] :<- [:group-chat/selected-participants]
(fn [selected-participants [_ element]] (fn [selected-participants [_ element]]
(-> selected-participants (-> selected-participants
(contains? element)))) (contains? element))))

View File

@ -99,7 +99,8 @@
(reg-root-key-sub :new-chat-name :new-chat-name) (reg-root-key-sub :new-chat-name :new-chat-name)
(reg-root-key-sub :group-chat-profile/editing? :group-chat-profile/editing?) (reg-root-key-sub :group-chat-profile/editing? :group-chat-profile/editing?)
(reg-root-key-sub :group-chat-profile/profile :group-chat-profile/profile) (reg-root-key-sub :group-chat-profile/profile :group-chat-profile/profile)
(reg-root-key-sub :selected-participants :selected-participants) (reg-root-key-sub :group-chat/selected-participants :group-chat/selected-participants)
(reg-root-key-sub :group-chat/deselected-members :group-chat/deselected-members)
(reg-root-key-sub :chat/inputs :chat/inputs) (reg-root-key-sub :chat/inputs :chat/inputs)
(reg-root-key-sub :chat/memberships :chat/memberships) (reg-root-key-sub :chat/memberships :chat/memberships)
(reg-root-key-sub :camera-roll/photos :camera-roll/photos) (reg-root-key-sub :camera-roll/photos :camera-roll/photos)

View File

@ -14,3 +14,9 @@
Similar to group-by except that the map values are single objects (depends on key uniqueness)." Similar to group-by except that the map values are single objects (depends on key uniqueness)."
[key coll] [key coll]
(into {} (map #(vector (key %) %) coll))) (into {} (map #(vector (key %) %) coll)))
(defn distinct-by
"Given a key and a collection returns a unique collection by that key"
[key coll]
(let [groups (group-by key coll)]
(map #(first (groups %)) (distinct (map key coll)))))

View File

@ -1923,5 +1923,6 @@
"search-contacts": "Search contacts", "search-contacts": "Search contacts",
"who-are-you-looking-for": "Who are you looking for ?", "who-are-you-looking-for": "Who are you looking for ?",
"close-contact-search": "Close contact search", "close-contact-search": "Close contact search",
"selected-count-from-max": "{{selected}}/{{max}}" "selected-count-from-max": "{{selected}}/{{max}}",
"online": "Online"
} }