[Gekidou MM-46195] Fix team picker height (#6554)
This commit is contained in:
parent
f55976a2c3
commit
f376b3f6af
9 changed files with 92 additions and 90 deletions
|
|
@ -64,7 +64,7 @@ export default function AddTeamSlideUp({otherTeams, title, showTitle = true}: Pr
|
|||
}
|
||||
}, [serverUrl]);
|
||||
|
||||
const hasOtherTeams = otherTeams.length;
|
||||
const hasOtherTeams = Boolean(otherTeams.length);
|
||||
|
||||
return (
|
||||
<BottomSheetContent
|
||||
|
|
|
|||
|
|
@ -4,13 +4,15 @@
|
|||
import React, {useCallback} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {useWindowDimensions, View} from 'react-native';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import TouchableWithFeedback from '@components/touchable_with_feedback';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {useIsTablet} from '@hooks/device';
|
||||
import {bottomSheetWithTeamList} from '@screens/navigation';
|
||||
import {bottomSheet} from '@screens/navigation';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {getTeamsSnapHeight} from '@utils/team_list';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import AddTeamSlideUp from './add_team_slide_up';
|
||||
|
|
@ -48,6 +50,7 @@ export default function AddTeam({otherTeams}: Props) {
|
|||
const styles = getStyleSheet(theme);
|
||||
const dimensions = useWindowDimensions();
|
||||
const intl = useIntl();
|
||||
const insets = useSafeAreaInsets();
|
||||
const isTablet = useIsTablet();
|
||||
|
||||
const onPress = useCallback(preventDoubleTap(() => {
|
||||
|
|
@ -62,12 +65,13 @@ export default function AddTeam({otherTeams}: Props) {
|
|||
);
|
||||
};
|
||||
|
||||
bottomSheetWithTeamList({
|
||||
dimensions,
|
||||
const height = getTeamsSnapHeight({dimensions, teams: otherTeams, insets});
|
||||
bottomSheet({
|
||||
closeButtonId: 'close-team_list',
|
||||
renderContent,
|
||||
snapPoints: [height, 10],
|
||||
theme,
|
||||
title,
|
||||
teams: otherTeams,
|
||||
});
|
||||
}), [otherTeams, intl, isTablet, dimensions, theme]);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,22 +22,16 @@ type Props = {
|
|||
onPress: (teamId: string) => void;
|
||||
}
|
||||
|
||||
const CONTAINER_HEIGHT = 40;
|
||||
const CONTAINER_VERTICAL_MARGIN = 8;
|
||||
export const ITEM_HEIGHT = CONTAINER_HEIGHT + (CONTAINER_VERTICAL_MARGIN * 2);
|
||||
export const ITEM_HEIGHT = 56;
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
return {
|
||||
container: {
|
||||
height: CONTAINER_HEIGHT,
|
||||
marginVertical: CONTAINER_VERTICAL_MARGIN,
|
||||
},
|
||||
touchable: {
|
||||
height: ITEM_HEIGHT,
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
borderRadius: 4,
|
||||
alignItems: 'center',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
},
|
||||
text: {
|
||||
|
|
@ -69,39 +63,37 @@ export default function TeamListItem({team, textColor, iconTextColor, iconBackgr
|
|||
}, [team.id, onPress]);
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<TouchableWithFeedback
|
||||
onPress={handlePress}
|
||||
type='opacity'
|
||||
style={styles.touchable}
|
||||
<TouchableWithFeedback
|
||||
onPress={handlePress}
|
||||
type='opacity'
|
||||
style={styles.touchable}
|
||||
>
|
||||
<View style={styles.icon_container}>
|
||||
<TeamIcon
|
||||
id={team.id}
|
||||
displayName={displayName}
|
||||
lastIconUpdate={lastTeamIconUpdateAt}
|
||||
selected={false}
|
||||
textColor={iconTextColor || theme.centerChannelColor}
|
||||
backgroundColor={iconBackgroundColor || changeOpacity(theme.centerChannelColor, 0.16)}
|
||||
testID={`${teamListItemTestId}.team_icon`}
|
||||
/>
|
||||
</View>
|
||||
<Text
|
||||
style={[styles.text, textColor && {color: textColor}]}
|
||||
numberOfLines={1}
|
||||
>
|
||||
<View style={styles.icon_container}>
|
||||
<TeamIcon
|
||||
id={team.id}
|
||||
displayName={displayName}
|
||||
lastIconUpdate={lastTeamIconUpdateAt}
|
||||
selected={false}
|
||||
textColor={iconTextColor || theme.centerChannelColor}
|
||||
backgroundColor={iconBackgroundColor || changeOpacity(theme.centerChannelColor, 0.16)}
|
||||
testID={`${teamListItemTestId}.team_icon`}
|
||||
/>
|
||||
</View>
|
||||
<Text
|
||||
style={[styles.text, textColor && {color: textColor}]}
|
||||
numberOfLines={1}
|
||||
>
|
||||
{displayName}
|
||||
</Text>
|
||||
{(team.id === selectedTeamId) &&
|
||||
<View style={styles.compassContainer}>
|
||||
<CompassIcon
|
||||
color={theme.buttonBg}
|
||||
name='check'
|
||||
size={24}
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
</TouchableWithFeedback>
|
||||
</View>
|
||||
{displayName}
|
||||
</Text>
|
||||
{(team.id === selectedTeamId) &&
|
||||
<View style={styles.compassContainer}>
|
||||
<CompassIcon
|
||||
color={theme.buttonBg}
|
||||
name='check'
|
||||
size={24}
|
||||
/>
|
||||
</View>
|
||||
}
|
||||
</TouchableWithFeedback>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,8 +27,8 @@ const TITLE_MARGIN_TOP = 4;
|
|||
const TITLE_MARGIN_BOTTOM = 12;
|
||||
|
||||
export const TITLE_HEIGHT = TITLE_MARGIN_TOP + TITLE_MARGIN_BOTTOM + 30; // typography 600 line height
|
||||
export const SEPARATOR_MARGIN = 12;
|
||||
export const SEPARATOR_MARGIN_TABLET = 20;
|
||||
export const TITLE_SEPARATOR_MARGIN = 12;
|
||||
export const TITLE_SEPARATOR_MARGIN_TABLET = 20;
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||
return {
|
||||
|
|
@ -76,14 +76,14 @@ const BottomSheetContent = ({buttonText, buttonIcon, children, disableButton, on
|
|||
</View>
|
||||
}
|
||||
{titleSeparator &&
|
||||
<View style={[styles.separator, {width: separatorWidth, marginBottom: (isTablet ? SEPARATOR_MARGIN_TABLET : SEPARATOR_MARGIN)}]}/>
|
||||
<View style={[styles.separator, {width: separatorWidth, marginBottom: (isTablet ? TITLE_SEPARATOR_MARGIN_TABLET : TITLE_SEPARATOR_MARGIN)}]}/>
|
||||
}
|
||||
<>
|
||||
{children}
|
||||
</>
|
||||
{showButton && (
|
||||
<>
|
||||
<View style={[styles.separator, {width: separatorWidth, marginBottom: (isTablet ? SEPARATOR_MARGIN_TABLET : SEPARATOR_MARGIN)}]}/>
|
||||
<View style={[styles.separator, {width: separatorWidth, marginBottom: (isTablet ? TITLE_SEPARATOR_MARGIN_TABLET : TITLE_SEPARATOR_MARGIN)}]}/>
|
||||
<Button
|
||||
disabled={disableButton}
|
||||
onPress={onPress}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ type SlideUpPanelProps = {
|
|||
testID?: string;
|
||||
}
|
||||
|
||||
export const PADDING_TOP_MOBILE = 20;
|
||||
|
||||
const BottomSheet = ({closeButtonId, componentId, initialSnapIndex = 0, renderContent, snapPoints = ['90%', '50%', 50], testID}: SlideUpPanelProps) => {
|
||||
const sheetRef = useRef<RNBottomSheet>(null);
|
||||
const dimensions = useWindowDimensions();
|
||||
|
|
@ -116,7 +118,7 @@ const BottomSheet = ({closeButtonId, componentId, initialSnapIndex = 0, renderCo
|
|||
backgroundColor: theme.centerChannelBg,
|
||||
opacity: 1,
|
||||
paddingHorizontal: 20,
|
||||
paddingTop: isTablet ? 0 : 20,
|
||||
paddingTop: isTablet ? 0 : PADDING_TOP_MOBILE,
|
||||
height: '100%',
|
||||
width: isTablet ? '100%' : Math.min(dimensions.width, 450),
|
||||
alignSelf: 'center',
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import Badge from '@components/badge';
|
|||
import CompassIcon from '@components/compass_icon';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {useIsTablet} from '@hooks/device';
|
||||
import {SEPARATOR_MARGIN, SEPARATOR_MARGIN_TABLET, TITLE_HEIGHT} from '@screens/bottom_sheet/content';
|
||||
import {TITLE_SEPARATOR_MARGIN, TITLE_SEPARATOR_MARGIN_TABLET, TITLE_HEIGHT} from '@screens/bottom_sheet/content';
|
||||
import {bottomSheet} from '@screens/navigation';
|
||||
import {FileFilter, FileFilters} from '@utils/file';
|
||||
import {bottomSheetSnapPoint} from '@utils/helpers';
|
||||
|
|
@ -90,7 +90,7 @@ const Header = ({
|
|||
NUMBER_FILTER_ITEMS,
|
||||
FILTER_ITEM_HEIGHT,
|
||||
bottom,
|
||||
) + TITLE_HEIGHT + DIVIDERS_HEIGHT + (isTablet ? SEPARATOR_MARGIN_TABLET : SEPARATOR_MARGIN),
|
||||
) + TITLE_HEIGHT + DIVIDERS_HEIGHT + (isTablet ? TITLE_SEPARATOR_MARGIN_TABLET : TITLE_SEPARATOR_MARGIN),
|
||||
10];
|
||||
}, []);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,13 +4,15 @@
|
|||
import React, {useCallback} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {View, useWindowDimensions} from 'react-native';
|
||||
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import TeamIcon from '@components/team_sidebar/team_list/team_item/team_icon';
|
||||
import TouchableWithFeedback from '@components/touchable_with_feedback';
|
||||
import {useTheme} from '@context/theme';
|
||||
import {bottomSheetWithTeamList} from '@screens/navigation';
|
||||
import {bottomSheet} from '@screens/navigation';
|
||||
import {preventDoubleTap} from '@utils/tap';
|
||||
import {getTeamsSnapHeight} from '@utils/team_list';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import SelectTeamSlideUp from './search_team_slideup';
|
||||
|
|
@ -52,6 +54,7 @@ const TeamPickerIcon = ({size = 24, divider = false, setTeamId, teams, teamId}:
|
|||
const theme = useTheme();
|
||||
const dimensions = useWindowDimensions();
|
||||
const styles = getStyleFromTheme(theme);
|
||||
const insets = useSafeAreaInsets();
|
||||
|
||||
const selectedTeam = teams.find((t) => t.id === teamId);
|
||||
|
||||
|
|
@ -69,12 +72,13 @@ const TeamPickerIcon = ({size = 24, divider = false, setTeamId, teams, teamId}:
|
|||
);
|
||||
};
|
||||
|
||||
bottomSheetWithTeamList({
|
||||
dimensions,
|
||||
const height = getTeamsSnapHeight({dimensions, teams, insets});
|
||||
bottomSheet({
|
||||
closeButtonId: 'close-team_list',
|
||||
renderContent,
|
||||
snapPoints: [height, 10],
|
||||
theme,
|
||||
title,
|
||||
teams,
|
||||
});
|
||||
}), [theme, setTeamId, teamId, teams]);
|
||||
|
||||
|
|
|
|||
|
|
@ -4,23 +4,19 @@
|
|||
/* eslint-disable max-lines */
|
||||
|
||||
import merge from 'deepmerge';
|
||||
import {Appearance, ScaledSize, DeviceEventEmitter, NativeModules, StatusBar, Platform, Alert} from 'react-native';
|
||||
import {Appearance, DeviceEventEmitter, NativeModules, StatusBar, Platform, Alert} from 'react-native';
|
||||
import {ImageResource, Navigation, Options, OptionsModalPresentationStyle, OptionsTopBarButton} from 'react-native-navigation';
|
||||
import tinyColor from 'tinycolor2';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import {ITEM_HEIGHT} from '@components/team_sidebar/add_team/team_list_item/team_list_item';
|
||||
import {Device, Events, Screens, Navigation as NavigationConstants, Launch} from '@constants';
|
||||
import {NOT_READY} from '@constants/screens';
|
||||
import {getDefaultThemeByAppearance} from '@context/theme';
|
||||
import {TITLE_HEIGHT} from '@screens/bottom_sheet/content';
|
||||
import EphemeralStore from '@store/ephemeral_store';
|
||||
import NavigationStore from '@store/navigation_store';
|
||||
import {bottomSheetSnapPoint} from '@utils/helpers';
|
||||
import {appearanceControlledScreens, mergeNavigationOptions} from '@utils/navigation';
|
||||
import {changeOpacity, setNavigatorStyles} from '@utils/theme';
|
||||
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
import type {LaunchProps} from '@typings/launch';
|
||||
import type {NavButtons} from '@typings/screens/navigation';
|
||||
|
||||
|
|
@ -666,34 +662,6 @@ export async function bottomSheet({title, renderContent, snapPoints, initialSnap
|
|||
}
|
||||
}
|
||||
|
||||
type BottomSheetWithTeamListArgs = {
|
||||
teams: TeamModel[];
|
||||
dimensions: ScaledSize;
|
||||
renderContent: () => JSX.Element;
|
||||
theme: Theme;
|
||||
title: string;
|
||||
}
|
||||
|
||||
export async function bottomSheetWithTeamList({title, teams, dimensions, renderContent, theme}: BottomSheetWithTeamListArgs) {
|
||||
const NO_TEAMS_HEIGHT = 392;
|
||||
const maxHeight = Math.round((dimensions.height * 0.9));
|
||||
|
||||
let height = NO_TEAMS_HEIGHT;
|
||||
if (teams.length) {
|
||||
const itemsHeight = bottomSheetSnapPoint(teams.length, ITEM_HEIGHT, 0);
|
||||
const heightWithHeader = TITLE_HEIGHT + itemsHeight;
|
||||
height = Math.min(maxHeight, heightWithHeader);
|
||||
}
|
||||
|
||||
bottomSheet({
|
||||
closeButtonId: 'close-team_list',
|
||||
renderContent,
|
||||
snapPoints: [height, 10],
|
||||
theme,
|
||||
title,
|
||||
});
|
||||
}
|
||||
|
||||
export async function dismissBottomSheet(alternativeScreen = Screens.BOTTOM_SHEET) {
|
||||
DeviceEventEmitter.emit(Events.CLOSE_BOTTOM_SHEET);
|
||||
await NavigationStore.waitUntilScreensIsRemoved(alternativeScreen);
|
||||
|
|
|
|||
32
app/utils/team_list/index.ts
Normal file
32
app/utils/team_list/index.ts
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {ScaledSize} from 'react-native';
|
||||
import {EdgeInsets} from 'react-native-safe-area-context';
|
||||
|
||||
import {ITEM_HEIGHT} from '@components/team_sidebar/add_team/team_list_item/team_list_item';
|
||||
import {PADDING_TOP_MOBILE} from '@screens/bottom_sheet';
|
||||
import {TITLE_HEIGHT, TITLE_SEPARATOR_MARGIN} from '@screens/bottom_sheet/content';
|
||||
import {bottomSheetSnapPoint} from '@utils/helpers';
|
||||
|
||||
import type TeamModel from '@typings/database/models/servers/team';
|
||||
|
||||
type TeamsSnapProps = {
|
||||
teams: TeamModel[];
|
||||
dimensions: ScaledSize;
|
||||
insets: EdgeInsets;
|
||||
}
|
||||
|
||||
const NO_TEAMS_HEIGHT = 392;
|
||||
export const getTeamsSnapHeight = ({dimensions, teams, insets}: TeamsSnapProps) => {
|
||||
let height = NO_TEAMS_HEIGHT;
|
||||
if (teams.length) {
|
||||
const itemsHeight = bottomSheetSnapPoint(teams.length, ITEM_HEIGHT, 0);
|
||||
const heightWithHeader = PADDING_TOP_MOBILE +
|
||||
TITLE_HEIGHT + (TITLE_SEPARATOR_MARGIN * 2) +
|
||||
itemsHeight + insets.bottom;
|
||||
const maxHeight = Math.round((dimensions.height * 0.9));
|
||||
height = Math.min(maxHeight, heightWithHeader);
|
||||
}
|
||||
return height;
|
||||
};
|
||||
Loading…
Reference in a new issue