forked from Ivasoft/mattermost-mobile
Move User list to a component (#6783)
* Move user list to a component * added tests to see that several situations render
This commit is contained in:
817
app/components/user_list/__snapshots__/index.test.tsx.snap
Normal file
817
app/components/user_list/__snapshots__/index.test.tsx.snap
Normal file
@@ -0,0 +1,817 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`components/channel_list_row should show no results 1`] = `
|
||||
<RCTScrollView
|
||||
ListEmptyComponent={[Function]}
|
||||
ListFooterComponent={[Function]}
|
||||
contentContainerStyle={
|
||||
{
|
||||
"flexGrow": 1,
|
||||
}
|
||||
}
|
||||
data={
|
||||
[
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"auth_service": "",
|
||||
"create_at": 1111,
|
||||
"delete_at": 0,
|
||||
"email": "john@doe.com",
|
||||
"first_name": "",
|
||||
"id": "1",
|
||||
"last_name": "",
|
||||
"locale": "",
|
||||
"nickname": "",
|
||||
"notify_props": {
|
||||
"channel": "true",
|
||||
"comments": "never",
|
||||
"desktop": "mention",
|
||||
"desktop_sound": "true",
|
||||
"email": "true",
|
||||
"first_name": "true",
|
||||
"mention_keys": "",
|
||||
"push": "mention",
|
||||
"push_status": "away",
|
||||
},
|
||||
"position": "",
|
||||
"roles": "",
|
||||
"update_at": 1111,
|
||||
"username": "johndoe",
|
||||
},
|
||||
],
|
||||
"id": "J",
|
||||
},
|
||||
]
|
||||
}
|
||||
extraData={false}
|
||||
getItem={[Function]}
|
||||
getItemCount={[Function]}
|
||||
initialNumToRender={15}
|
||||
keyExtractor={[Function]}
|
||||
keyboardDismissMode="on-drag"
|
||||
keyboardShouldPersistTaps="always"
|
||||
maxToRenderPerBatch={16}
|
||||
onContentSizeChange={[Function]}
|
||||
onEndReached={[Function]}
|
||||
onLayout={[Function]}
|
||||
onMomentumScrollBegin={[Function]}
|
||||
onMomentumScrollEnd={[Function]}
|
||||
onScroll={[Function]}
|
||||
onScrollBeginDrag={[Function]}
|
||||
onScrollEndDrag={[Function]}
|
||||
removeClippedSubviews={true}
|
||||
renderItem={[Function]}
|
||||
scrollEventThrottle={60}
|
||||
stickyHeaderIndices={[]}
|
||||
style={
|
||||
{
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
testID="UserListRow.section_list"
|
||||
>
|
||||
<View>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
style={null}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"backgroundColor": "#ffffff",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"backgroundColor": "rgba(63,67,80,0.08)",
|
||||
"height": 24,
|
||||
"justifyContent": "center",
|
||||
"paddingLeft": 16,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
{
|
||||
"color": "#3f4350",
|
||||
"fontFamily": "OpenSans-SemiBold",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "600",
|
||||
"lineHeight": 16,
|
||||
}
|
||||
}
|
||||
>
|
||||
J
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
style={null}
|
||||
>
|
||||
<View
|
||||
onMoveShouldSetResponder={[Function]}
|
||||
onMoveShouldSetResponderCapture={[Function]}
|
||||
onResponderEnd={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderReject={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderStart={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
onStartShouldSetResponderCapture={[Function]}
|
||||
>
|
||||
<View
|
||||
accessible={true}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"height": 58,
|
||||
"overflow": "hidden",
|
||||
"paddingHorizontal": 20,
|
||||
}
|
||||
}
|
||||
testID="create_direct_message.user_list.user_item.1"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
[
|
||||
{
|
||||
"alignItems": "center",
|
||||
"color": "#3f4350",
|
||||
"flexDirection": "row",
|
||||
},
|
||||
{
|
||||
"opacity": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"borderRadius": 21.5,
|
||||
"height": 42,
|
||||
"width": 42,
|
||||
}
|
||||
}
|
||||
testID="create_direct_message.user_list.user_item.1.profile_picture"
|
||||
>
|
||||
<Icon
|
||||
name="account-outline"
|
||||
size={24}
|
||||
style={
|
||||
{
|
||||
"color": "rgba(63,67,80,0.48)",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
[
|
||||
{
|
||||
"flex": 1,
|
||||
"flexDirection": "column",
|
||||
"justifyContent": "center",
|
||||
"paddingHorizontal": 10,
|
||||
},
|
||||
{
|
||||
"opacity": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"flexDirection": "row",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
{
|
||||
"color": "#3f4350",
|
||||
"fontFamily": "OpenSans",
|
||||
"fontSize": 16,
|
||||
"fontWeight": "400",
|
||||
"height": 24,
|
||||
"lineHeight": 24,
|
||||
"maxWidth": "80%",
|
||||
}
|
||||
}
|
||||
testID="create_direct_message.user_list.user_item.1.display_name"
|
||||
>
|
||||
johndoe
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
color="rgba(63,67,80,0.1024)"
|
||||
name="circle-outline"
|
||||
size={28}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
style={null}
|
||||
/>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<ActivityIndicator
|
||||
color="#1c58d9"
|
||||
size="large"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</RCTScrollView>
|
||||
`;
|
||||
|
||||
exports[`components/channel_list_row should show results and tutorial 1`] = `
|
||||
<RCTScrollView
|
||||
ListEmptyComponent={[Function]}
|
||||
ListFooterComponent={[Function]}
|
||||
contentContainerStyle={
|
||||
{
|
||||
"flexGrow": 1,
|
||||
}
|
||||
}
|
||||
data={
|
||||
[
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"auth_service": "",
|
||||
"create_at": 1111,
|
||||
"delete_at": 0,
|
||||
"email": "john@doe.com",
|
||||
"first_name": "",
|
||||
"id": "1",
|
||||
"last_name": "",
|
||||
"locale": "",
|
||||
"nickname": "",
|
||||
"notify_props": {
|
||||
"channel": "true",
|
||||
"comments": "never",
|
||||
"desktop": "mention",
|
||||
"desktop_sound": "true",
|
||||
"email": "true",
|
||||
"first_name": "true",
|
||||
"mention_keys": "",
|
||||
"push": "mention",
|
||||
"push_status": "away",
|
||||
},
|
||||
"position": "",
|
||||
"roles": "",
|
||||
"update_at": 1111,
|
||||
"username": "johndoe",
|
||||
},
|
||||
],
|
||||
"id": "J",
|
||||
},
|
||||
]
|
||||
}
|
||||
extraData={false}
|
||||
getItem={[Function]}
|
||||
getItemCount={[Function]}
|
||||
initialNumToRender={15}
|
||||
keyExtractor={[Function]}
|
||||
keyboardDismissMode="on-drag"
|
||||
keyboardShouldPersistTaps="always"
|
||||
maxToRenderPerBatch={16}
|
||||
onContentSizeChange={[Function]}
|
||||
onEndReached={[Function]}
|
||||
onLayout={[Function]}
|
||||
onMomentumScrollBegin={[Function]}
|
||||
onMomentumScrollEnd={[Function]}
|
||||
onScroll={[Function]}
|
||||
onScrollBeginDrag={[Function]}
|
||||
onScrollEndDrag={[Function]}
|
||||
removeClippedSubviews={true}
|
||||
renderItem={[Function]}
|
||||
scrollEventThrottle={60}
|
||||
stickyHeaderIndices={[]}
|
||||
style={
|
||||
{
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
testID="UserListRow.section_list"
|
||||
>
|
||||
<View>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
style={null}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"backgroundColor": "#ffffff",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"backgroundColor": "rgba(63,67,80,0.08)",
|
||||
"height": 24,
|
||||
"justifyContent": "center",
|
||||
"paddingLeft": 16,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
{
|
||||
"color": "#3f4350",
|
||||
"fontFamily": "OpenSans-SemiBold",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "600",
|
||||
"lineHeight": 16,
|
||||
}
|
||||
}
|
||||
>
|
||||
J
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
style={null}
|
||||
>
|
||||
<View
|
||||
onMoveShouldSetResponder={[Function]}
|
||||
onMoveShouldSetResponderCapture={[Function]}
|
||||
onResponderEnd={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderReject={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderStart={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
onStartShouldSetResponderCapture={[Function]}
|
||||
>
|
||||
<View
|
||||
accessible={true}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"height": 58,
|
||||
"overflow": "hidden",
|
||||
"paddingHorizontal": 20,
|
||||
}
|
||||
}
|
||||
testID="create_direct_message.user_list.user_item.1"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
[
|
||||
{
|
||||
"alignItems": "center",
|
||||
"color": "#3f4350",
|
||||
"flexDirection": "row",
|
||||
},
|
||||
{
|
||||
"opacity": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"borderRadius": 21.5,
|
||||
"height": 42,
|
||||
"width": 42,
|
||||
}
|
||||
}
|
||||
testID="create_direct_message.user_list.user_item.1.profile_picture"
|
||||
>
|
||||
<Icon
|
||||
name="account-outline"
|
||||
size={24}
|
||||
style={
|
||||
{
|
||||
"color": "rgba(63,67,80,0.48)",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
[
|
||||
{
|
||||
"flex": 1,
|
||||
"flexDirection": "column",
|
||||
"justifyContent": "center",
|
||||
"paddingHorizontal": 10,
|
||||
},
|
||||
{
|
||||
"opacity": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"flexDirection": "row",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
{
|
||||
"color": "#3f4350",
|
||||
"fontFamily": "OpenSans",
|
||||
"fontSize": 16,
|
||||
"fontWeight": "400",
|
||||
"height": 24,
|
||||
"lineHeight": 24,
|
||||
"maxWidth": "80%",
|
||||
}
|
||||
}
|
||||
testID="create_direct_message.user_list.user_item.1.display_name"
|
||||
>
|
||||
johndoe
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
color="rgba(63,67,80,0.1024)"
|
||||
name="circle-outline"
|
||||
size={28}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
style={null}
|
||||
/>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<ActivityIndicator
|
||||
color="#1c58d9"
|
||||
size="large"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</RCTScrollView>
|
||||
`;
|
||||
|
||||
exports[`components/channel_list_row should show results no tutorial 1`] = `
|
||||
<RCTScrollView
|
||||
ListEmptyComponent={[Function]}
|
||||
ListFooterComponent={[Function]}
|
||||
contentContainerStyle={
|
||||
{
|
||||
"flexGrow": 1,
|
||||
}
|
||||
}
|
||||
data={
|
||||
[
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"auth_service": "",
|
||||
"create_at": 1111,
|
||||
"delete_at": 0,
|
||||
"email": "john@doe.com",
|
||||
"first_name": "",
|
||||
"id": "1",
|
||||
"last_name": "",
|
||||
"locale": "",
|
||||
"nickname": "",
|
||||
"notify_props": {
|
||||
"channel": "true",
|
||||
"comments": "never",
|
||||
"desktop": "mention",
|
||||
"desktop_sound": "true",
|
||||
"email": "true",
|
||||
"first_name": "true",
|
||||
"mention_keys": "",
|
||||
"push": "mention",
|
||||
"push_status": "away",
|
||||
},
|
||||
"position": "",
|
||||
"roles": "",
|
||||
"update_at": 1111,
|
||||
"username": "johndoe",
|
||||
},
|
||||
],
|
||||
"id": "J",
|
||||
},
|
||||
]
|
||||
}
|
||||
extraData={false}
|
||||
getItem={[Function]}
|
||||
getItemCount={[Function]}
|
||||
initialNumToRender={15}
|
||||
keyExtractor={[Function]}
|
||||
keyboardDismissMode="on-drag"
|
||||
keyboardShouldPersistTaps="always"
|
||||
maxToRenderPerBatch={16}
|
||||
onContentSizeChange={[Function]}
|
||||
onEndReached={[Function]}
|
||||
onLayout={[Function]}
|
||||
onMomentumScrollBegin={[Function]}
|
||||
onMomentumScrollEnd={[Function]}
|
||||
onScroll={[Function]}
|
||||
onScrollBeginDrag={[Function]}
|
||||
onScrollEndDrag={[Function]}
|
||||
removeClippedSubviews={true}
|
||||
renderItem={[Function]}
|
||||
scrollEventThrottle={60}
|
||||
stickyHeaderIndices={[]}
|
||||
style={
|
||||
{
|
||||
"backgroundColor": "#ffffff",
|
||||
"flex": 1,
|
||||
}
|
||||
}
|
||||
testID="UserListRow.section_list"
|
||||
>
|
||||
<View>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
style={null}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"backgroundColor": "#ffffff",
|
||||
}
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"backgroundColor": "rgba(63,67,80,0.08)",
|
||||
"height": 24,
|
||||
"justifyContent": "center",
|
||||
"paddingLeft": 16,
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
style={
|
||||
{
|
||||
"color": "#3f4350",
|
||||
"fontFamily": "OpenSans-SemiBold",
|
||||
"fontSize": 12,
|
||||
"fontWeight": "600",
|
||||
"lineHeight": 16,
|
||||
}
|
||||
}
|
||||
>
|
||||
J
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
style={null}
|
||||
>
|
||||
<View
|
||||
onMoveShouldSetResponder={[Function]}
|
||||
onMoveShouldSetResponderCapture={[Function]}
|
||||
onResponderEnd={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderReject={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderStart={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
onStartShouldSetResponderCapture={[Function]}
|
||||
>
|
||||
<View
|
||||
accessible={true}
|
||||
focusable={true}
|
||||
onClick={[Function]}
|
||||
onResponderGrant={[Function]}
|
||||
onResponderMove={[Function]}
|
||||
onResponderRelease={[Function]}
|
||||
onResponderTerminate={[Function]}
|
||||
onResponderTerminationRequest={[Function]}
|
||||
onStartShouldSetResponder={[Function]}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"height": 58,
|
||||
"overflow": "hidden",
|
||||
"paddingHorizontal": 20,
|
||||
}
|
||||
}
|
||||
testID="create_direct_message.user_list.user_item.1"
|
||||
>
|
||||
<View
|
||||
style={
|
||||
[
|
||||
{
|
||||
"alignItems": "center",
|
||||
"color": "#3f4350",
|
||||
"flexDirection": "row",
|
||||
},
|
||||
{
|
||||
"opacity": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"borderRadius": 21.5,
|
||||
"height": 42,
|
||||
"width": 42,
|
||||
}
|
||||
}
|
||||
testID="create_direct_message.user_list.user_item.1.profile_picture"
|
||||
>
|
||||
<Icon
|
||||
name="account-outline"
|
||||
size={24}
|
||||
style={
|
||||
{
|
||||
"color": "rgba(63,67,80,0.48)",
|
||||
}
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
[
|
||||
{
|
||||
"flex": 1,
|
||||
"flexDirection": "column",
|
||||
"justifyContent": "center",
|
||||
"paddingHorizontal": 10,
|
||||
},
|
||||
{
|
||||
"opacity": 1,
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"flexDirection": "row",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Text
|
||||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
{
|
||||
"color": "#3f4350",
|
||||
"fontFamily": "OpenSans",
|
||||
"fontSize": 16,
|
||||
"fontWeight": "400",
|
||||
"height": 24,
|
||||
"lineHeight": 24,
|
||||
"maxWidth": "80%",
|
||||
}
|
||||
}
|
||||
testID="create_direct_message.user_list.user_item.1.display_name"
|
||||
>
|
||||
johndoe
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"alignItems": "center",
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<Icon
|
||||
color="rgba(63,67,80,0.1024)"
|
||||
name="circle-outline"
|
||||
size={28}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
style={null}
|
||||
/>
|
||||
<View
|
||||
onLayout={[Function]}
|
||||
>
|
||||
<View
|
||||
style={
|
||||
{
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
}
|
||||
>
|
||||
<ActivityIndicator
|
||||
color="#1c58d9"
|
||||
size="large"
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</RCTScrollView>
|
||||
`;
|
||||
116
app/components/user_list/index.test.tsx
Normal file
116
app/components/user_list/index.test.tsx
Normal file
@@ -0,0 +1,116 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import Database from '@nozbe/watermelondb/Database';
|
||||
import React from 'react';
|
||||
|
||||
import {renderWithEverything} from '@test/intl-test-helper';
|
||||
import TestHelper from '@test/test_helper';
|
||||
|
||||
import UserList from '.';
|
||||
|
||||
describe('components/channel_list_row', () => {
|
||||
let database: Database;
|
||||
const user: UserProfile = {
|
||||
id: '1',
|
||||
create_at: 1111,
|
||||
update_at: 1111,
|
||||
delete_at: 0,
|
||||
username: 'johndoe',
|
||||
auth_service: '',
|
||||
email: 'john@doe.com',
|
||||
nickname: '',
|
||||
first_name: '',
|
||||
last_name: '',
|
||||
position: '',
|
||||
roles: '',
|
||||
locale: '',
|
||||
notify_props: {
|
||||
channel: 'true',
|
||||
comments: 'never',
|
||||
desktop: 'mention',
|
||||
desktop_sound: 'true',
|
||||
email: 'true',
|
||||
first_name: 'true',
|
||||
mention_keys: '',
|
||||
push: 'mention',
|
||||
push_status: 'away',
|
||||
},
|
||||
};
|
||||
beforeAll(async () => {
|
||||
const server = await TestHelper.setupServerDatabase();
|
||||
database = server.database;
|
||||
});
|
||||
|
||||
it('should show no results', () => {
|
||||
const wrapper = renderWithEverything(
|
||||
<UserList
|
||||
profiles={[user]}
|
||||
testID='UserListRow'
|
||||
currentUserId={'1'}
|
||||
teammateNameDisplay={'johndoe'}
|
||||
handleSelectProfile={() => {
|
||||
// noop
|
||||
}}
|
||||
fetchMore={() => {
|
||||
// noop
|
||||
}}
|
||||
loading={true}
|
||||
selectedIds={{}}
|
||||
showNoResults={true}
|
||||
tutorialWatched={true}
|
||||
/>,
|
||||
{database},
|
||||
);
|
||||
|
||||
expect(wrapper.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should show results no tutorial', () => {
|
||||
const wrapper = renderWithEverything(
|
||||
<UserList
|
||||
profiles={[user]}
|
||||
testID='UserListRow'
|
||||
currentUserId={'1'}
|
||||
teammateNameDisplay={'johndoe'}
|
||||
handleSelectProfile={() => {
|
||||
// noop
|
||||
}}
|
||||
fetchMore={() => {
|
||||
// noop
|
||||
}}
|
||||
loading={true}
|
||||
selectedIds={{}}
|
||||
showNoResults={true}
|
||||
tutorialWatched={true}
|
||||
/>,
|
||||
{database},
|
||||
);
|
||||
|
||||
expect(wrapper.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should show results and tutorial', () => {
|
||||
const wrapper = renderWithEverything(
|
||||
<UserList
|
||||
profiles={[user]}
|
||||
testID='UserListRow'
|
||||
currentUserId={'1'}
|
||||
teammateNameDisplay={'johndoe'}
|
||||
handleSelectProfile={() => {
|
||||
// noop
|
||||
}}
|
||||
fetchMore={() => {
|
||||
// noop
|
||||
}}
|
||||
loading={true}
|
||||
selectedIds={{}}
|
||||
showNoResults={false}
|
||||
tutorialWatched={false}
|
||||
/>,
|
||||
{database},
|
||||
);
|
||||
|
||||
expect(wrapper.toJSON()).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
280
app/components/user_list/index.tsx
Normal file
280
app/components/user_list/index.tsx
Normal file
@@ -0,0 +1,280 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useCallback, useMemo} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {FlatList, Keyboard, ListRenderItemInfo, Platform, SectionList, SectionListData, Text, View} from 'react-native';
|
||||
|
||||
import {storeProfile} from '@actions/local/user';
|
||||
import Loading from '@components/loading';
|
||||
import NoResultsWithTerm from '@components/no_results_with_term';
|
||||
import UserListRow from '@components/user_list_row';
|
||||
import {General, Screens} from '@constants';
|
||||
import {useServerUrl} from '@context/server';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {useKeyboardHeight} from '@hooks/device';
|
||||
import {openAsBottomSheet} from '@screens/navigation';
|
||||
import {
|
||||
changeOpacity,
|
||||
makeStyleSheetFromTheme,
|
||||
} from '@utils/theme';
|
||||
import {typography} from '@utils/typography';
|
||||
|
||||
const INITIAL_BATCH_TO_RENDER = 15;
|
||||
const SCROLL_EVENT_THROTTLE = 60;
|
||||
|
||||
const keyboardDismissProp = Platform.select({
|
||||
android: {
|
||||
onScrollBeginDrag: Keyboard.dismiss,
|
||||
},
|
||||
ios: {
|
||||
keyboardDismissMode: 'on-drag' as const,
|
||||
},
|
||||
});
|
||||
|
||||
const keyExtractor = (item: UserProfile) => {
|
||||
return item.id;
|
||||
};
|
||||
|
||||
const sectionKeyExtractor = (profile: UserProfile) => {
|
||||
// Group items alphabetically by first letter of username
|
||||
return profile.username[0].toUpperCase();
|
||||
};
|
||||
|
||||
export function createProfilesSections(profiles: UserProfile[]) {
|
||||
const sections: {[key: string]: UserProfile[]} = {};
|
||||
const sectionKeys: string[] = [];
|
||||
for (const profile of profiles) {
|
||||
const sectionKey = sectionKeyExtractor(profile);
|
||||
|
||||
if (!sections[sectionKey]) {
|
||||
sections[sectionKey] = [];
|
||||
sectionKeys.push(sectionKey);
|
||||
}
|
||||
|
||||
sections[sectionKey].push(profile);
|
||||
}
|
||||
|
||||
sectionKeys.sort();
|
||||
|
||||
return sectionKeys.map((sectionKey) => {
|
||||
return {
|
||||
id: sectionKey,
|
||||
data: sections[sectionKey],
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
||||
return {
|
||||
list: {
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
flex: 1,
|
||||
...Platform.select({
|
||||
android: {
|
||||
marginBottom: 20,
|
||||
},
|
||||
}),
|
||||
},
|
||||
container: {
|
||||
flexGrow: 1,
|
||||
},
|
||||
loadingContainer: {
|
||||
flex: 1,
|
||||
justifyContent: 'center' as const,
|
||||
alignItems: 'center' as const,
|
||||
},
|
||||
noResultContainer: {
|
||||
flexGrow: 1,
|
||||
alignItems: 'center' as const,
|
||||
justifyContent: 'center' as const,
|
||||
},
|
||||
sectionContainer: {
|
||||
backgroundColor: changeOpacity(theme.centerChannelColor, 0.08),
|
||||
paddingLeft: 16,
|
||||
justifyContent: 'center',
|
||||
height: 24,
|
||||
},
|
||||
sectionWrapper: {
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
sectionText: {
|
||||
color: theme.centerChannelColor,
|
||||
...typography('Body', 75, 'SemiBold'),
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
type Props = {
|
||||
profiles: UserProfile[];
|
||||
currentUserId: string;
|
||||
teammateNameDisplay: string;
|
||||
handleSelectProfile: (user: UserProfile) => void;
|
||||
fetchMore: () => void;
|
||||
loading: boolean;
|
||||
showNoResults: boolean;
|
||||
selectedIds: {[id: string]: UserProfile};
|
||||
testID?: string;
|
||||
term?: string;
|
||||
tutorialWatched: boolean;
|
||||
}
|
||||
|
||||
export default function UserList({
|
||||
profiles,
|
||||
selectedIds,
|
||||
currentUserId,
|
||||
teammateNameDisplay,
|
||||
handleSelectProfile,
|
||||
fetchMore,
|
||||
loading,
|
||||
showNoResults,
|
||||
term,
|
||||
testID,
|
||||
tutorialWatched,
|
||||
}: Props) {
|
||||
const intl = useIntl();
|
||||
const theme = useTheme();
|
||||
const serverUrl = useServerUrl();
|
||||
const style = getStyleFromTheme(theme);
|
||||
const keyboardHeight = useKeyboardHeight();
|
||||
const noResutsStyle = useMemo(() => [
|
||||
style.noResultContainer,
|
||||
{paddingBottom: keyboardHeight},
|
||||
], [style, keyboardHeight]);
|
||||
|
||||
const data = useMemo(() => {
|
||||
if (term) {
|
||||
return profiles;
|
||||
}
|
||||
return createProfilesSections(profiles);
|
||||
}, [term, profiles]);
|
||||
|
||||
const openUserProfile = useCallback(async (profile: UserProfile) => {
|
||||
const {user} = await storeProfile(serverUrl, profile);
|
||||
if (user) {
|
||||
const screen = Screens.USER_PROFILE;
|
||||
const title = intl.formatMessage({id: 'mobile.routes.user_profile', defaultMessage: 'Profile'});
|
||||
const closeButtonId = 'close-user-profile';
|
||||
const props = {
|
||||
closeButtonId,
|
||||
userId: user.id,
|
||||
location: Screens.USER_PROFILE,
|
||||
};
|
||||
|
||||
Keyboard.dismiss();
|
||||
openAsBottomSheet({screen, title, theme, closeButtonId, props});
|
||||
}
|
||||
}, []);
|
||||
|
||||
const renderItem = useCallback(({item, index, section}: ListRenderItemInfo<UserProfile> & {section?: SectionListData<UserProfile>}) => {
|
||||
// The list will re-render when the selection changes because it's passed into the list as extraData
|
||||
const selected = Boolean(selectedIds[item.id]);
|
||||
const canAdd = Object.keys(selectedIds).length < General.MAX_USERS_IN_GM;
|
||||
|
||||
return (
|
||||
<UserListRow
|
||||
key={item.id}
|
||||
highlight={section?.id === data?.[0].id && index === 0}
|
||||
id={item.id}
|
||||
isMyUser={currentUserId === item.id}
|
||||
onPress={handleSelectProfile}
|
||||
onLongPress={openUserProfile}
|
||||
selectable={canAdd}
|
||||
selected={selected}
|
||||
testID='create_direct_message.user_list.user_item'
|
||||
teammateNameDisplay={teammateNameDisplay}
|
||||
tutorialWatched={tutorialWatched}
|
||||
user={item}
|
||||
/>
|
||||
);
|
||||
}, [selectedIds, currentUserId, handleSelectProfile, teammateNameDisplay, tutorialWatched, data]);
|
||||
|
||||
const renderLoading = useCallback(() => {
|
||||
if (!loading) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<Loading
|
||||
color={theme.buttonBg}
|
||||
containerStyle={style.loadingContainer}
|
||||
size='large'
|
||||
/>
|
||||
);
|
||||
}, [loading, theme]);
|
||||
|
||||
const renderNoResults = useCallback(() => {
|
||||
if (!showNoResults || !term) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={noResutsStyle}>
|
||||
<NoResultsWithTerm term={term}/>
|
||||
</View>
|
||||
);
|
||||
}, [showNoResults && style, term, noResutsStyle]);
|
||||
|
||||
const renderSectionHeader = useCallback(({section}: {section: SectionListData<UserProfile>}) => {
|
||||
return (
|
||||
<View style={style.sectionWrapper}>
|
||||
<View style={style.sectionContainer}>
|
||||
<Text style={style.sectionText}>{section.id}</Text>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
}, [style]);
|
||||
|
||||
const renderFlatList = (items: UserProfile[]) => {
|
||||
return (
|
||||
<FlatList
|
||||
contentContainerStyle={style.container}
|
||||
data={items}
|
||||
extraData={selectedIds}
|
||||
keyboardShouldPersistTaps='always'
|
||||
{...keyboardDismissProp}
|
||||
keyExtractor={keyExtractor}
|
||||
initialNumToRender={INITIAL_BATCH_TO_RENDER}
|
||||
ListEmptyComponent={renderNoResults}
|
||||
ListFooterComponent={renderLoading}
|
||||
maxToRenderPerBatch={INITIAL_BATCH_TO_RENDER + 1}
|
||||
removeClippedSubviews={true}
|
||||
renderItem={renderItem}
|
||||
scrollEventThrottle={SCROLL_EVENT_THROTTLE}
|
||||
style={style.list}
|
||||
testID={`${testID}.flat_list`}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
const renderSectionList = (sections: Array<SectionListData<UserProfile>>) => {
|
||||
return (
|
||||
<SectionList
|
||||
contentContainerStyle={style.container}
|
||||
extraData={loading ? false : selectedIds}
|
||||
keyboardShouldPersistTaps='always'
|
||||
{...keyboardDismissProp}
|
||||
keyExtractor={keyExtractor}
|
||||
initialNumToRender={INITIAL_BATCH_TO_RENDER}
|
||||
ListEmptyComponent={renderNoResults}
|
||||
ListFooterComponent={renderLoading}
|
||||
maxToRenderPerBatch={INITIAL_BATCH_TO_RENDER + 1}
|
||||
removeClippedSubviews={true}
|
||||
renderItem={renderItem}
|
||||
renderSectionHeader={renderSectionHeader}
|
||||
scrollEventThrottle={SCROLL_EVENT_THROTTLE}
|
||||
sections={sections}
|
||||
style={style.list}
|
||||
stickySectionHeadersEnabled={false}
|
||||
testID={`${testID}.section_list`}
|
||||
onEndReached={fetchMore}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
if (term) {
|
||||
return renderFlatList(data as UserProfile[]);
|
||||
}
|
||||
return renderSectionList(data as Array<SectionListData<UserProfile>>);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user