Skip to content

Comments

feat: channel list redesign#3418

Open
khushal87 wants to merge 7 commits intodevelopfrom
feat/channel-list-redesign
Open

feat: channel list redesign#3418
khushal87 wants to merge 7 commits intodevelopfrom
feat/channel-list-redesign

Conversation

@khushal87
Copy link
Member

This pull request introduces significant improvements to the channel preview and messaging experience, focusing on richer message previews, enhanced delivery status indicators, and improved flexibility in UI customization. The changes modernize the ChannelPreview and ChannelList components to better support draft messages, typing indicators, poll previews, and message delivery statuses, while also providing more control over the layout and appearance of muted status indicators.

Enhancements to Channel Preview and Message Status:

  • The ChannelPreview and related components now support richer message previews, including draft messages, typing indicators, poll previews, and error states. Message delivery status (sent, delivered, read) is now visually indicated for the latest message sent by the current user. [1] [2] [3] [4] [5] [6] [7]

UI Customization and Layout Improvements:

  • The mutedStatusPosition prop is added throughout the channel list and preview components, allowing the muted status indicator to be positioned either inline with the title or at the bottom of the preview. This prop is now part of the ChannelListProps and is passed through context to all relevant components. [1] [2] [3] [4] [5] [6] [7] [8]

Visual and Interaction Tweaks:

  • The channel preview UI is updated to use Pressable instead of TouchableOpacity for better feedback and flexibility, and the avatar size is increased for improved visibility. Layout and styling are modernized for consistency and accessibility. [1] [2]

Minor UI Adjustments:

  • The badge size in the image overlay component is reduced from large to small for a more compact appearance.
  • The UserAdd icon in the new direct messaging screen is now explicitly sized for consistency.

@Stream-SDK-Bot
Copy link
Contributor

Stream-SDK-Bot commented Feb 23, 2026

SDK Size

title develop branch diff status
js_bundle_size 429 KB 423 KB -5953 B 🚀

@khushal87 khushal87 marked this pull request as ready for review February 23, 2026 09:05
const paddingMedium = 12;
const paddingSmall = 8;

const AnimatedPath = Animated.createAnimatedComponent(Path);
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we no longer animating this ? What's the reason behind it ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Its animated but this is not required. I have added a simple SVG and the Animated view applies to the view. You can run the app to see it working.

return channel;
};

describe('useLatestMessagePreview', () => {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we deleting a bunch of tests ? I can't see them moved elsewhere (might be wrong though)

Copy link
Member Author

Choose a reason for hiding this comment

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

This hook is not relevant any more so its deleted. We have to properly write tests for MessagePreview component. I have it in my todo and there are a lot of edge cases, so I will handle it later. If you want I can spend time to add now. But the reason this is deleted, is the hook is non-relevant anymore.

voiceRecording: '🎙️',
} as const;

type LatestMessage = ReturnType<ChannelState['formatMessage']> | MessageResponse;
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we doing changes to ThreadList in a PR dedicated to ChannelList ?

Copy link
Member Author

Choose a reason for hiding this comment

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

To fix the build errors for now as MessagePreview has a different prop signature now. I will take care of it in ThreadList soon. Don't worry, I will make sure nothing would be broken.

"{{ index }} of {{ photoLength }}": "{{ index }} sur {{ photoLength }}",
"{{ replyCount }} Replies": "{{ replyCount }} Réponses",
"{{ user }} is typing": "{{ user }} est en train d'écrire",
"You voted: {{ option }}": "Vous avez voté: {{ option }}",
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we also removing the old translations which are no longer relevant ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Not yet, we can do that cleanup later. Once we know what's not used finally.

Copy link
Member Author

Choose a reason for hiding this comment

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

I can run over a check later to remove onces that are not used.

/>
<Path d='M12.9167 16.0718L9.23183 13.4187L8.33391 14.3167C8.35791 14.3312 8.3815 14.3467 8.40441 14.3632L12.5163 17.3238C13.2054 17.82 14.1667 17.3276 14.1667 16.4785V8.4839L12.9167 9.7339V16.0718Z' />
</Mask>
export const Mute = ({ height, width, ...rest }: IconProps) => (
Copy link
Contributor

Choose a reason for hiding this comment

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

Changing this also affects other parts of the code, such as the quick actions menu in the attachment picker. Has this been checked ?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I fixed in in the actions menu atleast.

<View style={[styles.container, container]}>
<MessagePreview previews={latestMessagePreview.previews} />
</View>
const { attachments } = useStateStore(
Copy link
Contributor

Choose a reason for hiding this comment

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

Please extract this in a separate hook. There's no reason for ChannelPreviewMessage to be updating every time the attachments change in messageComposer. These need to be decoupled.

const isFailedMessage =
lastMessage?.status === MessageStatusTypes.FAILED || lastMessage?.type === 'error';

const renderMessagePreview = (message: LocalMessage | MessageResponse | DraftMessage) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

The identity of this render function changes basically on every render, causing a bad cascading effect. Let's please fix this.

styles.subtitle,
{ color: message?.type === 'deleted' ? semantics.textTertiary : semantics.textSecondary },
]}
iconProps={{
Copy link
Contributor

Choose a reason for hiding this comment

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

Passing iconProps inline like so invalidates any potential memoization you've included downstream. In other words, every single React.memo that's added there is for nothing


const subtitle = useMemo(() => {
const attachments = message?.attachments;
const giphyAttachments = attachments?.filter(
Copy link
Contributor

Choose a reason for hiding this comment

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

Even though attachments will always have a very limited number of stuff inside, I'm really against this approach. You're allocating 6 arrays, just to check if arr.length > 0 further down. This is all work for the garbage collector going forward, for every ChannelPreview, all the time. Can we at the very least do something a bit more optimal and .reduce a Map or an Set which tells us what types of attachments this message has ? We can even add it to some general purpose hook or whatever.

Copy link
Contributor

Choose a reason for hiding this comment

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

(and it will automatically work for pretty much anything going forward)

Copy link
Contributor

Choose a reason for hiding this comment

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

PS: I just saw that this is how it was done before as well, so just to be clear - not saying it was introduced in this PR but let's maybe simplify it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants