From 3f91c3a47d40f62591580d77a6604655473b945a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Espino?= Date: Wed, 1 Dec 2021 08:07:04 +0100 Subject: [PATCH] [Gekidou] Adding logic to hide the list of teams on the teams sidebar when needed (#5790) --- .../__snapshots__/index.test.tsx.snap | 16 +++- app/components/channel_list/channel_list.tsx | 89 ------------------- .../header/__snapshots__/header.test.tsx.snap | 16 +++- app/components/channel_list/header/header.tsx | 18 ++-- app/components/channel_list/index.test.tsx | 2 +- app/components/channel_list/index.tsx | 88 +++++++++++++++--- app/components/team_sidebar/team_sidebar.tsx | 79 +++++++++------- .../{index.tsx => channel_list.tsx} | 17 ++-- app/screens/home/channel_list/index.ts | 20 +++++ 9 files changed, 201 insertions(+), 144 deletions(-) delete mode 100644 app/components/channel_list/channel_list.tsx rename app/screens/home/channel_list/{index.tsx => channel_list.tsx} (83%) create mode 100644 app/screens/home/channel_list/index.ts diff --git a/app/components/channel_list/__snapshots__/index.test.tsx.snap b/app/components/channel_list/__snapshots__/index.test.tsx.snap index ceb36db65..20c0ff279 100644 --- a/app/components/channel_list/__snapshots__/index.test.tsx.snap +++ b/app/components/channel_list/__snapshots__/index.test.tsx.snap @@ -38,7 +38,21 @@ exports[`components/channel_list should match snapshot 1`] = ` } } > - + ({ - container: { - flex: 1, - backgroundColor: theme.sidebarBg, - paddingHorizontal: 20, - paddingVertical: 10, - }, - -})); - -type ChannelListProps = { - iconPad?: boolean; - isTablet: boolean; - teamsCount: number; -} - -const ChannelList = ({iconPad, isTablet, teamsCount}: ChannelListProps) => { - const theme = useTheme(); - const styles = getStyleSheet(theme); - const tabletWidth = useSharedValue(TABLET_SIDEBAR_WIDTH); - const tabletStyle = useAnimatedStyle(() => { - if (!isTablet) { - return { - maxWidth: undefined, - }; - } - - return {maxWidth: withTiming(tabletWidth.value, {duration: 250})}; - }, []); - - useEffect(() => { - if (isTablet) { - tabletWidth.value = TABLET_SIDEBAR_WIDTH - (teamsCount > 1 ? TEAM_SIDEBAR_WIDTH : 0); - } - }, [isTablet, teamsCount]); - - // @to-do; remove after testing - const [showCats, setShowCats] = useState(true); - - return ( - - setShowCats(!showCats)}> - - - - {showCats && ( - <> - - - - )} - {/* */} - {!showCats && ()} - - ); -}; - -export default ChannelList; diff --git a/app/components/channel_list/header/__snapshots__/header.test.tsx.snap b/app/components/channel_list/header/__snapshots__/header.test.tsx.snap index d66877d5c..743aabe9f 100644 --- a/app/components/channel_list/header/__snapshots__/header.test.tsx.snap +++ b/app/components/channel_list/header/__snapshots__/header.test.tsx.snap @@ -1,7 +1,21 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`components/channel_list/header Channel List Header Component should match snapshot 1`] = ` - + ({ color: changeOpacity(theme.sidebarText, 0.64), ...typography('Heading', 50), }, - iconPad: { - marginLeft: 44, - }, headerRow: { flexDirection: 'row', alignItems: 'center', @@ -57,10 +55,18 @@ const getStyles = makeStyleSheetFromTheme((theme: Theme) => ({ const ChannelListHeader = ({displayName, iconPad}: Props) => { const theme = useTheme(); const serverDisplayName = useServerDisplayName(); + const marginLeft = useSharedValue(iconPad ? 44 : 0); const styles = getStyles(theme); + const animatedStyle = useAnimatedStyle(() => ({ + marginLeft: withTiming(marginLeft.value, {duration: 350}), + }), []); + + useEffect(() => { + marginLeft.value = iconPad ? 44 : 0; + }, [iconPad]); return ( - + @@ -83,7 +89,7 @@ const ChannelListHeader = ({displayName, iconPad}: Props) => { {serverDisplayName} - + ); }; diff --git a/app/components/channel_list/index.test.tsx b/app/components/channel_list/index.test.tsx index 361a1c2d9..4933e4006 100644 --- a/app/components/channel_list/index.test.tsx +++ b/app/components/channel_list/index.test.tsx @@ -9,7 +9,7 @@ import {TeamModel} from '@database/models/server'; import {renderWithEverything} from '@test/intl-test-helper'; import TestHelper from '@test/test_helper'; -import ChannelsList from './channel_list'; +import ChannelsList from './index'; describe('components/channel_list', () => { let database: Database; diff --git a/app/components/channel_list/index.tsx b/app/components/channel_list/index.tsx index 89773fec1..89d070863 100644 --- a/app/components/channel_list/index.tsx +++ b/app/components/channel_list/index.tsx @@ -1,20 +1,88 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; -import withObservables from '@nozbe/with-observables'; +import React, {useEffect, useState} from 'react'; +import {TouchableOpacity} from 'react-native-gesture-handler'; +import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; -import {MM_TABLES} from '@constants/database'; -import MyTeamModel from '@typings/database/models/servers/my_team'; +import {TABLET_SIDEBAR_WIDTH, TEAM_SIDEBAR_WIDTH} from '@constants/view'; +import {useTheme} from '@context/theme'; +import {makeStyleSheetFromTheme} from '@utils/theme'; -import ChannelsList from './channel_list'; +import Categories from './categories'; +import ChannelListHeader from './header'; +import LoadingError from './loading_error'; +import SearchField from './search'; -import type {WithDatabaseArgs} from '@typings/database/database'; +// import Loading from '@components/loading'; -const {SERVER: {MY_TEAM}} = MM_TABLES; +const channels: TempoChannel[] = [ + {id: '1', name: 'Just a channel'}, + {id: '2', name: 'A Highlighted Channel!!!', highlight: true}, + {id: '3', name: 'And a longer channel name.'}, +]; + +const categories: TempoCategory[] = [ + {id: '1', title: 'My first Category', channels}, + {id: '2', title: 'Another Cat', channels}, +]; + +const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ + container: { + flex: 1, + backgroundColor: theme.sidebarBg, + paddingHorizontal: 20, + paddingVertical: 10, + }, -const enhanced = withObservables([], ({database}: WithDatabaseArgs) => ({ - teamsCount: database.get(MY_TEAM).query().observeCount(), })); -export default withDatabase(enhanced(ChannelsList)); +type ChannelListProps = { + iconPad?: boolean; + isTablet: boolean; + teamsCount: number; +} + +const ChannelList = ({iconPad, isTablet, teamsCount}: ChannelListProps) => { + const theme = useTheme(); + const styles = getStyleSheet(theme); + const tabletWidth = useSharedValue(TABLET_SIDEBAR_WIDTH); + const tabletStyle = useAnimatedStyle(() => { + if (!isTablet) { + return { + maxWidth: undefined, + }; + } + + return {maxWidth: withTiming(tabletWidth.value, {duration: 350})}; + }, []); + + useEffect(() => { + if (isTablet) { + tabletWidth.value = TABLET_SIDEBAR_WIDTH - (teamsCount > 1 ? TEAM_SIDEBAR_WIDTH : 0); + } + }, [isTablet, teamsCount]); + + const [showCats, setShowCats] = useState(true); + + return ( + + setShowCats(!showCats)}> + + + + {showCats && ( + <> + + + + )} + {/* */} + {!showCats && ()} + + ); +}; + +export default ChannelList; diff --git a/app/components/team_sidebar/team_sidebar.tsx b/app/components/team_sidebar/team_sidebar.tsx index 17844656d..afec0bd52 100644 --- a/app/components/team_sidebar/team_sidebar.tsx +++ b/app/components/team_sidebar/team_sidebar.tsx @@ -2,7 +2,7 @@ // See LICENSE.txt for license information. import React, {useEffect} from 'react'; -import {View} from 'react-native'; +import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated'; import {fetchAllTeams} from '@actions/remote/team'; import {TEAM_SIDEBAR_WIDTH} from '@constants/view'; @@ -17,34 +17,9 @@ import type TeamModel from '@typings/database/models/servers/team'; type Props = { canCreateTeams: boolean; - otherTeams: TeamModel[]; iconPad?: boolean; -} - -export default function TeamSidebar({canCreateTeams, otherTeams, iconPad}: Props) { - const theme = useTheme(); - const styles = getStyleSheet(theme); - const serverUrl = useServerUrl(); - - useEffect(() => { - fetchAllTeams(serverUrl); - }, [serverUrl]); - - const showAddTeam = canCreateTeams || otherTeams.length > 0; - - return ( - - - - {showAddTeam && ( - - )} - - - ); + otherTeams: TeamModel[]; + teamsCount: number; } const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { @@ -53,7 +28,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { width: TEAM_SIDEBAR_WIDTH, height: '100%', backgroundColor: theme.sidebarBg, - display: 'flex', paddingTop: 10, }, listContainer: { @@ -63,7 +37,52 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => { }, iconMargin: { marginTop: 44, - paddingTop: 0, }, }; }); + +export default function TeamSidebar({canCreateTeams, iconPad, otherTeams, teamsCount}: Props) { + const showAddTeam = canCreateTeams || otherTeams.length > 0; + const initialWidth = teamsCount > 1 ? TEAM_SIDEBAR_WIDTH : 0; + const width = useSharedValue(initialWidth); + const marginTop = useSharedValue(iconPad ? 44 : 0); + const theme = useTheme(); + const serverUrl = useServerUrl(); + const styles = getStyleSheet(theme); + + const transform = useAnimatedStyle(() => { + return { + width: withTiming(width.value, {duration: 350}), + }; + }, []); + + const serverStyle = useAnimatedStyle(() => ({ + marginTop: withTiming(marginTop.value, {duration: 350}), + }), []); + + useEffect(() => { + marginTop.value = iconPad ? 44 : 0; + }, [iconPad]); + + useEffect(() => { + fetchAllTeams(serverUrl); + }, [serverUrl]); + + useEffect(() => { + width.value = teamsCount > 1 ? TEAM_SIDEBAR_WIDTH : 0; + }, [teamsCount]); + + return ( + + + + {showAddTeam && ( + + )} + + + ); +} diff --git a/app/screens/home/channel_list/index.tsx b/app/screens/home/channel_list/channel_list.tsx similarity index 83% rename from app/screens/home/channel_list/index.tsx rename to app/screens/home/channel_list/channel_list.tsx index 4d3102a14..545851c29 100644 --- a/app/screens/home/channel_list/index.tsx +++ b/app/screens/home/channel_list/channel_list.tsx @@ -1,6 +1,7 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. +import {useManagedConfig} from '@mattermost/react-native-emm'; import {useIsFocused, useRoute} from '@react-navigation/native'; import React from 'react'; import {View} from 'react-native'; @@ -18,6 +19,7 @@ import {makeStyleSheetFromTheme} from '@utils/theme'; import type {LaunchProps} from '@typings/launch'; type ChannelProps = LaunchProps & { + teamsCount: number; time?: number; }; @@ -43,12 +45,14 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({ const ChannelListScreen = (props: ChannelProps) => { const theme = useTheme(); const styles = getStyleSheet(theme); + const managedConfig = useManagedConfig(); const isTablet = useIsTablet(); const route = useRoute(); const isFocused = useIsFocused(); const insets = useSafeAreaInsets(); const params = route.params as {direction: string}; + const canAddOtherServers = managedConfig?.allowOtherServers !== 'false'; const animated = useAnimatedStyle(() => { if (!isFocused) { @@ -74,17 +78,18 @@ const ChannelListScreen = (props: ChannelProps) => { style={styles.content} edges={['bottom', 'left', 'right']} > - + {canAddOtherServers && } - {/* @to-do: Server Icon requires padding in the team and channel components: - * https://mattermost.atlassian.net/browse/MM-39702 - */} - + {isTablet && diff --git a/app/screens/home/channel_list/index.ts b/app/screens/home/channel_list/index.ts new file mode 100644 index 000000000..89773fec1 --- /dev/null +++ b/app/screens/home/channel_list/index.ts @@ -0,0 +1,20 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; +import withObservables from '@nozbe/with-observables'; + +import {MM_TABLES} from '@constants/database'; +import MyTeamModel from '@typings/database/models/servers/my_team'; + +import ChannelsList from './channel_list'; + +import type {WithDatabaseArgs} from '@typings/database/database'; + +const {SERVER: {MY_TEAM}} = MM_TABLES; + +const enhanced = withObservables([], ({database}: WithDatabaseArgs) => ({ + teamsCount: database.get(MY_TEAM).query().observeCount(), +})); + +export default withDatabase(enhanced(ChannelsList));