Skip to content

Commit 1cdb4f0

Browse files
committed
fix: another review fixes
1 parent b78cc53 commit 1cdb4f0

7 files changed

Lines changed: 32 additions & 114 deletions

File tree

examples/SampleApp/src/components/ListItem.tsx

Lines changed: 0 additions & 69 deletions
This file was deleted.

package/src/components/ChannelDetailsScreen/__tests__/members/ChannelAddMembers.test.tsx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ jest.mock('../../components/members/AddMemberSearchResultItem', () => {
5353
mockRowProbe.push(props);
5454
return ReactLib.createElement(
5555
Text,
56-
{ onPress: props.onPress, testID: `add-member-row-${props.user.id}` },
56+
{ onPress: () => props.onPress(props.user), testID: `add-member-row-${props.user.id}` },
5757
props.user.id,
5858
);
5959
},
@@ -68,6 +68,7 @@ const channel = {
6868
const baseHookResult = (): UseChannelAddMembersResult => ({
6969
clearSearch: jest.fn(),
7070
hasMore: true,
71+
isAlreadyMember: jest.fn(() => false),
7172
isSelected: jest.fn(() => false),
7273
loading: false,
7374
loadingMore: false,
@@ -138,13 +139,12 @@ describe('ChannelAddMembers', () => {
138139
const userA = generateUser({ id: 'u-1' });
139140
const userB = generateUser({ id: 'u-2' });
140141
const isSelected = jest.fn((id: string) => id === 'u-2');
142+
const isAlreadyMember = jest.fn((id: string) => id === 'u-1');
141143
const toggleUser = jest.fn();
142144
mockHook({
145+
isAlreadyMember,
143146
isSelected,
144-
results: [
145-
{ ...userA, isAlreadyMember: true },
146-
{ ...userB, isAlreadyMember: false },
147-
],
147+
results: [userA, userB],
148148
toggleUser,
149149
});
150150

package/src/components/ChannelDetailsScreen/__tests__/members/useChannelAddMembers.test.tsx

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -196,18 +196,18 @@ describe('useChannelAddMembers', () => {
196196
expect(result.current.results.map((u) => u.id)).toEqual(['fresh-0']);
197197
});
198198

199-
it('decorates results with isAlreadyMember from the channel member state', async () => {
199+
it('reports membership via isAlreadyMember from the channel member state', async () => {
200200
(useChannelMembersState as jest.Mock).mockReturnValue({ 'u-0': { user_id: 'u-0' } });
201201
const queryUsers: QueryUsersMock = jest.fn().mockResolvedValue({ users: buildUsers(2) });
202202

203203
const { result } = renderUseChannelAddMembers(queryUsers);
204204

205205
await waitFor(() => expect(result.current.results).toHaveLength(2));
206-
expect(result.current.results.find((u) => u.id === 'u-0')?.isAlreadyMember).toBe(true);
207-
expect(result.current.results.find((u) => u.id === 'u-1')?.isAlreadyMember).toBe(false);
206+
expect(result.current.isAlreadyMember('u-0')).toBe(true);
207+
expect(result.current.isAlreadyMember('u-1')).toBe(false);
208208
});
209209

210-
it('toggleUser adds/removes selection, strips isAlreadyMember, and isSelected reflects it', async () => {
210+
it('toggleUser adds/removes selection and isSelected reflects it', async () => {
211211
const queryUsers: QueryUsersMock = jest.fn().mockResolvedValue({ users: buildUsers(1) });
212212

213213
const { result } = renderUseChannelAddMembers(queryUsers);
@@ -218,21 +218,19 @@ describe('useChannelAddMembers', () => {
218218
act(() => result.current.toggleUser(user));
219219
expect(result.current.isSelected('u-0')).toBe(true);
220220
expect(result.current.selectedUsers).toHaveLength(1);
221-
expect(result.current.selectedUsers[0]).not.toHaveProperty('isAlreadyMember');
222221

223222
act(() => result.current.toggleUser(user));
224223
expect(result.current.isSelected('u-0')).toBe(false);
225224
expect(result.current.selectedUsers).toHaveLength(0);
226225
});
227226

228-
it('toggleUser ignores already-member rows and rows without an id', async () => {
227+
it('toggleUser ignores rows without an id', async () => {
229228
const queryUsers: QueryUsersMock = jest.fn().mockResolvedValue({ users: [] });
230229

231230
const { result } = renderUseChannelAddMembers(queryUsers);
232231
await waitFor(() => expect(result.current.loading).toBe(false));
233232

234-
act(() => result.current.toggleUser({ id: 'm-1', isAlreadyMember: true } as never));
235-
act(() => result.current.toggleUser({ isAlreadyMember: false } as never));
233+
act(() => result.current.toggleUser({} as never));
236234

237235
expect(result.current.selectedUsers).toHaveLength(0);
238236
});

package/src/components/ChannelDetailsScreen/components/members/AddMemberSearchResultItem.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { SelectionCircle } from '../../../UIComponents/SelectionCircle';
1111

1212
export type AddMemberSearchResultItemProps = {
1313
isAlreadyMember: boolean;
14-
onPress: () => void;
14+
onPress: (user: UserResponse) => void;
1515
selected: boolean;
1616
user: UserResponse;
1717
};
@@ -86,7 +86,7 @@ const AddMemberSearchResultItemInner = ({
8686
accessibilityLabel={accessibilityLabel}
8787
accessibilityRole='button'
8888
accessibilityState={{ disabled: false, selected }}
89-
onPress={onPress}
89+
onPress={() => onPress(user)}
9090
style={[styles.userRow, userRowOverride]}
9191
testID={`channel-add-members-row-${user.id}`}
9292
>

package/src/components/ChannelDetailsScreen/components/members/ChannelAddMembers.tsx

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ import { Search } from '../../../../icons/search';
1313
import { primitives } from '../../../../theme';
1414
import { EmptySearchResult } from '../../../UIComponents/EmptySearchResult';
1515
import { SearchInput } from '../../../UIComponents/SearchInput';
16-
import {
17-
type AddMemberSearchResult,
18-
useChannelAddMembers,
19-
} from '../../hooks/members/useChannelAddMembers';
16+
import { useChannelAddMembers } from '../../hooks/members/useChannelAddMembers';
2017

2118
export type ChannelAddMembersProps = {
2219
/**
@@ -31,10 +28,10 @@ export type ChannelAddMembersProps = {
3128
*
3229
* See https://reactnative.dev/docs/flatlist#props for the full list.
3330
*/
34-
additionalFlatListProps?: Partial<FlatListProps<AddMemberSearchResult>>;
31+
additionalFlatListProps?: Partial<FlatListProps<UserResponse>>;
3532
};
3633

37-
const keyExtractor = (user: AddMemberSearchResult) => user.id;
34+
const keyExtractor = (user: UserResponse) => user.id;
3835

3936
/**
4037
* @experimental This component is experimental and is subject to change.
@@ -52,6 +49,7 @@ export const ChannelAddMembers = ({
5249

5350
const {
5451
clearSearch,
52+
isAlreadyMember,
5553
isSelected,
5654
loading,
5755
loadingMore,
@@ -70,15 +68,15 @@ export const ChannelAddMembers = ({
7068
}, [onSelectionChange, selectedUsers]);
7169

7270
const renderItem = useCallback(
73-
({ item }: { item: AddMemberSearchResult }) => (
71+
({ item }: { item: UserResponse }) => (
7472
<AddMemberSearchResultItem
75-
isAlreadyMember={item.isAlreadyMember}
76-
onPress={() => toggleUser(item)}
73+
isAlreadyMember={isAlreadyMember(item.id)}
74+
onPress={toggleUser}
7775
selected={isSelected(item.id)}
7876
user={item}
7977
/>
8078
),
81-
[isSelected, toggleUser],
79+
[isAlreadyMember, isSelected, toggleUser],
8280
);
8381

8482
const emptyState = loading ? (

package/src/components/ChannelDetailsScreen/hooks/members/useChannelAddMembers.ts

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,18 @@ import { useNotificationApi } from '../../../Notifications/hooks/useNotification
1111
const PAGE_SIZE = 25;
1212
const DEBOUNCE_MS = 200;
1313

14-
export type AddMemberSearchResult = UserResponse & { isAlreadyMember: boolean };
15-
1614
export type UseChannelAddMembersResult = {
1715
clearSearch: () => void;
1816
hasMore: boolean;
17+
isAlreadyMember: (userId: string) => boolean;
1918
isSelected: (userId: string) => boolean;
2019
loading: boolean;
2120
loadingMore: boolean;
2221
loadMore: () => void;
2322
onChangeSearchText: (text: string) => void;
24-
results: AddMemberSearchResult[];
23+
results: UserResponse[];
2524
selectedUsers: UserResponse[];
26-
toggleUser: (user: AddMemberSearchResult) => void;
25+
toggleUser: (user: UserResponse) => void;
2726
};
2827

2928
/**
@@ -38,7 +37,7 @@ export const useChannelAddMembers = ({
3837
const { addNotification } = useNotificationApi();
3938
const { t } = useTranslationContext();
4039

41-
const [rawResults, setRawResults] = useState<UserResponse[]>([]);
40+
const [results, setResults] = useState<UserResponse[]>([]);
4241
const [selectedUsers, setSelectedUsers] = useState<UserResponse[]>([]);
4342
const [loading, setLoading] = useState(true);
4443
const [loadingMore, setLoadingMore] = useState(false);
@@ -80,7 +79,7 @@ export const useChannelAddMembers = ({
8079

8180
const fetched = response.users ?? [];
8281

83-
setRawResults((prev) => {
82+
setResults((prev) => {
8483
if (!append) return fetched;
8584
const seen = new Set(prev.map((u) => u.id));
8685
const deduped = fetched.filter((u) => u.id && !seen.has(u.id));
@@ -150,33 +149,25 @@ export const useChannelAddMembers = ({
150149
fetchPageRef.current({ append: true, query: queryRef.current });
151150
}, [hasMore, loading]);
152151

153-
const toggleUser = useCallback((user: AddMemberSearchResult) => {
154-
if (!user.id || user.isAlreadyMember) return;
152+
const toggleUser = useCallback((user: UserResponse) => {
153+
if (!user.id) return;
155154
setSelectedUsers((prev) => {
156155
const exists = prev.some((u) => u.id === user.id);
157156
if (exists) return prev.filter((u) => u.id !== user.id);
158-
const userResponse: UserResponse = { ...user };
159-
delete (userResponse as Partial<AddMemberSearchResult>).isAlreadyMember;
160-
return [...prev, userResponse];
157+
return [...prev, user];
161158
});
162159
}, []);
163160

164161
const selectedIds = useMemo(() => new Set(selectedUsers.map((u) => u.id)), [selectedUsers]);
165162

166163
const isSelected = useCallback((userId: string) => selectedIds.has(userId), [selectedIds]);
167164

168-
const results = useMemo<AddMemberSearchResult[]>(
169-
() =>
170-
rawResults.map((user) => ({
171-
...user,
172-
isAlreadyMember: !!user.id && memberIds.has(user.id),
173-
})),
174-
[rawResults, memberIds],
175-
);
165+
const isAlreadyMember = useCallback((userId: string) => memberIds.has(userId), [memberIds]);
176166

177167
return {
178168
clearSearch,
179169
hasMore,
170+
isAlreadyMember,
180171
isSelected,
181172
loading,
182173
loadingMore,

package/src/components/ChannelList/hooks/useMutedUsers.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const keys: EventTypes[] = ['health.check', 'notification.mutes_updated'];
99
export function useMutedUsers(): Array<Mute>;
1010
/**
1111
*
12-
* @param @deprecated _channel - This parameter is deprecated because it is no longer necessary. It is kept for backwards compatibility only..
12+
* @param @deprecated _channel - This parameter is deprecated because it is no longer necessary. It is kept for backwards compatibility only.
1313
* @returns
1414
*/
1515
export function useMutedUsers(_channel: Channel): Array<Mute> | undefined;

0 commit comments

Comments
 (0)