Skip to content

Commit 7a45c94

Browse files
committed
msglist: Use faster fade to hidden animation for mark as read button
Fixes: zulip#613
1 parent 594039f commit 7a45c94

File tree

2 files changed

+65
-4
lines changed

2 files changed

+65
-4
lines changed

lib/widgets/message_list.dart

+25-4
Original file line numberDiff line numberDiff line change
@@ -486,10 +486,9 @@ class MarkAsReadWidgetState extends State<MarkAsReadWidget> {
486486

487487
return IgnorePointer(
488488
ignoring: areMessagesRead,
489-
child: AnimatedOpacity(
490-
opacity: areMessagesRead ? 0 : loading ? 0.5 : 1,
491-
duration: Duration(milliseconds: areMessagesRead ? 2000 : 300),
492-
curve: Curves.easeOut,
489+
child: MarkAsReadAnimation(
490+
loading: loading,
491+
hidden: areMessagesRead,
493492
child: SizedBox(width: double.infinity,
494493
// Design referenced from:
495494
// https://www.figma.com/file/1JTNtYo9memgW7vV6d0ygq/Zulip-Mobile?type=design&node-id=132-9684&mode=design&t=jJwHzloKJ0TMOG4M-0
@@ -523,6 +522,28 @@ class MarkAsReadWidgetState extends State<MarkAsReadWidget> {
523522
}
524523
}
525524

525+
class MarkAsReadAnimation extends StatelessWidget {
526+
final bool loading;
527+
final bool hidden;
528+
final Widget child;
529+
530+
const MarkAsReadAnimation({
531+
super.key,
532+
required this.loading,
533+
required this.hidden,
534+
required this.child
535+
});
536+
537+
@override
538+
Widget build(BuildContext context) {
539+
return AnimatedOpacity(
540+
opacity: hidden ? 0 : loading ? 0.5 : 1,
541+
duration: const Duration(milliseconds: 500),
542+
curve: Curves.easeOut,
543+
child: child);
544+
}
545+
}
546+
526547
class RecipientHeader extends StatelessWidget {
527548
const RecipientHeader({super.key, required this.message, required this.narrow});
528549

test/widgets/message_list_test.dart

+40
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,46 @@ void main() {
801801

802802
check(state.loading).isFalse();
803803
});
804+
805+
testWidgets('in idle state', (WidgetTester tester) async {
806+
final child = Container();
807+
808+
await tester.pumpWidget(MaterialApp(
809+
home: MarkAsReadAnimation(hidden: false, loading: false, child: child)));
810+
811+
check(find.byWidget(child).evaluate()).length.equals(1);
812+
check(tester.widget<AnimatedOpacity>(find.byType(AnimatedOpacity)).opacity).equals(1);
813+
});
814+
815+
testWidgets('in loading state', (WidgetTester tester) async {
816+
final child = Container();
817+
818+
await tester.pumpWidget(MaterialApp(
819+
home: MarkAsReadAnimation(hidden: false, loading: true, child: child)));
820+
821+
check(find.byWidget(child).evaluate()).length.equals(1);
822+
check(tester.widget<AnimatedOpacity>(find.byType(AnimatedOpacity)).opacity).equals(0.55);
823+
});
824+
825+
testWidgets('in hidden state', (WidgetTester tester) async {
826+
final child = Container();
827+
828+
await tester.pumpWidget(MaterialApp(
829+
home: MarkAsReadAnimation(hidden: true, loading: false, child: child)));
830+
831+
check(find.byWidget(child).evaluate()).length.equals(1);
832+
check(tester.widget<AnimatedOpacity>(find.byType(AnimatedOpacity)).opacity).equals(0);
833+
});
834+
835+
testWidgets('in hidden state but loading is true', (WidgetTester tester) async {
836+
final child = Container();
837+
838+
await tester.pumpWidget(MaterialApp(
839+
home: MarkAsReadAnimation(hidden: true, loading: true, child: child)));
840+
841+
check(find.byWidget(child).evaluate()).length.equals(1);
842+
check(tester.widget<AnimatedOpacity>(find.byType(AnimatedOpacity)).opacity).equals(0);
843+
});
804844
});
805845

806846
testWidgets('smoke test on modern server', (WidgetTester tester) async {

0 commit comments

Comments
 (0)