Skip to content

Commit 78f9331

Browse files
authored
fix(group-chat): Prevent adding more participants than the allowed group limit (#22561)
Addresses an issue where users were able to add more participants to a group chat than the allowed maximum(20). The new logic ensures that participant additions are validated against the group size limit, preventing overflows. This PR also adds member count in the right side of Manage members header. Platforms: - Android - iOS Areas that may be impacted: Functional - Group chats Steps to test: - Open Status - Create a group chat - Open group chat - Open group chat options -> Manage members - Try adding more than 20 members Fixes #21590 Author @ajayesivan
1 parent e364df3 commit 78f9331

File tree

6 files changed

+125
-31
lines changed

6 files changed

+125
-31
lines changed

src/status_im/contexts/chat/group/details/style.cljs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,17 @@
2525
:margin-bottom bottom
2626
:background-color (colors/theme-colors colors/white colors/neutral-95-opa-70 theme)
2727
:flex-direction :row})
28+
29+
(def manage-members-header
30+
{:flex-direction :row
31+
:justify-content :space-between
32+
:align-items :flex-end
33+
:margin-horizontal 20
34+
:margin-bottom 16})
35+
36+
(defn counter
37+
[theme error?]
38+
{:margin-bottom 2
39+
:color (if error?
40+
(colors/theme-colors colors/danger-50 colors/danger-60 theme)
41+
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))})

src/status_im/contexts/chat/group/details/view.cljs

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
[react-native.core :as rn]
77
[react-native.gesture :as gesture]
88
[react-native.safe-area :as safe-area]
9-
[reagent.core :as reagent]
109
[status-im.common.contact-list-item.view :as contact-list-item]
1110
[status-im.common.contact-list.view :as contact-list]
1211
[status-im.common.home.actions.view :as actions]
@@ -26,27 +25,35 @@
2625
(rf/dispatch [:deselect-member public-key true]))))
2726

2827
(defn add-member-contact-item-render
29-
[{:keys [public-key] :as item} _ _ {:keys [group admin? current-pk]}]
30-
(let [{:keys [contacts]} group
31-
member? (contains? contacts public-key)
32-
checked? (reagent/atom member?)]
33-
(if (or (= current-pk public-key) (and (not admin?) member?))
34-
(fn []
35-
[contact-list-item/contact-list-item
36-
{:disabled? true
37-
:accessory {:disabled? true
38-
:type :checkbox
39-
:checked? @checked?}}
40-
item])
41-
(fn []
42-
(let [on-toggle #(group-chat-member-toggle member? (swap! checked? not) public-key)]
43-
[contact-list-item/contact-list-item
44-
{:on-press on-toggle
45-
:allow-multiple-presses? true
46-
:accessory {:type :checkbox
47-
:checked? @checked?
48-
:on-check on-toggle}}
49-
item])))))
28+
[{:keys [public-key] :as item} _ _ {:keys [group admin? current-pk chat-id]}]
29+
(let [{:keys [contacts]} group
30+
member? (contains? contacts public-key)
31+
[checked? set-checked] (rn/use-state member?)
32+
selected-contacts-count (rf/sub [:group-chat/manage-members-count chat-id])
33+
disabled? (or (= current-pk public-key) (and (not admin?) member?))
34+
on-toggle (rn/use-callback
35+
(fn [value]
36+
(let [error? (and value
37+
(= constants/max-group-chat-participants
38+
selected-contacts-count))]
39+
(rf/dispatch [:group-chat/set-manage-members-error
40+
{:chat-id chat-id
41+
:error? error?}])
42+
(when-not error?
43+
(group-chat-member-toggle member?
44+
value
45+
public-key)
46+
(set-checked value))))
47+
[selected-contacts-count member? public-key])]
48+
[contact-list-item/contact-list-item
49+
{:on-press on-toggle
50+
:allow-multiple-presses? true
51+
:disabled? disabled?
52+
:accessory {:type :checkbox
53+
:disabled? disabled?
54+
:checked? checked?
55+
:on-check on-toggle}}
56+
item]))
5057

