Skip to content

Commit

Permalink
feat: avatar support (#715)
Browse files Browse the repository at this point in the history
  • Loading branch information
demchenkoalex authored Feb 16, 2025
1 parent 55e2e88 commit cfd69a5
Show file tree
Hide file tree
Showing 39 changed files with 401 additions and 82 deletions.
43 changes: 41 additions & 2 deletions examples/flyer_chat/lib/local.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,14 @@ class LocalState extends State<Local> {
final _chatController = InMemoryChatController();
final _uuid = const Uuid();

final _currentUser = const User(id: 'me');
final _recipient = const User(id: 'recipient');
final _currentUser = const User(
id: 'me',
imageSource: 'https://picsum.photos/id/65/200/200',
);
final _recipient = const User(
id: 'recipient',
imageSource: 'https://picsum.photos/id/265/200/200',
);
final _systemUser = const User(id: 'system');

bool _isTyping = false;
Expand Down Expand Up @@ -87,6 +93,39 @@ class LocalState extends State<Local> {
),
textMessageBuilder: (context, message, index) =>
FlyerChatTextMessage(message: message, index: index),
chatMessageBuilder: (
context,
message,
index,
animation,
child, {
bool? isRemoved,
MessageGroupStatus? groupStatus,
}) {
return ChatMessage(
message: message,
index: index,
animation: animation,
groupStatus: groupStatus,
leadingWidget: message.authorId != _currentUser.id &&
(groupStatus?.isLast ?? true) &&
isRemoved != true
? Padding(
padding: const EdgeInsets.only(right: 8),
child: Avatar(userId: message.authorId),
)
: const SizedBox(width: 40),
trailingWidget: message.authorId == _currentUser.id &&
(groupStatus?.isLast ?? true) &&
isRemoved != true
? Padding(
padding: const EdgeInsets.only(left: 8),
child: Avatar(userId: message.authorId),
)
: const SizedBox(width: 40),
child: child,
);
},
),
chatController: _chatController,
currentUserId: _currentUser.id,
Expand Down
10 changes: 5 additions & 5 deletions examples/flyer_chat/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,17 @@ environment:
dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cross_cache: ^0.0.5
cross_cache: ^0.0.6
cupertino_icons: ^1.0.8
dio: ^5.7.0
flutter:
sdk: flutter
flutter_chat_core: ^0.0.5
flutter_chat_ui: ^2.0.0-dev.4
flutter_chat_core: ^0.0.6
flutter_chat_ui: ^2.0.0-dev.5
flutter_dotenv: ^5.2.1
flutter_lorem: ^2.0.0
flyer_chat_image_message: ^0.0.5
flyer_chat_text_message: ^0.0.5
flyer_chat_image_message: ^0.0.6
flyer_chat_text_message: ^0.0.6
google_generative_ai: ^0.4.6
hive: ^4.0.0-dev.2
http: ^1.2.2
Expand Down
4 changes: 4 additions & 0 deletions packages/cross_cache/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 0.0.6

- Version bump to match other packages

## 0.0.5

- Version bump to match other packages
Expand Down
2 changes: 1 addition & 1 deletion packages/cross_cache/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: cross_cache
version: 0.0.5
version: 0.0.6
description: >
Cross-platform cache manager for Flutter using IndexedDB for web, file system
for mobile and desktop, and Dio for network requests. #cache #indexeddb #dio
Expand Down
7 changes: 7 additions & 0 deletions packages/flutter_chat_core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 0.0.6

**⚠️ Breaking changes ⚠️**

- Changed signature of `chatMessageBuilder` to include `isRemoved` and `groupStatus` parameters.
- Changed `imageUrl` to `imageSource` for the `User` model. Change is necessary to show that not only remote URLs are supported but also local assets.

## 0.0.5

**⚠️ Breaking changes ⚠️**
Expand Down
1 change: 1 addition & 0 deletions packages/flutter_chat_core/lib/flutter_chat_core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export 'src/chat_controller/upload_progress_mixin.dart';
export 'src/models/builders.dart';
export 'src/models/link_preview.dart';
export 'src/models/message.dart';
export 'src/models/message_group_status.dart';
export 'src/models/user.dart';
export 'src/theme/chat_theme.dart';
export 'src/theme/chat_theme_extension.dart';
Expand Down
7 changes: 5 additions & 2 deletions packages/flutter_chat_core/lib/src/models/builders.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/widgets.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import '../utils/typedefs.dart';
import 'message.dart';
import 'message_group_status.dart';

part 'builders.freezed.dart';

Expand Down Expand Up @@ -31,8 +32,10 @@ typedef ChatMessageBuilder = Widget Function(
Message message,
int index,
Animation<double> animation,
Widget child,
);
Widget child, {
bool? isRemoved,
MessageGroupStatus? groupStatus,
});
typedef ChatAnimatedListBuilder = Widget Function(
BuildContext,
ChatItem itemBuilder,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class MessageGroupStatus {
final bool isFirst;
final bool isLast;
final bool isMiddle;

const MessageGroupStatus({
required this.isFirst,
required this.isLast,
required this.isMiddle,
});
}
2 changes: 1 addition & 1 deletion packages/flutter_chat_core/lib/src/models/user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class User with _$User {
required String id,
String? firstName,
String? lastName,
String? imageUrl,
String? imageSource,
@EpochDateTimeConverter() DateTime? createdAt,
Map<String, dynamic>? metadata,
}) = _User;
Expand Down
38 changes: 19 additions & 19 deletions packages/flutter_chat_core/lib/src/models/user.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ mixin _$User {
String get id => throw _privateConstructorUsedError;
String? get firstName => throw _privateConstructorUsedError;
String? get lastName => throw _privateConstructorUsedError;
String? get imageUrl => throw _privateConstructorUsedError;
String? get imageSource => throw _privateConstructorUsedError;
@EpochDateTimeConverter()
DateTime? get createdAt => throw _privateConstructorUsedError;
Map<String, dynamic>? get metadata => throw _privateConstructorUsedError;
Expand All @@ -46,7 +46,7 @@ abstract class $UserCopyWith<$Res> {
{String id,
String? firstName,
String? lastName,
String? imageUrl,
String? imageSource,
@EpochDateTimeConverter() DateTime? createdAt,
Map<String, dynamic>? metadata});
}
Expand All @@ -69,7 +69,7 @@ class _$UserCopyWithImpl<$Res, $Val extends User>
Object? id = null,
Object? firstName = freezed,
Object? lastName = freezed,
Object? imageUrl = freezed,
Object? imageSource = freezed,
Object? createdAt = freezed,
Object? metadata = freezed,
}) {
Expand All @@ -86,9 +86,9 @@ class _$UserCopyWithImpl<$Res, $Val extends User>
? _value.lastName
: lastName // ignore: cast_nullable_to_non_nullable
as String?,
imageUrl: freezed == imageUrl
? _value.imageUrl
: imageUrl // ignore: cast_nullable_to_non_nullable
imageSource: freezed == imageSource
? _value.imageSource
: imageSource // ignore: cast_nullable_to_non_nullable
as String?,
createdAt: freezed == createdAt
? _value.createdAt
Expand All @@ -113,7 +113,7 @@ abstract class _$$UserImplCopyWith<$Res> implements $UserCopyWith<$Res> {
{String id,
String? firstName,
String? lastName,
String? imageUrl,
String? imageSource,
@EpochDateTimeConverter() DateTime? createdAt,
Map<String, dynamic>? metadata});
}
Expand All @@ -133,7 +133,7 @@ class __$$UserImplCopyWithImpl<$Res>
Object? id = null,
Object? firstName = freezed,
Object? lastName = freezed,
Object? imageUrl = freezed,
Object? imageSource = freezed,
Object? createdAt = freezed,
Object? metadata = freezed,
}) {
Expand All @@ -150,9 +150,9 @@ class __$$UserImplCopyWithImpl<$Res>
? _value.lastName
: lastName // ignore: cast_nullable_to_non_nullable
as String?,
imageUrl: freezed == imageUrl
? _value.imageUrl
: imageUrl // ignore: cast_nullable_to_non_nullable
imageSource: freezed == imageSource
? _value.imageSource
: imageSource // ignore: cast_nullable_to_non_nullable
as String?,
createdAt: freezed == createdAt
? _value.createdAt
Expand All @@ -173,7 +173,7 @@ class _$UserImpl extends _User {
{required this.id,
this.firstName,
this.lastName,
this.imageUrl,
this.imageSource,
@EpochDateTimeConverter() this.createdAt,
final Map<String, dynamic>? metadata})
: _metadata = metadata,
Expand All @@ -189,7 +189,7 @@ class _$UserImpl extends _User {
@override
final String? lastName;
@override
final String? imageUrl;
final String? imageSource;
@override
@EpochDateTimeConverter()
final DateTime? createdAt;
Expand All @@ -205,7 +205,7 @@ class _$UserImpl extends _User {

@override
String toString() {
return 'User(id: $id, firstName: $firstName, lastName: $lastName, imageUrl: $imageUrl, createdAt: $createdAt, metadata: $metadata)';
return 'User(id: $id, firstName: $firstName, lastName: $lastName, imageSource: $imageSource, createdAt: $createdAt, metadata: $metadata)';
}

@override
Expand All @@ -218,8 +218,8 @@ class _$UserImpl extends _User {
other.firstName == firstName) &&
(identical(other.lastName, lastName) ||
other.lastName == lastName) &&
(identical(other.imageUrl, imageUrl) ||
other.imageUrl == imageUrl) &&
(identical(other.imageSource, imageSource) ||
other.imageSource == imageSource) &&
(identical(other.createdAt, createdAt) ||
other.createdAt == createdAt) &&
const DeepCollectionEquality().equals(other._metadata, _metadata));
Expand All @@ -228,7 +228,7 @@ class _$UserImpl extends _User {
@JsonKey(includeFromJson: false, includeToJson: false)
@override
int get hashCode => Object.hash(runtimeType, id, firstName, lastName,
imageUrl, createdAt, const DeepCollectionEquality().hash(_metadata));
imageSource, createdAt, const DeepCollectionEquality().hash(_metadata));

/// Create a copy of User
/// with the given fields replaced by the non-null parameter values.
Expand All @@ -251,7 +251,7 @@ abstract class _User extends User {
{required final String id,
final String? firstName,
final String? lastName,
final String? imageUrl,
final String? imageSource,
@EpochDateTimeConverter() final DateTime? createdAt,
final Map<String, dynamic>? metadata}) = _$UserImpl;
const _User._() : super._();
Expand All @@ -265,7 +265,7 @@ abstract class _User extends User {
@override
String? get lastName;
@override
String? get imageUrl;
String? get imageSource;
@override
@EpochDateTimeConverter()
DateTime? get createdAt;
Expand Down
4 changes: 2 additions & 2 deletions packages/flutter_chat_core/lib/src/models/user.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/flutter_chat_core/lib/src/utils/typedefs.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ typedef ChatItem = Widget Function(
Message message,
int index,
Animation<double> animation, {
int? messageGroupingTimeoutInSeconds,
bool? isRemoved,
});
2 changes: 1 addition & 1 deletion packages/flutter_chat_core/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: flutter_chat_core
version: 0.0.5
version: 0.0.6
description: >
Core package for Flutter chat apps, complementing flutter_chat_ui.
Contains models and core functionality. #chat #ui
Expand Down
11 changes: 11 additions & 0 deletions packages/flutter_chat_ui/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
## 2.0.0-dev.5

**⚠️ Breaking changes ⚠️**

- Changed signature of `chatMessageBuilder` to include `isRemoved` and `groupStatus` parameters.
- Changed `imageUrl` to `imageSource` for the `User` model. Change is necessary to show that not only remote URLs are supported but also local assets.
- `messageGroupingTimeoutInSeconds` is now set via `chatAnimatedListBuilder`.

**⚠️ New features ⚠️**

- Add `hintText` to the `ChatInput` widget.
- Added avatar support. Check local example for details.
- `chatMessageBuilder` now returns `isRemoved` and `groupStatus` parameters. Group status returns information about message's position in the group. `isRemoved` is `true` if message is removed.
- Added `leadingWidget` and `trailingWidget` to the `ChatMessage` widget.

## 2.0.0-dev.4

Expand Down
1 change: 1 addition & 0 deletions packages/flutter_chat_ui/lib/flutter_chat_ui.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export 'src/avatar.dart';
export 'src/chat.dart';
export 'src/chat_animated_list/chat_animated_list.dart';
export 'src/chat_animated_list/chat_animated_list_reversed.dart';
Expand Down
Loading

0 comments on commit cfd69a5

Please sign in to comment.