Skip to content
This repository has been archived by the owner on Jan 9, 2024. It is now read-only.

feat: headline animation #67

Merged
merged 4 commits into from
Dec 5, 2023
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
70 changes: 37 additions & 33 deletions lib/home/bloc/home_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -72,39 +72,6 @@ class HomeState extends Equatable {
return ParsedSummary(elements: elements);
}

bool get isWelcomeVisible =>
status == Status.welcome || status == Status.welcomeToAskQuestion;
bool get isQuestionVisible =>
status == Status.welcomeToAskQuestion || status == Status.askQuestion;
bool get isThinkingVisible =>
status == Status.askQuestionToThinking ||
status == Status.thinking ||
status == Status.thinkingToResults ||
status == Status.resultsToThinking;
bool get isResultsVisible =>
status == Status.thinkingToResults ||
status == Status.results ||
status == Status.resultsToSourceAnswers ||
status == Status.seeSourceAnswers ||
status == Status.sourceAnswersBackToResults;
bool get isMovingToSeeSourceAnswers =>
status == Status.resultsToSourceAnswers ||
status == Status.seeSourceAnswers ||
status == Status.sourceAnswersBackToResults;
bool get isSeeSourceAnswersVisible => status == Status.seeSourceAnswers;
bool get isDashOnLeft =>
status == Status.welcome ||
status == Status.welcomeToAskQuestion ||
status == Status.askQuestion ||
status == Status.askQuestionToThinking ||
status == Status.thinking ||
status == Status.thinkingToResults ||
status == Status.results;
bool get isDashOnRight =>
status == Status.resultsToSourceAnswers ||
status == Status.seeSourceAnswers ||
status == Status.sourceAnswersBackToResults;

