Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 7 additions & 10 deletions examples/SampleApp/src/components/ChannelInfoOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import Animated, {
withTiming,
} from 'react-native-reanimated';
import {
Avatar,
CircleClose,
Delete,
User,
UserMinus,
useTheme,
useViewport,
UserAvatar,
} from 'stream-chat-react-native';
import { ChannelMemberResponse } from 'stream-chat';

Expand All @@ -34,8 +34,6 @@ import { SafeAreaView } from 'react-native-safe-area-context';

dayjs.extend(relativeTime);

const avatarSize = 64;

const styles = StyleSheet.create({
avatarPresenceIndicator: {
right: 5,
Expand Down Expand Up @@ -83,7 +81,7 @@ const styles = StyleSheet.create({
fontSize: 14,
fontWeight: '700',
},
userItemContainer: { marginHorizontal: 8, width: 64 },
userItemContainer: { marginHorizontal: 8, alignItems: 'center' },
userName: {
fontSize: 12,
fontWeight: '600',
Expand Down Expand Up @@ -311,13 +309,12 @@ export const ChannelInfoOverlay = (props: ChannelInfoOverlayProps) => {
renderItem={({ item }) =>
item ? (
<View style={styles.userItemContainer}>
<Avatar
image={item.image}
name={item.name || item.id}
online={item.online}
presenceIndicatorContainerStyle={styles.avatarPresenceIndicator}
size={avatarSize}
<UserAvatar
user={item}
size='md'
showOnlineIndicator={item.online}
/>

<Text style={[styles.userName, { color: black }]}>
{item.name || item.id || ''}
</Text>
Expand Down
4 changes: 2 additions & 2 deletions examples/SampleApp/src/components/MessageInfoBottomSheet.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import React, { useMemo } from 'react';
import {
Avatar,
BottomSheetModal,
useChatContext,
useMessageDeliveredData,
useMessageReadData,
useTheme,
UserAvatar,
} from 'stream-chat-react-native';
import { LocalMessage, UserResponse } from 'stream-chat';
import { FlatList, StyleSheet, Text, View } from 'react-native';

const renderUserItem = ({ item }: { item: UserResponse }) => (
<View style={styles.userItem}>
<Avatar image={item.image} name={item.name ?? item.id} size={32} />
<UserAvatar user={item} size={'md'} />
<Text style={styles.userName}>{item.name ?? item.id}</Text>
</View>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { FlatList, StyleSheet, Text, TouchableOpacity, View } from 'react-native
import { NavigationProp, useNavigation } from '@react-navigation/native';
import dayjs from 'dayjs';
import calendar from 'dayjs/plugin/calendar';
import { Avatar, Spinner, useTheme, useViewport } from 'stream-chat-react-native';
import { Spinner, useTheme, useViewport, UserAvatar } from 'stream-chat-react-native';
import { DEFAULT_PAGINATION_LIMIT } from '../../utils/constants';

import type { MessageResponse } from 'stream-chat';
Expand All @@ -27,6 +27,8 @@ const styles = StyleSheet.create({
justifyContent: 'center',
},
itemContainer: {
alignItems: 'center',
justifyContent: 'center',
borderBottomWidth: 1,
flex: 1,
flexDirection: 'row',
Expand Down Expand Up @@ -131,12 +133,8 @@ export const MessageSearchList: React.FC<MessageSearchListProps> = React.forward
style={[styles.itemContainer, { borderBottomColor: border.surfaceSubtle }]}
testID='channel-preview-button'
>
<Avatar
image={item.user?.image}
name={item.user?.name}
online={item?.user?.online}
size={40}
/>
<UserAvatar user={item.user} size={'lg'} />

<View style={styles.flex}>
<View style={styles.row}>
<Text
Expand Down
20 changes: 7 additions & 13 deletions examples/SampleApp/src/components/UserInfoOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import Animated, {
withTiming,
} from 'react-native-reanimated';
import {
Avatar,
CircleClose,
MessageIcon,
useChatContext,
User,
UserMinus,
useTheme,
useViewport,
UserAvatar,
} from 'stream-chat-react-native';

import { useAppOverlayContext } from '../context/AppOverlayContext';
Expand All @@ -35,8 +35,6 @@ import { SafeAreaView } from 'react-native-safe-area-context';

dayjs.extend(relativeTime);

const avatarSize = 64;

const styles = StyleSheet.create({
avatarPresenceIndicator: {
right: 5,
Expand Down Expand Up @@ -77,10 +75,7 @@ const styles = StyleSheet.create({
fontWeight: '700',
},
userItemContainer: {
marginHorizontal: 8,
paddingBottom: 24,
paddingTop: 16,
width: 64,
paddingVertical: 16,
},
userName: {
fontSize: 12,
Expand Down Expand Up @@ -269,12 +264,11 @@ export const UserInfoOverlay = (props: UserInfoOverlayProps) => {
: `Last Seen ${dayjs(member.user?.last_active).fromNow()}`}
</Text>
<View style={styles.userItemContainer}>
<Avatar
image={member.user?.image}
name={member.user?.name || member.user?.id}
online={member.user?.online}
presenceIndicatorContainerStyle={styles.avatarPresenceIndicator}
size={avatarSize}
<UserAvatar
user={member.user}
size='lg'
showBorder
showOnlineIndicator={member.user?.online}
/>
</View>
</View>
Expand Down
14 changes: 3 additions & 11 deletions examples/SampleApp/src/components/UserSearch/UserGridItem.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { TouchableOpacity } from '@gorhom/bottom-sheet';
import { Avatar, Close, useTheme } from 'stream-chat-react-native';
import { Close, useTheme, UserAvatar } from 'stream-chat-react-native';

import type { UserResponse } from 'stream-chat';


const presenceIndicator = { cx: 7, cy: 7, r: 5 };

const styles = StyleSheet.create({
presenceIndicatorContainer: {
bottom: 0,
Expand Down Expand Up @@ -55,13 +52,8 @@ export const UserGridItem: React.FC<UserGridItemProps> = ({
} = useTheme();
return (
<TouchableOpacity key={user.id} onPress={onPress} style={styles.selectedUserItemContainer}>
<Avatar
image={user.image}
online={user.online}
presenceIndicator={presenceIndicator}
presenceIndicatorContainerStyle={styles.presenceIndicatorContainer}
size={64}
/>
<UserAvatar user={user} size='lg' showOnlineIndicator={user.online} showBorder />

{removeButton && (
<View
style={[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
} from 'react-native';
import dayjs from 'dayjs';
import Svg, { Defs, LinearGradient, Rect, Stop } from 'react-native-svg';
import { Avatar, CheckSend, Close, useTheme, useViewport } from 'stream-chat-react-native';
import { CheckSend, Close, useTheme, useViewport, UserAvatar } from 'stream-chat-react-native';

import { useUserSearchContext } from '../../context/UserSearchContext';

Expand Down Expand Up @@ -203,7 +203,7 @@ export const UserSearchResults: React.FC<UserSearchResultsProps> = ({
},
]}
>
<Avatar image={item.image} name={item.name} size={40} />
<UserAvatar user={item} size={'lg'} />
<View style={styles.searchResultUserDetails}>
<Text
style={[
Expand Down
20 changes: 18 additions & 2 deletions examples/SampleApp/src/screens/ChannelScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { useHeaderHeight } from '@react-navigation/elements';
import { RouteProp, useFocusEffect, useNavigation } from '@react-navigation/native';
import {
Channel,
ChannelAvatar,
MessageInput,
MessageList,
MessageFlashList,
Expand All @@ -17,6 +16,9 @@ import {
AITypingIndicatorView,
useTranslationContext,
MessageActionsParams,
UserAvatar,
ChannelAvatar,
useChannelPreviewDisplayPresence,
} from 'stream-chat-react-native';
import { Pressable, StyleSheet, View } from 'react-native';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
Expand Down Expand Up @@ -53,6 +55,7 @@ const ChannelHeader: React.FC<ChannelHeaderProps> = ({ channel }) => {
const { closePicker } = useAttachmentPickerContext();
const membersStatus = useChannelMembersStatus(channel);
const displayName = useChannelPreviewDisplayName(channel, 30);
const online = useChannelPreviewDisplayPresence(channel);
const { isOnline } = useChatContext();
const { chatClient } = useAppContext();
const navigation = useNavigation<ChannelScreenNavigationProp>();
Expand Down Expand Up @@ -92,6 +95,10 @@ const ChannelHeader: React.FC<ChannelHeaderProps> = ({ channel }) => {
return null;
}

const members = channel.state.members;
const membersValues = Object.values(members);
const otherMembers = membersValues.filter((member) => member.user?.id !== chatClient?.user?.id);

return (
<ScreenHeader
onBack={onBackPress}
Expand All @@ -103,7 +110,16 @@ const ChannelHeader: React.FC<ChannelHeaderProps> = ({ channel }) => {
opacity: pressed ? 0.5 : 1,
})}
>
<ChannelAvatar channel={channel} />
{otherMembers.length === 1 ? (
<UserAvatar
size='lg'
user={otherMembers[0].user}
showBorder={otherMembers[0].user?.image ? true : false}
showOnlineIndicator={online}
/>
) : (
<ChannelAvatar channel={channel} size='lg' />
)}
</Pressable>
)}
showUnreadCountBadge
Expand Down
12 changes: 6 additions & 6 deletions examples/SampleApp/src/screens/GroupChannelDetailsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ import {
import { RouteProp, useNavigation } from '@react-navigation/native';
import { SafeAreaView } from 'react-native-safe-area-context';
import {
Avatar,
useChannelPreviewDisplayName,
useOverlayContext,
useTheme,
UserAvatar,
} from 'stream-chat-react-native';

import { RoundButton } from '../components/RoundButton';
Expand Down Expand Up @@ -281,11 +281,11 @@ export const GroupChannelDetailsScreen: React.FC<GroupChannelDetailsProps> = ({
]}
>
<View style={styles.memberRow}>
<Avatar
image={member.user?.image}
name={member.user?.name}
online={member.user?.online}
size={40}
<UserAvatar
user={member.user}
size={'lg'}
showOnlineIndicator={member.user?.online}
showBorder
/>
<View style={styles.memberDetails}>
<Text style={[{ color: black }, styles.memberName]}>{member.user?.name}</Text>
Expand Down
29 changes: 15 additions & 14 deletions examples/SampleApp/src/screens/SharedGroupsScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import React from 'react';
import React, { useMemo } from 'react';
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { NavigationProp, RouteProp, useNavigation } from '@react-navigation/native';
import {
Avatar,
ChannelList,
ChannelListMessenger,
ChannelListMessengerProps,
Expand All @@ -12,6 +11,8 @@ import {
useChannelPreviewDisplayName,
useChannelsContext,
useTheme,
Avatar,
getInitialsFromName,
} from 'stream-chat-react-native';

import { ScreenHeader } from '../components/ScreenHeader';
Expand Down Expand Up @@ -66,6 +67,16 @@ const CustomPreview: React.FC<CustomPreviewProps> = ({ channel }) => {
},
} = useTheme();

const displayAvatar = getChannelPreviewDisplayAvatar(channel, chatClient);

const placeholder = useMemo(() => {
if (displayAvatar?.name) {
return <Text style={{ color: '#003179' }}>{getInitialsFromName(displayAvatar?.name)}</Text>;
} else {
return <Text style={{ color: '#003179' }}>?</Text>;
}
}, [displayAvatar.name]);

if (!chatClient) {
return null;
}
Expand All @@ -74,8 +85,6 @@ const CustomPreview: React.FC<CustomPreviewProps> = ({ channel }) => {
return null;
}

const displayAvatar = getChannelPreviewDisplayAvatar(channel, chatClient);

const switchToChannel = () => {
navigation.reset({
index: 1,
Expand Down Expand Up @@ -106,17 +115,9 @@ const CustomPreview: React.FC<CustomPreviewProps> = ({ channel }) => {
>
<View style={styles.groupContainer}>
{displayAvatar.images ? (
<GroupAvatar
images={displayAvatar.images}
names={displayAvatar.names}
size={40}
/>
<GroupAvatar images={displayAvatar.images} names={displayAvatar.names} size={40} />
) : (
<Avatar
image={displayAvatar.image}
name={displayAvatar.name}
size={40}
/>
<Avatar image={displayAvatar.image} placeholder={placeholder} size={'lg'} />
)}
<Text style={[styles.nameText, { color: black }]}>{name}</Text>
</View>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,28 @@ import { useTheme } from '../../contexts/themeContext/ThemeContext';
import { AtMentions } from '../../icons/AtMentions';
import type { Emoji } from '../../types/types';

import { Avatar } from '../Avatar/Avatar';
import { UserAvatar } from '../ui/Avatar/UserAvatar';

export type AutoCompleteSuggestionItemProps = {
itemProps: TextComposerSuggestion;
triggerType?: string;
};

export const MentionSuggestionItem = (item: UserSuggestion) => {
const { id, image, name, online } = item;
const { id, name, online } = item;
const {
theme: {
colors: { accent_blue, black },
messageInput: {
suggestions: {
mention: { avatarSize, column, container: mentionContainer, name: nameStyle },
mention: { column, container: mentionContainer, name: nameStyle },
},
},
},
} = useTheme();
return (
<View style={[styles.container, mentionContainer]}>
<Avatar image={image} name={name} online={online} size={avatarSize} />
<UserAvatar user={item} size='md' showOnlineIndicator={online} />
Copy link

Copilot AI Jan 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The showOnlineIndicator prop is being set to the value of 'online' (a boolean), but it should control whether to show the indicator at all, not pass the online status. The UserAvatar component should determine the online status from the user object itself. Consider changing this to just 'showOnlineIndicator' without a value, or 'showOnlineIndicator={true}'.

Copilot uses AI. Check for mistakes.
<View style={[styles.column, column]}>
<Text style={[styles.name, { color: black }, nameStyle]} testID='mentions-item-name'>
{name || id}
Expand Down
Loading
Loading