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

Commit

Permalink
feat: question screen (#14)
Browse files Browse the repository at this point in the history
  • Loading branch information
RuiMiguel authored Nov 23, 2023
1 parent 6cf3caa commit ca84b50
Show file tree
Hide file tree
Showing 25 changed files with 510 additions and 29 deletions.
28 changes: 28 additions & 0 deletions lib/home/bloc/home_bloc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import 'dart:async';

import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';

part 'home_event.dart';
part 'home_state.dart';

class HomeBloc extends Bloc<HomeEvent, HomeState> {
HomeBloc() : super(const HomeState()) {
on<FromWelcomeToQuestion>(_onFromWelcomeToQuestion);
on<AskQuestion>(_onQuestion);
}

Future<void> _onFromWelcomeToQuestion(
FromWelcomeToQuestion event,
Emitter<HomeState> emit,
) async {
emit(state.copyWith(status: Status.welcomeToAskQuestion));
}

Future<void> _onQuestion(
AskQuestion event,
Emitter<HomeState> emit,
) async {
emit(state.copyWith(status: Status.askQuestion));
}
}
16 changes: 16 additions & 0 deletions lib/home/bloc/home_event.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
part of 'home_bloc.dart';

abstract class HomeEvent extends Equatable {
const HomeEvent();

@override
List<Object> get props => [];
}

class FromWelcomeToQuestion extends HomeEvent {
const FromWelcomeToQuestion();
}

class AskQuestion extends HomeEvent {
const AskQuestion();
}
27 changes: 27 additions & 0 deletions lib/home/bloc/home_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
part of 'home_bloc.dart';

enum Status { welcome, welcomeToAskQuestion, askQuestion }

class HomeState extends Equatable {
const HomeState({
this.status = Status.welcome,
});

final Status status;

bool get isWelcomeVisible =>
status == Status.welcome || status == Status.welcomeToAskQuestion;
bool get isQuestionVisible =>
status == Status.welcomeToAskQuestion || status == Status.askQuestion;

HomeState copyWith({
Status? status,
}) {
return HomeState(
status: status ?? this.status,
);
}

@override
List<Object> get props => [status];
}
1 change: 1 addition & 0 deletions lib/home/home.dart
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export 'bloc/home_bloc.dart';
export 'view/home_page.dart';
export 'widgets/widgets.dart';
27 changes: 22 additions & 5 deletions lib/home/view/home_page.dart
Original file line number Diff line number Diff line change
@@ -1,28 +1,45 @@
import 'package:app_ui/app_ui.dart';
import 'package:dash_ai_search/home/home.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class HomePage extends StatelessWidget {
const HomePage({super.key});

@override
Widget build(BuildContext context) {
return const Scaffold(
return BlocProvider(
create: (_) => HomeBloc(),
child: const HomeView(),
);
}
}

class HomeView extends StatelessWidget {
@visibleForTesting
const HomeView({super.key});

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

return Scaffold(
backgroundColor: VertexColors.arctic,
body: Stack(
children: [
Positioned(
const Positioned(
top: 0,
bottom: 0,
child: Background(),
),
Positioned(
const Positioned(
top: 40,
left: 48,
child: Logo(),
),
WelcomeView(),
Positioned(
if (state.isWelcomeVisible) const WelcomeView(),
if (state.isQuestionVisible) const QuestionView(),
const Positioned(
bottom: 50,
left: 50,
child: DashAnimation(),
Expand Down
43 changes: 43 additions & 0 deletions lib/home/widgets/question_view.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import 'package:app_ui/app_ui.dart';
import 'package:dash_ai_search/home/home.dart';
import 'package:dash_ai_search/l10n/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class QuestionView extends StatelessWidget {
const QuestionView({super.key});

@override
Widget build(BuildContext context) {
final theme = Theme.of(context);
final l10n = context.l10n;

final state = context.watch<HomeBloc>().state;
final isAnimating = state.status == Status.welcomeToAskQuestion;

return AnimatedOpacity(
opacity: isAnimating ? 1 : 0,
duration: const Duration(milliseconds: 500),
child: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
l10n.questionScreenTitle,
textAlign: TextAlign.center,
style: theme.textTheme.displayLarge,
),
const SizedBox(height: 40),
QuestionInputTextField(
icon: vertexIcons.stars.image(),
hint: l10n.questionHint,
actionText: l10n.ask,
),
],
),
),
),
);
}
}
49 changes: 32 additions & 17 deletions lib/home/widgets/welcome_view.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import 'package:app_ui/app_ui.dart';
import 'package:dash_ai_search/home/home.dart';
import 'package:dash_ai_search/l10n/l10n.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class WelcomeView extends StatelessWidget {
const WelcomeView({super.key});
Expand All @@ -10,24 +12,37 @@ class WelcomeView extends StatelessWidget {
final theme = Theme.of(context);
final l10n = context.l10n;

return Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
l10n.initialScreenTitle,
textAlign: TextAlign.center,
style: theme.textTheme.displayLarge?.copyWith(
color: VertexColors.navy,
),
),
const SizedBox(height: 40),
CTAButton(
icon: vertexIcons.arrowForward.image(),
label: l10n.startAsking,
final state = context.watch<HomeBloc>().state;
final isAnimating = state.status == Status.welcomeToAskQuestion;

return AnimatedOpacity(
opacity: isAnimating ? 0 : 1,
duration: const Duration(milliseconds: 500),
child: IgnorePointer(
ignoring: !state.isWelcomeVisible,
child: Center(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
l10n.initialScreenTitle,
textAlign: TextAlign.center,
style: theme.textTheme.displayLarge?.copyWith(
color: VertexColors.navy,
),
),
const SizedBox(height: 40),
CTAButton(
icon: vertexIcons.arrowForward.image(),
label: l10n.startAsking,
onPressed: () => context
.read<HomeBloc>()
.add(const FromWelcomeToQuestion()),
),
],
),
],
),
),
),
);
Expand Down
1 change: 1 addition & 0 deletions lib/home/widgets/widgets.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export 'background.dart';
export 'logo.dart';
export 'question_view.dart';
export 'welcome_view.dart';
12 changes: 12 additions & 0 deletions lib/l10n/arb/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,17 @@
"startAsking": "Start asking",
"@startAsking": {
"description": "Button text for start asking"
},
"questionScreenTitle": "Ask a question",
"@questionScreenTitle": {
"description": "Title shown on Question screen"
},
"questionHint": "Ex: How do I manage a state?",
"@questionHint": {
"description": "Hint shown on Question screen"
},
"ask": "Ask",
"@ask": {
"description": "Button text for ask"
}
}
Binary file added packages/app_ui/assets/icons/stars.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion packages/app_ui/lib/src/generated/assets.gen.dart

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

15 changes: 15 additions & 0 deletions packages/app_ui/lib/src/generated/fonts.gen.dart

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

27 changes: 27 additions & 0 deletions packages/app_ui/lib/src/theme/vertex_theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class VertexTheme {
return ThemeData(
colorScheme: ColorScheme.fromSwatch(accentColor: VertexColors.navy),
textTheme: _textTheme,
inputDecorationTheme: _inputDecorationTheme,
useMaterial3: true,
);
}
Expand All @@ -21,4 +22,30 @@ class VertexTheme {
labelLarge: VertexTextStyles.label,
);
}

static InputDecorationTheme get _inputDecorationTheme {
return InputDecorationTheme(
hintStyle: VertexTextStyles.body.copyWith(color: VertexColors.mediumGrey),
isDense: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(100),
borderSide: const BorderSide(
color: VertexColors.googleBlue,
),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(100),
borderSide: const BorderSide(
color: VertexColors.googleBlue,
),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(100),
borderSide: const BorderSide(
color: VertexColors.googleBlue,
),
),
contentPadding: const EdgeInsets.symmetric(vertical: 32),
);
}
}
6 changes: 3 additions & 3 deletions packages/app_ui/lib/src/widgets/cta_button.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ class CTAButton extends StatelessWidget {
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: onPressed,
style: const ButtonStyle(
backgroundColor: MaterialStatePropertyAll(
style: ButtonStyle(
backgroundColor: const MaterialStatePropertyAll(
VertexColors.googleBlue,
),
padding: MaterialStatePropertyAll(
EdgeInsets.only(
left: 24,
left: icon != null ? 24 : 32,
top: 20,
bottom: 20,
right: 32,
Expand Down
Loading

0 comments on commit ca84b50

Please sign in to comment.