HomeState copyWith({
Status? status,
String? query,
Expand Down Expand Up @@ -133,3 +100,40 @@ class HomeState extends Equatable {
answerFeedbacks,
];
}

extension StatusX on Status {
bool get isWelcomeVisible =>
this == Status.welcome || this == Status.welcomeToAskQuestion;
bool get isQuestionVisible =>
this == Status.welcomeToAskQuestion ||
this == Status.askQuestion ||
this == Status.askQuestionToThinking;
bool get isThinkingVisible =>
this == Status.askQuestionToThinking ||
this == Status.thinking ||
this == Status.thinkingToResults ||
this == Status.resultsToThinking;
bool get isResultsVisible =>
this == Status.thinkingToResults ||
this == Status.results ||
this == Status.resultsToSourceAnswers ||
this == Status.seeSourceAnswers ||
this == Status.sourceAnswersBackToResults;
bool get isMovingToSeeSourceAnswers =>
this == Status.resultsToSourceAnswers ||
this == Status.seeSourceAnswers ||
this == Status.sourceAnswersBackToResults;
bool get isSeeSourceAnswersVisible => this == Status.seeSourceAnswers;
bool get isDashOnLeft =>
this == Status.welcome ||
this == Status.welcomeToAskQuestion ||
this == Status.askQuestion ||
this == Status.askQuestionToThinking ||
this == Status.thinking ||
this == Status.thinkingToResults ||
this == Status.results;
bool get isDashOnRight =>
this == Status.resultsToSourceAnswers ||
this == Status.seeSourceAnswers ||
this == Status.sourceAnswersBackToResults;
}
18 changes: 9 additions & 9 deletions lib/home/view/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,30 @@ class HomeView extends StatelessWidget {

@override
Widget build(BuildContext context) {
final state = context.watch<HomeBloc>().state;
final status = context.select((HomeBloc bloc) => bloc.state.status);

return Scaffold(
backgroundColor: VertexColors.arctic,
body: Stack(
children: [
if (state.isWelcomeVisible)
if (status.isWelcomeVisible)
const Positioned(
top: 0,
bottom: 0,
left: 0,
right: 0,
child: Background(),
),
if (state.isWelcomeVisible) const WelcomeView(),
if (state.isQuestionVisible) const QuestionView(),
if (state.isThinkingVisible) const ThinkingView(),
if (state.isResultsVisible) const ResultsView(),
if (status.isWelcomeVisible) const WelcomeView(),
if (status.isThinkingVisible) const ThinkingView(),
if (status.isQuestionVisible) const QuestionView(),
if (status.isResultsVisible) const ResultsView(),
Positioned(
top: 40,
left: 48,
child: Logo(hasDarkBackground: state.isSeeSourceAnswersVisible),
child: Logo(hasDarkBackground: status.isSeeSourceAnswersVisible),
),
if (state.isDashOnRight)
if (status.isDashOnRight)
const Positioned(
bottom: 50,
right: 50,
Expand All @@ -57,7 +57,7 @@ class HomeView extends StatelessWidget {
key: _dashRightKey,
),
),
if (state.isDashOnLeft)
if (status.isDashOnLeft)
const Positioned(
bottom: 50,
left: 50,
Expand Down
61 changes: 39 additions & 22 deletions lib/home/widgets/question_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,22 @@ class QuestionView extends StatefulWidget {

class QuestionViewState extends State<QuestionView>
with TickerProviderStateMixin, TransitionScreenMixin {
late Animation<double> _opacity;
late Animation<Offset> _offsetVerticalIn;
late Animation<Offset> _offsetVerticalOut;

@override
List<Status> get forwardEnterStatuses => [Status.welcomeToAskQuestion];

@override
List<Status> get forwardExitStatuses => [Status.askQuestionToThinking];

@override
void initializeTransitionController() {
super.initializeTransitionController();

enterTransitionController = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
duration: const Duration(milliseconds: 1500),
)..addStatusListener((status) {
if (status == AnimationStatus.completed) {
context.read<HomeBloc>().add(const AskQuestion());
Expand All @@ -33,29 +37,29 @@ class QuestionViewState extends State<QuestionView>

exitTransitionController = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
duration: const Duration(milliseconds: 1500),
);
}

@override
void initState() {
super.initState();
_offsetVerticalIn =
Tween<Offset>(begin: const Offset(0, 1), end: Offset.zero).animate(
CurvedAnimation(
parent: enterTransitionController,
curve: Curves.decelerate,
),
);

_opacity =
Tween<double>(begin: 0, end: 1).animate(enterTransitionController);
}

@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _opacity,
child: const _QuestionView(),
_offsetVerticalOut =
Tween<Offset>(begin: Offset.zero, end: const Offset(0, -1.5)).animate(
CurvedAnimation(
parent: exitTransitionController,
curve: Curves.decelerate,
),
);
}
}

class _QuestionView extends StatelessWidget {
const _QuestionView();

@override
Widget build(BuildContext context) {
Expand All @@ -68,14 +72,27 @@ class _QuestionView extends StatelessWidget {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
l10n.questionScreenTitle,
textAlign: TextAlign.center,
style: textTheme.displayLarge
?.copyWith(color: VertexColors.flutterNavy),
ClipRRect(
child: SlideTransition(
position: _offsetVerticalIn,
child: SlideTransition(
position: _offsetVerticalOut,
child: Text(
l10n.questionScreenTitle,
textAlign: TextAlign.center,
style: textTheme.displayLarge
?.copyWith(color: VertexColors.flutterNavy),
),
),
),
),
const SizedBox(height: 40),
const SearchBox(),
ClipRRect(
child: SlideTransition(
position: _offsetVerticalOut,
child: const SearchBox(),
),
),
],
),
),
Expand Down
6 changes: 3 additions & 3 deletions lib/home/widgets/results_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class _ResultsView extends StatelessWidget {

@override
Widget build(BuildContext context) {
final state = context.watch<HomeBloc>().state;
final status = context.select((HomeBloc bloc) => bloc.state.status);

final response =
context.select((HomeBloc bloc) => bloc.state.vertexResponse);
Expand All @@ -89,7 +89,7 @@ class _ResultsView extends StatelessWidget {
child: SearchBoxView(),
),
),
if (state.isMovingToSeeSourceAnswers)
if (status.isMovingToSeeSourceAnswers)
Positioned(
top: _questionBoxHeight + _searchBarTopPadding + 32,
right: 100,
Expand Down Expand Up @@ -429,7 +429,7 @@ class _AiResponseState extends State<_AiResponse>
);
},
),
if (!state.isSeeSourceAnswersVisible)
if (!state.status.isSeeSourceAnswersVisible)
const SeeSourceAnswersButton(),
],
),
Expand Down
Loading