Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
4 changes: 3 additions & 1 deletion analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ linter:
- avoid_null_checks_in_equality_operators
- avoid_positional_boolean_parameters
- avoid_private_typedef_functions
- avoid_redundant_argument_values
# Does not always make sense to remove them; it also makes it hard
# to notice future breaking changes.
# - avoid_redundant_argument_values
- avoid_return_types_on_setters
- avoid_returning_null_for_void
- avoid_shadowing_type_parameters
Expand Down
6 changes: 6 additions & 0 deletions melos.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ command:
stream_chat_persistence: ^10.0.0-beta.12
streaming_shared_preferences: ^2.0.0
svg_icon_widget: ^0.0.1
# TODO: Replace with hosted version before merging PR
stream_core_flutter:
git:
url: https://github.com/GetStream/stream-core-flutter.git
ref: c066cb481bd8a8523e5ea52f3433ffeaeab11332
path: packages/stream_core_flutter
synchronized: ^3.1.0+1
thumblr: ^0.0.4
url_launcher: ^6.3.0
Expand Down
50 changes: 50 additions & 0 deletions migrations/redesign/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# Stream Chat Flutter UI Redesign Migration Guide

This folder contains migration guides for the redesigned UI components in Stream Chat Flutter SDK.

## Overview

The redesigned components aim to provide:
- Simplified and consistent APIs
- Better theme integration
- Improved developer experience
- Reduced boilerplate

Each component migration guide contains specific details about the changes and how to migrate.

## Theming

The redesigned components use `StreamTheme` for theming. If no `StreamTheme` is provided, a default theme is automatically created based on `Theme.of(context).brightness` (light or dark mode).

To customize the default theming, add `StreamTheme` as a theme extension to your `MaterialApp`:

```dart
MaterialApp(
theme: ThemeData(
extensions: [
StreamTheme(
brightness: Brightness.light,
colorScheme: StreamColorScheme.light().copyWith(
// Customize colors...
),
avatarTheme: const StreamAvatarThemeData(
// Customize avatar defaults...
),
),
],
),
// ...
)
```

You can also use the convenience factories `StreamTheme.light()` or `StreamTheme.dark()` as a starting point.

## Components

| Component | Migration Guide |
|-----------|-----------------|
| Stream Avatar | [stream_avatar.md](stream_avatar.md) |

## Need Help?

