mattermost-mobile/app/screens/join_team/join_team.tsx
Elias Nahum 7aa5bd0611
Update Dependencies and bug fixes (#7000)
* update dependencies

* update dependencies

* feedback review

* update @mattermost/react-native-turbo-mailer
2023-01-24 09:14:23 +02:00

160 lines
5.1 KiB
TypeScript

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {View} from 'react-native';
import {addCurrentUserToTeam, fetchTeamsForComponent, handleTeamChange} from '@actions/remote/team';
import FormattedText from '@components/formatted_text';
import Empty from '@components/illustrations/no_team';
import Loading from '@components/loading';
import TeamList from '@components/team_list';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {dismissModal} from '@screens/navigation';
import {logDebug} from '@utils/log';
import {alertTeamAddError} from '@utils/navigation';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
joinedIds: Set<string>;
componentId: AvailableScreens;
closeButtonId: string;
}
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
container: {
paddingHorizontal: 10,
paddingVertical: 5,
flex: 1,
},
empty: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
loading: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
title: {
color: theme.centerChannelColor,
marginTop: 16,
...typography('Heading', 400, 'Regular'),
},
description: {
color: theme.centerChannelColor,
marginTop: 8,
maxWidth: 334,
...typography('Body', 200, 'Regular'),
},
}));
export default function JoinTeam({
joinedIds,
componentId,
closeButtonId,
}: Props) {
const serverUrl = useServerUrl();
const theme = useTheme();
const styles = getStyleSheet(theme);
const intl = useIntl();
const page = useRef(0);
const hasMore = useRef(true);
const mounted = useRef(true);
const [loading, setLoading] = useState(true);
const [joining, setJoining] = useState(false);
const [otherTeams, setOtherTeams] = useState<Team[]>([]);
const loadTeams = useCallback(async () => {
setLoading(true);
const resp = await fetchTeamsForComponent(serverUrl, page.current, joinedIds);
page.current = resp.page;
hasMore.current = resp.hasMore;
if (resp.teams.length && mounted.current) {
setOtherTeams((cur) => [...cur, ...resp.teams]);
}
setLoading(false);
}, [joinedIds, serverUrl]);
const onEndReached = useCallback(() => {
if (hasMore.current && !loading) {
loadTeams();
}
}, [loadTeams, loading]);
const onPress = useCallback(async (teamId: string) => {
setJoining(true);
const {error} = await addCurrentUserToTeam(serverUrl, teamId);
if (error) {
alertTeamAddError(error, intl);
logDebug('error joining a team:', error);
setJoining(false);
} else {
handleTeamChange(serverUrl, teamId);
dismissModal({componentId});
}
}, [serverUrl, componentId, intl]);
useEffect(() => {
loadTeams();
return () => {
mounted.current = false;
};
}, []);
const onClosePressed = useCallback(() => {
return dismissModal({componentId});
}, [componentId]);
useNavButtonPressed(closeButtonId, componentId, onClosePressed, []);
useAndroidHardwareBackHandler(componentId, onClosePressed);
const hasOtherTeams = Boolean(otherTeams.length);
let body;
if ((loading && !hasOtherTeams) || joining) {
body = (<Loading containerStyle={styles.loading}/>);
} else if (hasOtherTeams) {
body = (
<TeamList
teams={otherTeams}
onPress={onPress}
testID='team_sidebar.add_team_slide_up.team_list'
onEndReached={onEndReached}
loading={loading}
/>
);
} else {
body = (
<View style={styles.empty}>
<Empty theme={theme}/>
<FormattedText
id='team_list.no_other_teams.title'
defaultMessage='No additional teams to join'
style={styles.title}
testID='team_sidebar.add_team_slide_up.no_other_teams.title'
/>
<FormattedText
id='team_list.no_other_teams.description'
defaultMessage='To join another team, ask a Team Admin for an invitation, or create your own team.'
style={styles.description}
testID='team_sidebar.add_team_slide_up.no_other_teams.description'
/>
</View>
);
}
return (
<View style={styles.container}>
{body}
</View>
);
}