💫 Message list fully animated
This commit is contained in:
@@ -561,13 +561,31 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
.abs() >
|
.abs() >
|
||||||
3;
|
3;
|
||||||
|
|
||||||
final key = ValueKey('$messageKeyPrefix${message.id}');
|
// Use a stable animation key that doesn't change during message lifecycle
|
||||||
|
final animationKey = ValueKey(
|
||||||
|
'message-anim-${message.nonce ?? message.id}',
|
||||||
|
);
|
||||||
|
|
||||||
return chatIdentity.when(
|
return TweenAnimationBuilder<double>(
|
||||||
|
key: animationKey,
|
||||||
|
tween: Tween<double>(begin: 0.0, end: 1.0),
|
||||||
|
duration: Duration(
|
||||||
|
milliseconds: 400 + (index % 5) * 50,
|
||||||
|
), // Staggered delay
|
||||||
|
curve: Curves.easeOutCubic,
|
||||||
|
builder: (context, animationValue, child) {
|
||||||
|
return Transform.translate(
|
||||||
|
offset: Offset(
|
||||||
|
0,
|
||||||
|
20 * (1 - animationValue),
|
||||||
|
), // Slide up from bottom
|
||||||
|
child: Opacity(opacity: animationValue, child: child),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
child: chatIdentity.when(
|
||||||
skipError: true,
|
skipError: true,
|
||||||
data:
|
data:
|
||||||
(identity) => MessageItem(
|
(identity) => MessageItem(
|
||||||
key: key,
|
|
||||||
message: message,
|
message: message,
|
||||||
isCurrentUser: identity?.id == message.senderId,
|
isCurrentUser: identity?.id == message.senderId,
|
||||||
onAction: (action) {
|
onAction: (action) {
|
||||||
@@ -605,7 +623,6 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
loading:
|
loading:
|
||||||
() => MessageItem(
|
() => MessageItem(
|
||||||
key: key,
|
|
||||||
message: message,
|
message: message,
|
||||||
isCurrentUser: false,
|
isCurrentUser: false,
|
||||||
onAction: null,
|
onAction: null,
|
||||||
@@ -613,7 +630,8 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
showAvatar: false,
|
showAvatar: false,
|
||||||
onJump: (_) {},
|
onJump: (_) {},
|
||||||
),
|
),
|
||||||
error: (_, _) => SizedBox.shrink(key: key),
|
error: (_, _) => SizedBox.shrink(),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -692,21 +710,45 @@ class ChatRoomScreen extends HookConsumerWidget {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
|
child: AnimatedSwitcher(
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
switchInCurve: Curves.easeOutCubic,
|
||||||
|
switchOutCurve: Curves.easeInCubic,
|
||||||
|
transitionBuilder: (
|
||||||
|
Widget child,
|
||||||
|
Animation<double> animation,
|
||||||
|
) {
|
||||||
|
return SlideTransition(
|
||||||
|
position: Tween<Offset>(
|
||||||
|
begin: const Offset(0, 0.05),
|
||||||
|
end: Offset.zero,
|
||||||
|
).animate(animation),
|
||||||
|
child: FadeTransition(opacity: animation, child: child),
|
||||||
|
);
|
||||||
|
},
|
||||||
child: messages.when(
|
child: messages.when(
|
||||||
data:
|
data:
|
||||||
(messageList) =>
|
(messageList) =>
|
||||||
messageList.isEmpty
|
messageList.isEmpty
|
||||||
? Center(child: Text('No messages yet'.tr()))
|
? Center(
|
||||||
|
key: const ValueKey('empty-messages'),
|
||||||
|
child: Text('No messages yet'.tr()),
|
||||||
|
)
|
||||||
: chatMessageListWidget(messageList),
|
: chatMessageListWidget(messageList),
|
||||||
loading:
|
loading:
|
||||||
() => const Center(child: CircularProgressIndicator()),
|
() => const Center(
|
||||||
|
key: ValueKey('loading-messages'),
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
error:
|
error:
|
||||||
(error, _) => ResponseErrorWidget(
|
(error, _) => ResponseErrorWidget(
|
||||||
|
key: const ValueKey('error-messages'),
|
||||||
error: error,
|
error: error,
|
||||||
onRetry: () => messagesNotifier.loadInitial(),
|
onRetry: () => messagesNotifier.loadInitial(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
),
|
||||||
chatRoom.when(
|
chatRoom.when(
|
||||||
data:
|
data:
|
||||||
(room) => Column(
|
(room) => Column(
|
||||||
|
Reference in New Issue
Block a user