diff --git a/package/src/components/ui/Avatar/UserAvatar.tsx b/package/src/components/ui/Avatar/UserAvatar.tsx index 02270a5045..c7265c0f49 100644 --- a/package/src/components/ui/Avatar/UserAvatar.tsx +++ b/package/src/components/ui/Avatar/UserAvatar.tsx @@ -5,7 +5,13 @@ import { StyleProp, StyleSheet, Text, View, ViewStyle } from 'react-native'; import { UserResponse } from 'stream-chat'; import { Avatar, AvatarProps } from './Avatar'; -import { fontSizes, iconSizes, indicatorSizes, numberOfInitials } from './constants'; +import { + fontSizes, + iconSizes, + indicatorPositions, + indicatorSizes, + numberOfInitials, +} from './constants'; import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { PeopleIcon } from '../../../icons/users'; @@ -57,7 +63,7 @@ export const UserAvatar = (props: UserAvatarProps) => { style={style} /> {showOnlineIndicator ? ( - + ) : null} @@ -71,8 +77,6 @@ const useStyles = () => { StyleSheet.create({ onlineIndicatorWrapper: { position: 'absolute', - right: -2, - top: -2, }, }), [], diff --git a/package/src/components/ui/Avatar/constants.ts b/package/src/components/ui/Avatar/constants.ts index c51cb594a9..61ececcf2b 100644 --- a/package/src/components/ui/Avatar/constants.ts +++ b/package/src/components/ui/Avatar/constants.ts @@ -41,6 +41,45 @@ const indicatorSizes: Record = { + xl: { + borderWidth: 2, + height: 16, + width: 16, + }, + lg: { + borderWidth: 2, + height: 14, + width: 14, + }, + md: { + borderWidth: 2, + height: 12, + width: 12, + }, + sm: { + borderWidth: 1, + height: 8, + width: 8, + }, +}; + +// Anchors the presence dot on the avatar's circular edge at 45°: +// offset = avatarWidth / 2 * (1 - Math.SQRT1_2) - indicatorDiameter / 2 (rounded to px) +const indicatorPositions = (Object.keys(avatarSizes) as UserAvatarProps['size'][]).reduce( + (acc, size) => { + const avatarDiameter = avatarSizes[size].width; + const indicatorDiameter = onlineIndicatorSizes[indicatorSizes[size]].width; + const offset = Math.round((avatarDiameter / 2) * (1 - Math.SQRT1_2) - indicatorDiameter / 2); + acc[size] = { right: offset, top: offset }; + return acc; + }, + {} as Record, +); + const iconSizes: Record = { xs: 10, sm: 12, @@ -99,4 +138,12 @@ const numberOfInitials: Record = { '2xl': 2, }; -export { indicatorSizes, iconSizes, fontSizes, numberOfInitials, avatarSizes }; +export { + indicatorSizes, + onlineIndicatorSizes, + indicatorPositions, + iconSizes, + fontSizes, + numberOfInitials, + avatarSizes, +}; diff --git a/package/src/components/ui/Badge/OnlineIndicator.tsx b/package/src/components/ui/Badge/OnlineIndicator.tsx index b6ea11273e..bcfeee4e3f 100644 --- a/package/src/components/ui/Badge/OnlineIndicator.tsx +++ b/package/src/components/ui/Badge/OnlineIndicator.tsx @@ -3,38 +3,24 @@ import { StyleSheet, View } from 'react-native'; import { useTheme } from '../../../contexts/themeContext/ThemeContext'; import { primitives } from '../../../theme'; +import { onlineIndicatorSizes } from '../Avatar/constants'; export type OnlineIndicatorProps = { online: boolean; size: 'xl' | 'lg' | 'sm' | 'md'; }; -const sizes = { - xl: { - borderWidth: 2, - height: 16, - width: 16, - }, - lg: { - borderWidth: 2, - height: 14, - width: 14, - }, - md: { - borderWidth: 2, - height: 12, - width: 12, - }, - sm: { - borderWidth: 1, - height: 8, - width: 8, - }, -}; - export const OnlineIndicator = ({ online, size = 'md' }: OnlineIndicatorProps) => { const styles = useStyles(); - return ; + return ( + + ); }; const useStyles = () => {