From da31c9c3cf961926cace4b3b57bc8950776f8783 Mon Sep 17 00:00:00 2001 From: Javier Aguirre Date: Tue, 22 Nov 2022 10:00:20 +0100 Subject: [PATCH] [MM-48515] Reuse ChannelListRow component to make it selectable maintaining compatibility (#6778) * Moving ChannelListRow to component * selectable --- .../__snapshots__/index.test.tsx.snap | 470 ++++++++++++++++++ .../channel_list_row/index.test.tsx | 151 ++++++ .../channel_list_row/index.tsx} | 24 +- app/screens/browse_channels/channel_list.tsx | 3 +- 4 files changed, 645 insertions(+), 3 deletions(-) create mode 100644 app/components/channel_list_row/__snapshots__/index.test.tsx.snap create mode 100644 app/components/channel_list_row/index.test.tsx rename app/{screens/browse_channels/channel_list_row.tsx => components/channel_list_row/index.tsx} (81%) 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;