If you encounter any issues during migration or have questions, please [open an issue](https://github.com/GetStream/stream-chat-flutter/issues) on GitHub.
225 changes: 225 additions & 0 deletions migrations/redesign/stream_avatar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
# Stream Avatar Components Migration Guide

This guide covers the migration for the redesigned avatar components in Stream Chat Flutter SDK.

---

## Table of Contents

- [Quick Reference](#quick-reference)
- [StreamUserAvatar](#streamuseravatar)
- [StreamChannelAvatar](#streamchannelavatar)
- [StreamGroupAvatar](#streamgroupavatar)
- [StreamUserAvatarStack](#streamuseravatarstack)
- [Size Reference](#size-reference)
- [Migration Checklist](#migration-checklist)

---

## Quick Reference

| Component | Key Changes |
|-----------|-------------|
| [**StreamUserAvatar**](#streamuseravatar) | `constraints` → `size` enum, `showOnlineStatus` → `showOnlineIndicator`, `onTap` removed |
| [**StreamChannelAvatar**](#streamchannelavatar) | `constraints` → `size` enum, `onTap` and builder callbacks removed |
| [**StreamGroupAvatar**](#streamgroupavatar) | Renamed to `StreamUserAvatarGroup`, `members` → `users` |
| [**StreamUserAvatarStack**](#streamuseravatarstack) | New component for overlapping avatars |

---

## StreamUserAvatar

### Breaking Changes:

- `constraints` parameter replaced with `size` enum (`StreamAvatarSize`)
- `showOnlineStatus` renamed to `showOnlineIndicator`
- `onTap` callback removed — wrap with `GestureDetector` or `InkWell` instead
- `borderRadius` parameter removed
- `selected`, `selectionColor`, `selectionThickness` parameters removed
- `onlineIndicatorAlignment` and `onlineIndicatorConstraints` removed

### Migration:

**Before:**
```dart
StreamUserAvatar(
user: user,
constraints: BoxConstraints.tight(const Size(40, 40)),
borderRadius: BorderRadius.circular(20),
showOnlineStatus: false,
onTap: (user) => print('Tapped ${user.name}'),
)
```

**After:**
```dart
GestureDetector(
onTap: () => print('Tapped ${user.name}'),
child: StreamUserAvatar(
size: StreamAvatarSize.lg,
user: user,
showOnlineIndicator: false,
),
)
```

> **Important:**
> - Use `GestureDetector` or `InkWell` to handle tap events
> - Use `StreamAvatarSize` enum values (`.xs`, `.sm`, `.md`, `.lg`, `.xl`) instead of `BoxConstraints`
> - See [Size Reference](#size-reference) for mapping old constraints to new enum values

---

## StreamChannelAvatar

### Breaking Changes:

- `constraints` parameter replaced with `size` enum (`StreamAvatarGroupSize`)
- `onTap` callback removed — wrap with `GestureDetector` or `InkWell` instead
- `borderRadius` parameter removed
- `selected`, `selectionColor`, `selectionThickness` parameters removed
- `ownSpaceAvatarBuilder`, `oneToOneAvatarBuilder`, `groupAvatarBuilder` callbacks removed

### Migration:

**Before:**
```dart
StreamChannelAvatar(
channel: channel,
constraints: BoxConstraints.tight(const Size(40, 40)),
onTap: () => print('Tapped channel'),
selected: isSelected,
)
```

**After:**
```dart
GestureDetector(
onTap: () => print('Tapped channel'),
child: StreamChannelAvatar(
size: StreamAvatarGroupSize.lg,
channel: channel,
),
)
```

> **Important:**
> - Use `StreamAvatarGroupSize` enum values (`.lg`, `.xl`) instead of `BoxConstraints`
> - Custom avatar builders are no longer supported

---

## StreamGroupAvatar

### Breaking Changes:

- Renamed from `StreamGroupAvatar` to `StreamUserAvatarGroup`
- `members` parameter replaced with `users` (`Iterable<User>` instead of `List<Member>`)
- `constraints` parameter replaced with `size` enum (`StreamAvatarGroupSize`)
- `channel` parameter removed
- `onTap` callback removed — wrap with `GestureDetector` or `InkWell` instead
- `borderRadius` parameter removed
- `selected`, `selectionColor`, `selectionThickness` parameters removed

### Migration:

**Before:**
```dart
StreamGroupAvatar(
channel: channel,
members: otherMembers,
constraints: BoxConstraints.tight(const Size(40, 40)),
onTap: () => print('Tapped group'),
)
```

**After:**
```dart
GestureDetector(
onTap: () => print('Tapped group'),
child: StreamUserAvatarGroup(
size: StreamAvatarGroupSize.lg,
users: otherMembers.map((m) => m.user!),
),
)
```

> **Important:**
> - Extract `User` objects from `Member` when migrating: `members.map((m) => m.user!)`
> - The component no longer requires a `channel` reference

---

## StreamUserAvatarStack

### Breaking Changes:

- **New component** for displaying overlapping user avatars (e.g., thread participants)
- Replaces custom `Stack` + `Positioned` implementations

### Parameters:

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `users` | `Iterable<User>` | required | Users to display |
| `size` | `StreamAvatarStackSize?` | `.sm` | Size of avatars |
| `max` | `int` | `5` | Max avatars before overflow badge |
| `overlap` | `double` | `0.33` | Overlap fraction (0.0 - 1.0) |

### Usage:

```dart
StreamUserAvatarStack(
max: 3,
size: StreamAvatarStackSize.xs,
users: threadParticipants,
)
```

> **Important:**
> - Use this component instead of manually building overlapping avatar stacks
> - The `overlap` parameter controls how much each avatar overlaps the previous one

---

## Size Reference

### StreamAvatarSize

| Old Constraints | New Size | Diameter |
|-----------------|----------|----------|
| `BoxConstraints.tight(Size(20, 20))` | `.xs` | 20px |
| `BoxConstraints.tight(Size(24, 24))` | `.sm` | 24px |
| `BoxConstraints.tight(Size(32, 32))` | `.md` | 32px |
| `BoxConstraints.tight(Size(40, 40))` | `.lg` | 40px |
| `BoxConstraints.tight(Size(64, 64))` | `.xl` | 64px |

### StreamAvatarGroupSize

| Old Constraints | New Size | Diameter |
|-----------------|----------|----------|
| `BoxConstraints.tight(Size(40, 40))` | `.lg` | 40px |
| `BoxConstraints.tight(Size(64, 64))` | `.xl` | 64px |

### StreamAvatarStackSize

| Old Constraints | New Size | Diameter |
|-----------------|----------|----------|
| `BoxConstraints.tight(Size(20, 20))` | `.xs` | 20px |
| `BoxConstraints.tight(Size(24, 24))` | `.sm` | 24px |

> **Note:**
> If your old constraints don't match exactly, choose the closest available size.

---

## Migration Checklist

- [ ] Replace `StreamUserAvatar` `constraints` with `size` enum (`StreamAvatarSize`)
- [ ] Rename `showOnlineStatus` to `showOnlineIndicator`
- [ ] Move `onTap` callbacks to parent `GestureDetector` or `InkWell` widgets
- [ ] Replace `StreamGroupAvatar` with `StreamUserAvatarGroup`
- [ ] Change `members` parameter to `users` (extract `User` from `Member`)
- [ ] Replace `StreamChannelAvatar` `constraints` with `size` enum (`StreamAvatarGroupSize`)
- [ ] Remove `selected`, `selectionColor`, `selectionThickness` parameters
- [ ] Use `StreamUserAvatarStack` for overlapping avatar displays
Loading
Loading