diff --git a/lib/types/avatar-types.js b/lib/types/avatar-types.js index f25dd57db..b8872df2f 100644 --- a/lib/types/avatar-types.js +++ b/lib/types/avatar-types.js @@ -1,81 +1,81 @@ // @flow import t, { type TUnion, type TInterface } from 'tcomb'; import type { CreateUpdatesResult } from './update-types.js'; import { validHexColorRegex } from '../shared/account-utils.js'; import { onlyOneEmojiRegex } from '../shared/emojis.js'; import { tRegex, tShape, tString } from '../utils/validation-utils.js'; export type EmojiAvatarDBContent = { +type: 'emoji', +emoji: string, +color: string, // hex, without "#" or "0x" }; export const emojiAvatarDBContentValidator: TInterface = tShape({ type: tString('emoji'), emoji: tRegex(onlyOneEmojiRegex), color: tRegex(validHexColorRegex), }); export type ImageAvatarDBContent = { +type: 'image', +uploadID: string, }; export type ENSAvatarDBContent = { +type: 'ens', }; export const ensAvatarDBContentValidator: TInterface = tShape({ type: tString('ens') }); export type AvatarDBContent = | EmojiAvatarDBContent | ImageAvatarDBContent | ENSAvatarDBContent; export type UpdateUserAvatarRemoveRequest = { +type: 'remove' }; export type UpdateUserAvatarRequest = | AvatarDBContent | UpdateUserAvatarRemoveRequest; export type ClientEmojiAvatar = EmojiAvatarDBContent; const clientEmojiAvatarValidator = emojiAvatarDBContentValidator; export type ClientImageAvatar = { +type: 'image', +uri: string, }; const clientImageAvatarValidator = tShape({ type: tString('image'), uri: t.String, }); export type ClientENSAvatar = ENSAvatarDBContent; const clientENSAvatarValidator = ensAvatarDBContentValidator; export type ClientAvatar = | ClientEmojiAvatar | ClientImageAvatar | ClientENSAvatar; export const clientAvatarValidator: TUnion = t.union([ clientEmojiAvatarValidator, clientImageAvatarValidator, clientENSAvatarValidator, ]); export type ResolvedClientAvatar = ClientEmojiAvatar | ClientImageAvatar; export type UpdateUserAvatarResponse = { +updates: CreateUpdatesResult, }; export type GenericUserInfoWithAvatar = { +username?: ?string, +avatar?: ?ClientAvatar, ... }; -export type AvatarSize = 'XS' | 'S' | 'M' | 'L' | 'XL'; +export type AvatarSize = 'XS' | 'S' | 'M' | 'L' | 'XL' | 'XXL'; diff --git a/native/avatars/avatar.react.js b/native/avatars/avatar.react.js index 5713e7e92..5ea4527f1 100644 --- a/native/avatars/avatar.react.js +++ b/native/avatars/avatar.react.js @@ -1,143 +1,156 @@ // @flow import * as React from 'react'; import { View, Text, StyleSheet } from 'react-native'; import type { ResolvedClientAvatar, AvatarSize, } from 'lib/types/avatar-types.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.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.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, }, medium: { borderRadius: 20, height: 40, width: 40, }, small: { borderRadius: 12, height: 24, width: 24, }, xLarge: { borderRadius: 56, height: 112, width: 112, }, xSmall: { borderRadius: 8, height: 16, width: 16, }, + xxLarge: { + borderRadius: 112, + height: 224, + width: 224, + }, }); export default Avatar;