310 lines
13 KiB
Dart
310 lines
13 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:stacked/stacked.dart';
|
|
import 'package:stacked/stacked_annotations.dart';
|
|
import 'package:yimaru_app/models/course_question.dart';
|
|
import 'package:yimaru_app/ui/common/enmus.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_listening_practice_1_review.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_listening_practice_2_review.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_practices_screens.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_finish_screen.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_intro_screen.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_listening_practice_1_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_listening_practice_2_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_listening_practice_3_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_retake_screen.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_1_answer.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_1_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_1_review.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_2_answer.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_2_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_2_review.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_3_answer.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_3_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_3_review.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_4_answer.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_4_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_speaking_practice_4_review.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_writing_practice_1_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_writing_practice_1_review.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_writing_practice_2_answer.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_writing_practice_2_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_writing_practice_2_review.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_writing_practice_3_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_writing_practice_3_review.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_writing_practice_4_question.dart';
|
|
import 'package:yimaru_app/ui/views/course_practice/screens/duolingo_writing_practice_4_review.dart';
|
|
|
|
import '../../common/app_colors.dart';
|
|
import '../../common/validators/form_validator.dart';
|
|
import '../../widgets/cancel_practice_sheet.dart';
|
|
import '../../widgets/page_loading_indicator.dart';
|
|
import '../../widgets/practice_loading_screen.dart';
|
|
import 'course_practice_view.form.dart';
|
|
import 'course_practice_viewmodel.dart';
|
|
|
|
@FormView(fields: [
|
|
FormTextField(name: 'practice', validator: FormValidator.validateForm),
|
|
])
|
|
class CoursePracticeView extends StackedView<CoursePracticeViewModel> with $CoursePracticeView {
|
|
final int id;
|
|
|
|
final CoursePractices practice;
|
|
|
|
const CoursePracticeView({
|
|
Key? key,
|
|
required this.id,
|
|
required this.practice,
|
|
}) : super(key: key);
|
|
|
|
Future<void> _cancel(CoursePracticeViewModel viewModel) async {
|
|
await viewModel.stopRecording();
|
|
viewModel.pop();
|
|
viewModel.pop();
|
|
}
|
|
|
|
Future<void> _showSheet(
|
|
{required BuildContext context,
|
|
required CoursePracticeViewModel viewModel}) async =>
|
|
await showModalBottomSheet(
|
|
context: context,
|
|
isScrollControlled: true,
|
|
backgroundColor: kcTransparent,
|
|
builder: (_) => _buildSheet(viewModel),
|
|
);
|
|
|
|
Widget _buildQuestionScreen(CoursePracticeViewModel viewModel) {
|
|
String type =
|
|
viewModel.questions[viewModel.currentQuestion].id.toString() ?? '';
|
|
if (type == '636') {
|
|
return const DuolingoSpeakingPractice1Question();
|
|
} else if (type == 'Read, Then Speak') {
|
|
return const DuolingoSpeakingPractice2Question();
|
|
} else if (type == 'Speaking Sample') {
|
|
return const DuolingoSpeakingPractice3Question();
|
|
} else if (type == 'Interactive Speaking') {
|
|
return const DuolingoSpeakingPractice4Question();
|
|
} else if (type == 'Write About the Photo') {
|
|
return DuolingoWritingPractice1Question(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Writing Sample') {
|
|
return DuolingoWritingPractice2Question(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Interactive Writing Part 1') {
|
|
return DuolingoWritingPractice3Question(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Interactive Writing Part 2') {
|
|
return DuolingoWritingPractice4Question(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Listen and Type') {
|
|
return DuolingoListeningPractice1Question(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Interactive Listening - Part 1') {
|
|
return DuolingoListeningPractice2Question(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Interactive Listening - Part 2') {
|
|
return DuolingoListeningPractice3Question(
|
|
practiceController: practiceController);
|
|
}
|
|
|
|
return Container();
|
|
}
|
|
|
|
Widget _buildAnswerScreen(CoursePracticeViewModel viewModel) {
|
|
String type =
|
|
viewModel.questions[viewModel.currentQuestion].id.toString() ?? '';
|
|
|
|
if (type == '636') {
|
|
return const DuolingoSpeakingPractice1Answer();
|
|
} else if (type == 'Read, Then Speak') {
|
|
return const DuolingoSpeakingPractice2Answer();
|
|
} else if (type == 'Speaking Sample') {
|
|
return const DuolingoSpeakingPractice3Answer();
|
|
} else if (type == 'Interactive Speaking') {
|
|
return const DuolingoSpeakingPractice4Answer();
|
|
} else if (type == 'Write About the Photo') {
|
|
return Container();
|
|
} else if (type == 'Writing Sample') {
|
|
return DuolingoWritingPractice2Answer(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Interactive Writing Part 1') {
|
|
return Container();
|
|
} else if (type == 'Interactive Writing Part 2') {
|
|
return Container();
|
|
} else if (type == 'Listen and Type') {
|
|
return Container();
|
|
} else if (type == 'Interactive Listening - Part 1') {
|
|
return Container();
|
|
}
|
|
|
|
return Container();
|
|
}
|
|
|
|
Widget _buildReviewScreen(CoursePracticeViewModel viewModel) {
|
|
String type =
|
|
viewModel.questions[viewModel.currentQuestion].id.toString() ?? '';
|
|
|
|
if (type == '636') {
|
|
return const DuolingoSpeakingPractice1Review();
|
|
} else if (type == 'Read, Then Speak') {
|
|
return const DuolingoSpeakingPractice2Review();
|
|
} else if (type == 'Speaking Sample') {
|
|
return const DuolingoSpeakingPractice3Review();
|
|
} else if (type == 'Interactive Speaking') {
|
|
return const DuolingoSpeakingPractice4Review();
|
|
} else if (type == 'Write About the Photo') {
|
|
return DuolingoWritingPractice1Review(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Writing Sample') {
|
|
return DuolingoWritingPractice2Review(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Interactive Writing Part 1') {
|
|
return DuolingoWritingPractice3Review(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Interactive Writing Part 2') {
|
|
return DuolingoWritingPractice4Review(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Listen and Type') {
|
|
return DuolingoListeningPractice1Review(
|
|
practiceController: practiceController);
|
|
} else if (type == 'Interactive Listening - Part 1') {
|
|
return DuolingoListeningPractice2Review(
|
|
practiceController: practiceController);
|
|
}
|
|
|
|
return Container();
|
|
}
|
|
|
|
@override
|
|
void onViewModelReady(CoursePracticeViewModel viewModel) async {
|
|
await viewModel.getCoursePractices(id: id, practice: practice);
|
|
super.onViewModelReady(viewModel);
|
|
}
|
|
|
|
|
|
@override
|
|
CoursePracticeViewModel viewModelBuilder(BuildContext context) =>
|
|
CoursePracticeViewModel();
|
|
|
|
@override
|
|
Widget builder(
|
|
BuildContext context,
|
|
CoursePracticeViewModel viewModel,
|
|
Widget? child,
|
|
) =>
|
|
_buildPracticeScreensWrapper(context: context, viewModel: viewModel);
|
|
|
|
Widget _buildPracticeScreensWrapper(
|
|
{required BuildContext context,
|
|
required CoursePracticeViewModel viewModel}) =>
|
|
PopScope(
|
|
canPop: false,
|
|
onPopInvokedWithResult: (didPop, data) {
|
|
if (!didPop) {
|
|
Future.microtask(() async =>
|
|
await _showSheet(context: context, viewModel: viewModel));
|
|
}
|
|
},
|
|
child: _buildScaffoldWrapper(viewModel));
|
|
|
|
Widget _buildSheet(CoursePracticeViewModel viewModel) => CancelPracticeSheet(
|
|
onClose: viewModel.pop,
|
|
onContinue: viewModel.pop,
|
|
user: viewModel.user?.firstName ?? '',
|
|
onCancel: () async => await _cancel(viewModel),
|
|
);
|
|
|
|
Widget _buildScaffoldWrapper(CoursePracticeViewModel viewModel) => Scaffold(
|
|
backgroundColor: kcBackgroundColor,
|
|
body: _buildBodyState(viewModel),
|
|
);
|
|
|
|
Widget _buildBodyState(CoursePracticeViewModel viewModel) =>
|
|
viewModel.busy(StateObjects.coursePractice)
|
|
? const PageLoadingIndicator()
|
|
: viewModel.practices.isEmpty || viewModel.questions.isEmpty
|
|
? _buildPageLoadingIndicator(viewModel)
|
|
: _buildBody(viewModel);
|
|
|
|
Widget _buildPageLoadingIndicator(CoursePracticeViewModel viewModel) =>
|
|
PracticeLoadingScreen(
|
|
isLoading: viewModel.busy(StateObjects.coursePractice),
|
|
onTap: () async =>
|
|
await viewModel.getCoursePractices(id: id, practice: practice),
|
|
onPop: viewModel.practices.isEmpty || viewModel.questions.isEmpty
|
|
? viewModel.pop
|
|
: null,
|
|
isEmpty: viewModel.practices.isEmpty || viewModel.questions.isEmpty,
|
|
);
|
|
|
|
Widget _buildBody(CoursePracticeViewModel viewModel) => IndexedStack(
|
|
index: viewModel.currentPage, children: _buildBodyChildren(viewModel));
|
|
|
|
List<Widget> _buildBodyChildren(CoursePracticeViewModel viewModel) => [
|
|
if (practice != CoursePractices.lesson)
|
|
_buildDuolingoAssessmentsScreen(),
|
|
_buildQuestionSetView(viewModel)
|
|
];
|
|
|
|
Widget _buildQuestionSetView(CoursePracticeViewModel viewModel) =>
|
|
PageView.builder(
|
|
itemCount: viewModel.questions.length,
|
|
controller: viewModel.practiceController,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
itemBuilder: (cotext, index) => _buildQuestionView(
|
|
index: index + 1,
|
|
viewModel: viewModel,
|
|
question: viewModel.questions[index]),
|
|
);
|
|
|
|
Widget _buildQuestionView(
|
|
{required int index,
|
|
required CourseQuestion question,
|
|
required CoursePracticeViewModel viewModel}) =>
|
|
PageView(
|
|
controller: viewModel.questionController,
|
|
physics: const NeverScrollableScrollPhysics(),
|
|
children: _buildScreens(
|
|
index: index, viewModel: viewModel, question: question),
|
|
);
|
|
|
|
List<Widget> _buildScreens(
|
|
{required int index,
|
|
required CourseQuestion question,
|
|
required CoursePracticeViewModel viewModel}) =>
|
|
[
|
|
_buildDuolingoIntroScreen(viewModel),
|
|
_buildDuolingoQuestionScreen(viewModel),
|
|
_buildDuolingoAnswerScreen(viewModel),
|
|
_buildDuolingoReviewScreen(viewModel),
|
|
_buildDuolingoRetakeScreen(viewModel),
|
|
_buildDuolingoFinishScreen(viewModel),
|
|
];
|
|
|
|
Widget _buildDuolingoAssessmentsScreen() => const DuolingoPracticesScreens();
|
|
|
|
Widget _buildDuolingoIntroScreen(CoursePracticeViewModel viewModel) =>
|
|
DuolingoIntroScreen(
|
|
type: viewModel.selectedQuestionParam['type'],
|
|
title: viewModel.selectedQuestionParam['intro_title'],
|
|
subtitle: viewModel.selectedQuestionParam['intro_subtitle']);
|
|
|
|
Widget _buildDuolingoQuestionScreen(CoursePracticeViewModel viewModel) =>
|
|
_buildQuestionScreen(viewModel);
|
|
|
|
Widget _buildDuolingoAnswerScreen(CoursePracticeViewModel viewModel) =>
|
|
_buildAnswerScreen(viewModel);
|
|
|
|
Widget _buildDuolingoReviewScreen(CoursePracticeViewModel viewModel) =>
|
|
_buildReviewScreen(viewModel);
|
|
|
|
Widget _buildDuolingoRetakeScreen(CoursePracticeViewModel viewModel) =>
|
|
DuolingoRetakeScreen(
|
|
title: viewModel.selectedQuestionParam['outro_title'],
|
|
subtitle: viewModel.selectedQuestionParam['outro_subtitle']);
|
|
|
|
Widget _buildDuolingoFinishScreen(CoursePracticeViewModel viewModel) =>
|
|
DuolingoFinishScreen(
|
|
title: viewModel.selectedQuestionParam['outro_title'],
|
|
subtitle: viewModel.selectedQuestionParam['outro_subtitle']);
|
|
}
|