refactor: animation dots

This commit is contained in:
cogwheel0
2025-09-08 00:05:13 +05:30
parent adbe3eb85f
commit 41f2739075
3 changed files with 113 additions and 31 deletions

View File

@@ -741,8 +741,10 @@ class _AssistantMessageWidgetState extends ConsumerState<AssistantMessageWidget>
Padding( Padding(
padding: const EdgeInsets.only(left: 4, bottom: 4), padding: const EdgeInsets.only(left: 4, bottom: 4),
child: SizedBox( child: SizedBox(
height: 18, height: 22,
child: _buildTypingDot(), child: Platform.isIOS
? _buildTypingPillBubble()
: _buildTypingEllipsis(),
), ),
), ),
], ],
@@ -751,17 +753,26 @@ class _AssistantMessageWidgetState extends ConsumerState<AssistantMessageWidget>
); );
} }
Widget _buildTypingDot() { Widget _buildTypingEllipsis() {
final min = AnimationValues.typingIndicatorScale; final min = AnimationValues.typingIndicatorScale;
final dotColor = context.conduitTheme.textSecondary.withValues(alpha: 0.75);
const double dotSize = 6.0;
const double gap = Spacing.xs; // 4.0
final d = AnimationDelay.typingDelay;
final d2 = Duration(milliseconds: d.inMilliseconds * 2);
Widget dot(Duration delay) {
return Container( return Container(
width: 14, width: dotSize,
height: 14, height: dotSize,
decoration: BoxDecoration( decoration: BoxDecoration(
color: context.conduitTheme.textSecondary.withValues(alpha: 0.6), color: dotColor,
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
) )
.animate(onPlay: (controller) => controller.repeat()) .animate(onPlay: (controller) => controller.repeat())
.then(delay: delay)
.scale( .scale(
duration: AnimationDuration.typingIndicator, duration: AnimationDuration.typingIndicator,
curve: AnimationCurves.typingIndicator, curve: AnimationCurves.typingIndicator,
@@ -777,6 +788,79 @@ class _AssistantMessageWidgetState extends ConsumerState<AssistantMessageWidget>
); );
} }
return Row(
mainAxisSize: MainAxisSize.min,
children: [
dot(Duration.zero),
const SizedBox(width: gap),
dot(d),
const SizedBox(width: gap),
dot(d2),
],
);
}
Widget _buildTypingPillBubble() {
final min = AnimationValues.typingIndicatorScale;
final bubbleColor = context.conduitTheme.surfaceContainerHighest;
final dotColor = context.conduitTheme.textSecondary.withValues(alpha: 0.75);
const double dotSize = 6.0;
const double gap = Spacing.xs; // 4.0
const double padV = 6.0;
const double padH = 10.0;
final d = AnimationDelay.typingDelay;
final d2 = Duration(milliseconds: d.inMilliseconds * 2);
Widget dot(Duration delay) {
return Container(
width: dotSize,
height: dotSize,
decoration: BoxDecoration(
color: dotColor,
shape: BoxShape.circle,
),
)
.animate(onPlay: (controller) => controller.repeat())
.then(delay: delay)
.scale(
duration: AnimationDuration.typingIndicator,
curve: AnimationCurves.typingIndicator,
begin: Offset(min, min),
end: const Offset(1, 1),
)
.then(delay: AnimationDelay.typingDelay)
.scale(
duration: AnimationDuration.typingIndicator,
curve: AnimationCurves.typingIndicator,
begin: const Offset(1, 1),
end: Offset(min, min),
);
}
return Container(
padding: const EdgeInsets.symmetric(horizontal: padH, vertical: padV),
decoration: BoxDecoration(
color: bubbleColor,
borderRadius: BorderRadius.circular(999),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
dot(Duration.zero),
const SizedBox(width: gap),
dot(d),
const SizedBox(width: gap),
dot(d2),
],
),
);
}
Widget _buildActionButtons() { Widget _buildActionButtons() {
final isErrorMessage = final isErrorMessage =
widget.message.content.contains('⚠️') || widget.message.content.contains('⚠️') ||

View File

@@ -613,11 +613,10 @@ class AppLocalizationsFr extends AppLocalizations {
'Ce dossier et ses associations seront supprimés.'; 'Ce dossier et ses associations seront supprimés.';
@override @override
String get failedToDeleteFolder => String get failedToDeleteFolder => 'Échec de la suppression du dossier';
'Échec de la suppression du dossier';
@override @override
String get aboutApp => 'À propos de l\'application'; String get aboutApp => 'À propos de lapplication';
@override @override
String get aboutAppSubtitle => 'Informations et liens Conduit'; String get aboutAppSubtitle => 'Informations et liens Conduit';

View File

@@ -606,11 +606,10 @@ class AppLocalizationsIt extends AppLocalizations {
'Questa cartella e le sue associazioni verranno rimosse.'; 'Questa cartella e le sue associazioni verranno rimosse.';
@override @override
String get failedToDeleteFolder => String get failedToDeleteFolder => 'Impossibile eliminare la cartella';
'Impossibile eliminare la cartella';
@override @override
String get aboutApp => 'Informazioni sull\'app'; String get aboutApp => 'Informazioni sullapp';
@override @override
String get aboutAppSubtitle => 'Informazioni e link di Conduit'; String get aboutAppSubtitle => 'Informazioni e link di Conduit';