diff --git a/app/components/channel_list_row/__snapshots__/index.test.tsx.snap b/app/components/channel_list_row/__snapshots__/index.test.tsx.snap
new file mode 100644
index 000000000..fdba65fb5
--- /dev/null
+++ b/app/components/channel_list_row/__snapshots__/index.test.tsx.snap
@@ -0,0 +1,470 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`components/channel_list_row should be selected 1`] = `
+
+
+
+
+
+
+ channel
+
+
+ My purpose
+
+
+
+
+
+
+
+
+`;
+
+exports[`components/channel_list_row should match snapshot with delete_at filled in 1`] = `
+
+
+
+
+
+
+ channel
+
+
+
+
+
+`;
+
+exports[`components/channel_list_row should match snapshot with open channel icon 1`] = `
+
+
+
+
+
+
+ channel
+
+
+
+
+
+`;
+
+exports[`components/channel_list_row should match snapshot with private channel icon 1`] = `
+
+
+
+
+
+
+ channel
+
+
+
+
+
+`;
+
+exports[`components/channel_list_row should match snapshot with purpose filled in 1`] = `
+
+
+
+
+
+
+ channel
+
+
+ My purpose
+
+
+
+
+
+`;
+
+exports[`components/channel_list_row should match snapshot with shared filled in 1`] = `
+
+
+
+
+
+
+ channel
+
+
+
+
+
+`;
diff --git a/app/components/channel_list_row/index.test.tsx b/app/components/channel_list_row/index.test.tsx
new file mode 100644
index 000000000..b2493116d
--- /dev/null
+++ b/app/components/channel_list_row/index.test.tsx
@@ -0,0 +1,151 @@
+// 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 ChannelListRow from '.';
+
+describe('components/channel_list_row', () => {
+ let database: Database;
+ const channel: Channel = {
+ id: '1',
+ create_at: 1111,
+ update_at: 1111,
+ delete_at: 0,
+ team_id: 'my team',
+ type: 'O',
+ display_name: 'channel',
+ name: 'channel',
+ header: 'channel',
+ purpose: '',
+ last_post_at: 1,
+ total_msg_count: 1,
+ extra_update_at: 1,
+ creator_id: '1',
+ scheme_id: null,
+ group_constrained: null,
+ shared: true,
+ };
+ beforeAll(async () => {
+ const server = await TestHelper.setupServerDatabase();
+ database = server.database;
+ });
+
+ it('should match snapshot with open channel icon', () => {
+ const wrapper = renderWithEverything(
+ {
+ // noop
+ }}
+ />,
+ {database},
+ );
+
+ expect(wrapper.toJSON()).toMatchSnapshot();
+ });
+
+ it('should match snapshot with private channel icon', () => {
+ channel.type = 'P';
+
+ const wrapper = renderWithEverything(
+ {
+ // noop
+ }}
+ />,
+ {database},
+ );
+
+ expect(wrapper.toJSON()).toMatchSnapshot();
+ });
+
+ it('should match snapshot with delete_at filled in', () => {
+ channel.delete_at = 1111;
+ channel.shared = false;
+ channel.type = 'O';
+
+ const wrapper = renderWithEverything(
+ {
+ // noop
+ }}
+ />,
+ {database},
+ );
+
+ expect(wrapper.toJSON()).toMatchSnapshot();
+ });
+
+ it('should match snapshot with shared filled in', () => {
+ channel.delete_at = 0;
+ channel.shared = true;
+ channel.type = 'O';
+
+ const wrapper = renderWithEverything(
+ {
+ // noop
+ }}
+ />,
+ {database},
+ );
+
+ expect(wrapper.toJSON()).toMatchSnapshot();
+ });
+
+ it('should match snapshot with purpose filled in', () => {
+ channel.purpose = 'My purpose';
+
+ const wrapper = renderWithEverything(
+ {
+ // noop
+ }}
+ />,
+ {database},
+ );
+
+ expect(wrapper.toJSON()).toMatchSnapshot();
+ });
+
+ it('should be selected', () => {
+ const wrapper = renderWithEverything(
+ {
+ // noop
+ }}
+ />,
+ {database},
+ );
+
+ expect(wrapper.toJSON()).toMatchSnapshot();
+ });
+});
diff --git a/app/screens/browse_channels/channel_list_row.tsx b/app/components/channel_list_row/index.tsx
similarity index 81%
rename from app/screens/browse_channels/channel_list_row.tsx
rename to app/components/channel_list_row/index.tsx
index 11e471251..68c864735 100644
--- a/app/screens/browse_channels/channel_list_row.tsx
+++ b/app/components/channel_list_row/index.tsx
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import React from 'react';
+import React, {useMemo} from 'react';
import {
Text,
TouchableOpacity,
@@ -17,6 +17,8 @@ type Props = {
channel: Channel;
onPress: (channel: Channel) => void;
testID?: string;
+ selectable?: boolean;
+ selected?: boolean;
}
const getStyleFromTheme = makeStyleSheetFromTheme((theme: Theme) => {
@@ -51,6 +53,8 @@ export default function ChannelListRow({
channel,
onPress,
testID,
+ selectable = false,
+ selected = false,
}: Props) {
const theme = useTheme();
const style = getStyleFromTheme(theme);
@@ -59,6 +63,23 @@ export default function ChannelListRow({
onPress(channel);
};
+ const selectionIcon = useMemo(() => {
+ if (!selectable) {
+ return null;
+ }
+
+ const color = selected ? theme.buttonBg : theme.centerChannelColor;
+ return (
+
+
+
+ );
+ }, [selectable, selected, theme]);
+
let purposeComponent;
if (channel.purpose) {
purposeComponent = (
@@ -105,6 +126,7 @@ export default function ChannelListRow({
{purposeComponent}
+ {selectionIcon}
diff --git a/app/screens/browse_channels/channel_list.tsx b/app/screens/browse_channels/channel_list.tsx
index 8534690b5..3b48bc8c0 100644
--- a/app/screens/browse_channels/channel_list.tsx
+++ b/app/screens/browse_channels/channel_list.tsx
@@ -4,6 +4,7 @@
import React, {useCallback, useMemo} from 'react';
import {View, FlatList} from 'react-native';
+import ChannelListRow from '@components/channel_list_row';
import FormattedText from '@components/formatted_text';
import Loading from '@components/loading';
import NoResultsWithTerm from '@components/no_results_with_term';
@@ -11,8 +12,6 @@ import {useTheme} from '@context/theme';
import {useKeyboardHeight} from '@hooks/device';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
-import ChannelListRow from './channel_list_row';
-
type Props = {
onEndReached: () => void;
loading: boolean;