diff --git a/native/avatars/avatar-constants.js b/native/avatars/avatar-constants.js new file mode 100644 index 000000000..8d024dd72 --- /dev/null +++ b/native/avatars/avatar-constants.js @@ -0,0 +1,13 @@ +// @flow + +export const xSmallAvatarSize = 16; + +export const smallAvatarSize = 24; + +export const mediumAvatarSize = 40; + +export const largeAvatarSize = 90; + +export const xLargeAvatarSize = 112; + +export const xxLargeAvatarSize = 224; diff --git a/native/avatars/avatar.react.js b/native/avatars/avatar.react.js index 5ea4527f1..40f7ffb8d 100644 --- a/native/avatars/avatar.react.js +++ b/native/avatars/avatar.react.js @@ -1,156 +1,164 @@ // @flow import * as React from 'react'; import { View, Text, StyleSheet } from 'react-native'; import type { ResolvedClientAvatar, AvatarSize, } from 'lib/types/avatar-types.js'; +import { + xSmallAvatarSize, + smallAvatarSize, + mediumAvatarSize, + largeAvatarSize, + xLargeAvatarSize, + xxLargeAvatarSize, +} from './avatar-constants.js'; import Multimedia from '../media/multimedia.react.js'; type Props = { +avatarInfo: ResolvedClientAvatar, +size: AvatarSize, }; function Avatar(props: Props): React.Node { const { avatarInfo, size } = props; const containerSizeStyle = React.useMemo(() => { if (size === 'XS') { return styles.xSmall; } else if (size === 'S') { return styles.small; } else if (size === 'M') { return styles.medium; } else if (size === 'L') { return styles.large; } else if (size === 'XL') { return styles.xLarge; } return styles.xxLarge; }, [size]); const emojiContainerStyle = React.useMemo(() => { const containerStyles = [styles.emojiContainer, containerSizeStyle]; if (avatarInfo.type === 'emoji') { const backgroundColor = { backgroundColor: `#${avatarInfo.color}` }; containerStyles.push(backgroundColor); } return containerStyles; }, [avatarInfo, containerSizeStyle]); const emojiSizeStyle = React.useMemo(() => { if (size === 'XS') { return styles.emojiXSmall; } else if (size === 'S') { return styles.emojiSmall; } else if (size === 'M') { return styles.emojiMedium; } else if (size === 'L') { return styles.emojiLarge; } else if (size === 'XL') { return styles.emojiXLarge; } return styles.emojiXXLarge; }, [size]); const avatar = React.useMemo(() => { if (avatarInfo.type === 'image') { const avatarMediaInfo = { type: 'photo', uri: avatarInfo.uri, }; return ( ); } return ( {avatarInfo.emoji} ); }, [ avatarInfo.emoji, avatarInfo.type, avatarInfo.uri, containerSizeStyle, emojiContainerStyle, emojiSizeStyle, ]); return avatar; } const styles = StyleSheet.create({ emojiContainer: { alignItems: 'center', justifyContent: 'center', }, emojiLarge: { fontSize: 64, textAlign: 'center', }, emojiMedium: { fontSize: 28, textAlign: 'center', }, emojiSmall: { fontSize: 14, textAlign: 'center', }, emojiXLarge: { fontSize: 80, textAlign: 'center', }, emojiXSmall: { fontSize: 9, textAlign: 'center', }, emojiXXLarge: { fontSize: 176, textAlign: 'center', }, imageContainer: { overflow: 'hidden', }, large: { - borderRadius: 45, - height: 90, - width: 90, + borderRadius: largeAvatarSize / 2, + height: largeAvatarSize, + width: largeAvatarSize, }, medium: { - borderRadius: 20, - height: 40, - width: 40, + borderRadius: mediumAvatarSize / 2, + height: mediumAvatarSize, + width: mediumAvatarSize, }, small: { - borderRadius: 12, - height: 24, - width: 24, + borderRadius: smallAvatarSize / 2, + height: smallAvatarSize, + width: smallAvatarSize, }, xLarge: { - borderRadius: 56, - height: 112, - width: 112, + borderRadius: xLargeAvatarSize / 2, + height: xLargeAvatarSize, + width: xLargeAvatarSize, }, xSmall: { - borderRadius: 8, - height: 16, - width: 16, + borderRadius: xSmallAvatarSize / 2, + height: xSmallAvatarSize, + width: xSmallAvatarSize, }, xxLarge: { - borderRadius: 112, - height: 224, - width: 224, + borderRadius: xxLargeAvatarSize / 2, + height: xxLargeAvatarSize, + width: xxLargeAvatarSize, }, }); export default Avatar; diff --git a/native/user-profile/user-profile-avatar-modal.react.js b/native/user-profile/user-profile-avatar-modal.react.js index ad40261f3..2088fd757 100644 --- a/native/user-profile/user-profile-avatar-modal.react.js +++ b/native/user-profile/user-profile-avatar-modal.react.js @@ -1,49 +1,50 @@ // @flow import * as React from 'react'; import type { Dimensions } from 'lib/types/media-types.js'; import type { UserProfileBottomSheetNavigationProp } from './user-profile-bottom-sheet-navigator.react.js'; +import { xxLargeAvatarSize } from '../avatars/avatar-constants.js'; import UserAvatar from '../avatars/user-avatar.react.js'; import FullScreenViewModal from '../components/full-screen-view-modal.react.js'; import type { NavigationRoute } from '../navigation/route-names.js'; import { type VerticalBounds, type LayoutCoordinates, } from '../types/layout-types.js'; const avatarDimensions: Dimensions = { - width: 224, - height: 224, + width: xxLargeAvatarSize, + height: xxLargeAvatarSize, }; export type UserProfileAvatarModalParams = { +presentedFrom: string, +initialCoordinates: LayoutCoordinates, +verticalBounds: VerticalBounds, +userID: ?string, }; type Props = { +navigation: UserProfileBottomSheetNavigationProp<'UserProfileAvatarModal'>, +route: NavigationRoute<'UserProfileAvatarModal'>, }; function UserProfileAvatarModal(props: Props): React.Node { const { navigation, route } = props; const { userID } = route.params; return ( ); } export default UserProfileAvatarModal;