|
|
|
@ -5,15 +5,19 @@ import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/common_ui/resources/my_colors.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/common_ui/resources/my_text_style.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/utils/gap.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/utils/screen_size.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/widgets/animations/fade_anim.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/widgets/animations/fade_anim_controller.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/widgets/animations/globe_animation.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/widgets/animations/slide_anim.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/widgets/animations/slide_up_fade.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/widgets/answer_box/answer_box.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/widgets/answer_box/styles/picture_box.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/core/widgets/showcase/my_showcase_widget.dart'; |
|
|
|
import 'package:hadi_hoda_flutter/features/question/domain/entity/answer_entity.dart'; |
|
|
|
@ -30,16 +34,25 @@ class QuestionScreen extends StatefulWidget { |
|
|
|
State<QuestionScreen> createState() => _QuestionScreenState(); |
|
|
|
} |
|
|
|
|
|
|
|
class _QuestionScreenState extends State<QuestionScreen> with SingleTickerProviderStateMixin { |
|
|
|
class _QuestionScreenState extends State<QuestionScreen> with TickerProviderStateMixin { |
|
|
|
|
|
|
|
@override |
|
|
|
void initState() { |
|
|
|
super.initState(); |
|
|
|
context.read<QuestionBloc>().animationController = AnimationController( |
|
|
|
context.read<QuestionBloc>().answerAnimationController = AnimationController( |
|
|
|
vsync: this, |
|
|
|
duration: Duration(milliseconds: 500), |
|
|
|
reverseDuration: Duration(milliseconds: 500), |
|
|
|
); |
|
|
|
|
|
|
|
context.read<QuestionBloc>().imageAnimationController = AnimationController( |
|
|
|
vsync: this, |
|
|
|
duration: Duration(milliseconds: 500), |
|
|
|
reverseDuration: Duration(milliseconds: 500), |
|
|
|
); |
|
|
|
if(LocalStorage.readData(key: MyConstants.firstShowcase) == 'true') { |
|
|
|
context.read<QuestionBloc>().imageAnimationController.forward(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@override |
|
|
|
@ -49,12 +62,39 @@ class _QuestionScreenState extends State<QuestionScreen> with SingleTickerProvid |
|
|
|
_stepper(), |
|
|
|
_titles(context), |
|
|
|
MySpaces.s20.gapHeight, |
|
|
|
_answers(context), |
|
|
|
Expanded( |
|
|
|
child: Stack( |
|
|
|
children: [ |
|
|
|
_questionImage(context), |
|
|
|
_answers(context), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
_bottom(context), |
|
|
|
], |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
Widget _questionImage(BuildContext context) { |
|
|
|
return Column( |
|
|
|
children: [ |
|
|
|
Spacer(), |
|
|
|
FadeAnimController( |
|
|
|
controller: context.read<QuestionBloc>().imageAnimationController, |
|
|
|
child: BlocBuilder<QuestionBloc, QuestionState>( |
|
|
|
builder: (context, state) => AnswerPictureBox( |
|
|
|
selected: false, |
|
|
|
correctAnswer: 0, |
|
|
|
index: 0, |
|
|
|
image: state.currentQuestion?.image ?? '', |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
Spacer(), |
|
|
|
], |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
Widget _stepper() { |
|
|
|
return BlocBuilder<QuestionBloc, QuestionState>( |
|
|
|
buildWhen: (previous, current) => |
|
|
|
@ -97,54 +137,53 @@ class _QuestionScreenState extends State<QuestionScreen> with SingleTickerProvid |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
Expanded _answers(BuildContext context) { |
|
|
|
return Expanded( |
|
|
|
child: BlocBuilder<QuestionBloc, QuestionState>( |
|
|
|
buildWhen: (previous, current) => |
|
|
|
previous.currentQuestion?.id != current.currentQuestion?.id, |
|
|
|
builder: (context, state) => GridView.builder( |
|
|
|
itemCount: state.currentQuestion?.answers?.length ?? 0, |
|
|
|
physics: NeverScrollableScrollPhysics(), |
|
|
|
shrinkWrap: true, |
|
|
|
padding: EdgeInsets.symmetric( |
|
|
|
horizontal: setSize(context: context, tablet: 70) ?? 0, |
|
|
|
), |
|
|
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( |
|
|
|
crossAxisCount: 2, |
|
|
|
crossAxisSpacing: MySpaces.s20, |
|
|
|
mainAxisSpacing: 80, |
|
|
|
), |
|
|
|
itemBuilder: (context, index) => |
|
|
|
state.currentQuestion?.answers?[index].imageId == null |
|
|
|
? SizedBox.shrink() |
|
|
|
: SlideAnim( |
|
|
|
key: Key('${state.currentQuestion?.id}'), |
|
|
|
controller: context.read<QuestionBloc>().animationController, |
|
|
|
index: index, |
|
|
|
child: MyShowcaseWidget( |
|
|
|
globalKey: context.read<QuestionBloc>().showCaseKey['answer_key_$index']!, |
|
|
|
description: context.translate.showcase_answer, |
|
|
|
child: AnswerBox( |
|
|
|
globalKey: context.read<QuestionBloc>().showCaseKey['notif_key_$index']!, |
|
|
|
index: state.currentQuestion?.answers?[index].order ?? 1, |
|
|
|
answer: |
|
|
|
state.currentQuestion?.answers?[index] ?? |
|
|
|
AnswerEntity(), |
|
|
|
correctAnswer: state.currentQuestion?.correctAnswer ?? 0, |
|
|
|
onNotifTap: (AnswerEntity answer) { |
|
|
|
context.read<QuestionBloc>().showAnswerDialog( |
|
|
|
context: context, |
|
|
|
answerEntity: answer, |
|
|
|
); |
|
|
|
}, |
|
|
|
onTap: (isCorrect, correctAnswer) => |
|
|
|
context.read<QuestionBloc>().add( |
|
|
|
ChooseAnswerEvent(isCorrect, correctAnswer, context), |
|
|
|
), |
|
|
|
), |
|
|
|
Widget _answers(BuildContext context) { |
|
|
|
return BlocBuilder<QuestionBloc, QuestionState>( |
|
|
|
buildWhen: (previous, current) => |
|
|
|
previous.currentQuestion?.id != current.currentQuestion?.id, |
|
|
|
builder: (context, state) => GridView.builder( |
|
|
|
itemCount: state.currentQuestion?.answers?.length ?? 0, |
|
|
|
physics: NeverScrollableScrollPhysics(), |
|
|
|
shrinkWrap: true, |
|
|
|
padding: EdgeInsets.symmetric( |
|
|
|
horizontal: setSize(context: context, tablet: 70) ?? 0, |
|
|
|
), |
|
|
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( |
|
|
|
crossAxisCount: 2, |
|
|
|
crossAxisSpacing: MySpaces.s20, |
|
|
|
mainAxisSpacing: 20, |
|
|
|
mainAxisExtent: 250 |
|
|
|
), |
|
|
|
itemBuilder: (context, index) => |
|
|
|
state.currentQuestion?.answers?[index].imageId == null |
|
|
|
? SizedBox.shrink() |
|
|
|
: SlideAnim( |
|
|
|
key: Key('${state.currentQuestion?.id}'), |
|
|
|
controller: context.read<QuestionBloc>().answerAnimationController, |
|
|
|
index: index, |
|
|
|
child: MyShowcaseWidget( |
|
|
|
globalKey: context.read<QuestionBloc>().showCaseKey['answer_key_$index']!, |
|
|
|
description: context.translate.showcase_answer, |
|
|
|
child: AnswerBox( |
|
|
|
globalKey: context.read<QuestionBloc>().showCaseKey['notif_key_$index']!, |
|
|
|
index: state.currentQuestion?.answers?[index].order ?? 1, |
|
|
|
answer: |
|
|
|
state.currentQuestion?.answers?[index] ?? |
|
|
|
AnswerEntity(), |
|
|
|
correctAnswer: state.currentQuestion?.correctAnswer ?? 0, |
|
|
|
onNotifTap: (AnswerEntity answer) { |
|
|
|
context.read<QuestionBloc>().showAnswerDialog( |
|
|
|
context: context, |
|
|
|
answerEntity: answer, |
|
|
|
); |
|
|
|
}, |
|
|
|
onTap: (isCorrect, correctAnswer) => |
|
|
|
context.read<QuestionBloc>().add( |
|
|
|
ChooseAnswerEvent(isCorrect, correctAnswer, context), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
); |
|
|
|
} |
|
|
|
@ -173,6 +212,27 @@ class _QuestionScreenState extends State<QuestionScreen> with SingleTickerProvid |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
Positioned( |
|
|
|
left: 120, |
|
|
|
right: 120, |
|
|
|
child: FadeAnimController( |
|
|
|
controller: context.read<QuestionBloc>().imageAnimationController, |
|
|
|
child: TextButton( |
|
|
|
onPressed: () async { |
|
|
|
context.read<QuestionBloc>().imageAnimationController.reverse(); |
|
|
|
context.read<QuestionBloc>().answerAnimationController.forward(); |
|
|
|
context.read<QuestionBloc>().showingAnswerSequence(show: false); |
|
|
|
}, |
|
|
|
style: TextButton.styleFrom( |
|
|
|
foregroundColor: MyColors.white.withValues(alpha: 0.7), |
|
|
|
), |
|
|
|
child: Text( |
|
|
|
context.translate.skip, |
|
|
|
style: MYTextStyle.button2 |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
PositionedDirectional( |
|
|
|
end: 0, |
|
|
|
child: MyShowcaseWidget( |
|
|
|
|