5158
(defn add-manage-members
5259
[{:keys [on-scroll]}]
@@ -56,7 +63,9 @@
5663
chat-id (quo.context/use-screen-params)
5764
{:keys [admins] :as group} (rf/sub [:chats/chat-by-id chat-id])
5865
current-pk (rf/sub [:multiaccount/public-key])
59-
admin? (get admins current-pk)]
66+
admin? (get admins current-pk)
67+
selected-contacts-count (rf/sub [:group-chat/manage-members-count chat-id])
68+
error? (rf/sub [:group-chat/manage-members-error-by-chat-id chat-id])]
6069
(rn/use-mount (fn []
6170
(rf/dispatch [:group/clear-added-participants])
6271
(rf/dispatch [:group/clear-removed-members])))
@@ -66,13 +75,21 @@
6675
:accessibility-label :close-manage-members
6776
:style (style/close-icon theme)}
6877
[quo/icon :i/close {:color (colors/theme-colors colors/neutral-100 colors/white theme)}]]
69-
[quo/text
70-
{:size :heading-1
71-
:weight :semi-bold
72-
:style {:margin-left 20}}
73-
(i18n/label (if admin? :t/manage-members :t/add-members))]
78+
[rn/view
79+
{:style style/manage-members-header}
80+
[quo/text
81+
{:size :heading-1
82+
:weight :semi-bold}
83+
(i18n/label (if admin? :t/manage-members :t/add-members))]
84+
[quo/text
85+
{:size :paragraph-2
86+
:weight :regular
87+
:style (style/counter theme error?)}
88+
(i18n/label :t/selected-count-from-max
89+
{:selected selected-contacts-count
90+
:max constants/max-group-chat-participants})]]
7491
[gesture/section-list
75-
{:key-fn :title
92+
{:key-fn :public-key
7693
:on-scroll on-scroll
7794
:sticky-section-headers-enabled false
7895
:sections (rf/sub [:contacts/grouped-by-first-letter])
@@ -81,7 +98,8 @@
8198
:content-container-style {:padding-bottom 20}
8299
:render-data {:group group
83100
:admin? admin?
84-
:current-pk current-pk}
101+
:current-pk current-pk
102+
:chat-id chat-id}
85103
:render-fn add-member-contact-item-render}]
86104
[rn/view {:style (style/bottom-container 30 theme)}
87105
[quo/button

src/status_im/contexts/chat/group/events.cljs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
[oops.core :as oops]
44
[re-frame.core :as rf]
55
[status-im.common.avatar-picture-picker.view :as avatar-picture-picker]
6-
[taoensso.timbre :as log]))
6+
[status-im.constants :as constants]
7+
[taoensso.timbre :as log]
8+
[utils.i18n :as i18n]))
79

810
(rf/reg-event-fx :group-chat/create
911
(fn [{:keys [db]} [{:keys [group-name group-color group-image]}]]
@@ -37,3 +39,16 @@
3739
:on-success (fn [response]
3840
(rf/dispatch [:chat-updated response true])
3941
(when on-success (on-success)))}]}))
42+
43+
(rf/reg-event-fx :group-chat/set-manage-members-error
44+
(fn [{:keys [db]} [{:keys [chat-id error?]}]]
45+
{:db (assoc-in db
46+
[:group-chat/manage-members-error chat-id]
47+
error?)
48+
:fx [(when error?
49+
[:dispatch
50+
[:toasts/upsert
51+
{:type :negative
52+
:text (i18n/label :t/new-group-limit
53+
{:max-contacts
54+
constants/max-group-chat-participants})}]])]}))

src/status_im/subs/chats.cljs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,3 +358,37 @@
358358
(re-frame/subscribe [:chats/chat chat-id]))
359359
:->
360360
:image)
361+
362+
(re-frame/reg-sub
363+
:group-chat/selected-participants-count
364+
:<- [:group-chat/selected-participants]
365+
(fn [selected-participants]
366+
(count selected-participants)))
367+
368+
(re-frame/reg-sub
369+
:group-chat/deselected-members-count
370+
:<- [:group-chat/deselected-members]
371+
(fn [deselected-members]
372+
(count deselected-members)))
373+
374+
(re-frame/reg-sub
375+
:group-chat/member-count
376+
(fn [[_ chat-id]]
377+
(re-frame/subscribe [:chats/chat-by-id chat-id]))
378+
(fn [{:keys [contacts]}]
379+
(count contacts)))
380+
381+
(re-frame/reg-sub
382+
:group-chat/manage-members-count
383+
(fn [[_ chat-id]]
384+
[(re-frame/subscribe [:group-chat/member-count chat-id])
385+
(re-frame/subscribe [:group-chat/selected-participants-count])
386+
(re-frame/subscribe [:group-chat/deselected-members-count])])
387+
(fn [[member-count selected-count deselected-count]]
388+
(+ member-count selected-count (- deselected-count))))
389+
390+
(re-frame/reg-sub
391+
:group-chat/manage-members-error-by-chat-id
392+
:<- [:group-chat/manage-members-error]
393+
(fn [errors [_ chat-id]]
394+
(get errors chat-id)))

src/status_im/subs/chats_test.cljs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,15 @@
207207
:chats chats
208208
:current-chat-id chat-id)
209209
(is (true? (rf/sub [sub-name]))))))
210+
211+
(h/deftest-sub :group-chat/manage-members-count
212+
[sub-name]
213+
(testing "calculates the correct count of members in a group chat"
214+
(let [contacts [{:id "0x777"} {:id "0x789"}]
215+
selected-participants ["0x123" "0x456"]
216+
deselected-members [{:id "Ox789"}]]
217+
(swap! rf-db/app-db assoc
218+
:chats {chat-id {:contacts contacts}}
219+
:group-chat/selected-participants selected-participants
220+
:group-chat/deselected-members deselected-members)
221+
(is (= 3 (rf/sub [sub-name chat-id]))))))

src/status_im/subs/root.cljs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@
129129
;;group chat
130130
(reg-root-key-sub :group-chat/selected-participants :group-chat/selected-participants)
131131
(reg-root-key-sub :group-chat/deselected-members :group-chat/deselected-members)
132+
(reg-root-key-sub :group-chat/manage-members-error :group-chat/manage-members-error)
132133

133134
;;messages
134135
(reg-root-key-sub :messages/messages :messages)

0 commit comments

Comments
 (0)