Browse Source
Merge pull request 'add/marquee' (#49) from add/marquee into develop
Merge pull request 'add/marquee' (#49) from add/marquee into develop
Reviewed-on: https://git.nwhco.ir/amirreza.chegini/hade_hoda_flutter/pulls/49develop
18 changed files with 727 additions and 141 deletions
-
10lib/core/middlewares/my_middlewares.dart
-
15lib/core/routers/my_routes.dart
-
57lib/core/widgets/answer_box/answer_box.dart
-
111lib/core/widgets/answer_box/answer_box_showcase.dart
-
6lib/core/widgets/showcase/my_showcase_widget.dart
-
33lib/features/guider/data/datasource/guider_datasource.dart
-
28lib/features/guider/data/repository_impl/guider_repository_impl.dart
-
7lib/features/guider/domain/repository/guider_repository.dart
-
17lib/features/guider/domain/usecases/get_first_level_usecase.dart
-
131lib/features/guider/presentation/bloc/guider_bloc.dart
-
8lib/features/guider/presentation/bloc/guider_event.dart
-
27lib/features/guider/presentation/bloc/guider_state.dart
-
247lib/features/guider/presentation/ui/guider_page.dart
-
4lib/features/language/presentation/ui/language_page.dart
-
70lib/features/question/presentation/bloc/question_bloc.dart
-
83lib/features/question/presentation/ui/screens/question_screen.dart
-
5lib/features/sample/presentation/ui/sample_page.dart
-
9lib/init_bindings.dart
@ -0,0 +1,111 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; |
|||
import 'package:hadi_hoda_flutter/common_ui/resources/my_spaces.dart'; |
|||
import 'package:hadi_hoda_flutter/core/utils/my_localization.dart'; |
|||
import 'package:hadi_hoda_flutter/core/utils/set_platform_size.dart'; |
|||
import 'package:hadi_hoda_flutter/core/widgets/answer_box/styles/picture_box.dart'; |
|||
import 'package:hadi_hoda_flutter/core/widgets/answer_box/styles/text_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'; |
|||
|
|||
class AnswerBoxShowCase extends StatefulWidget { |
|||
const AnswerBoxShowCase({ |
|||
super.key, |
|||
required this.answer, |
|||
required this.correctAnswer, |
|||
required this.index, |
|||
this.globalKey, |
|||
this.answerGlobalKey, |
|||
this.onTap, |
|||
this.onNotifTap, |
|||
}); |
|||
|
|||
final AnswerEntity answer; |
|||
final int correctAnswer; |
|||
final void Function(bool isCorrect, int correctAnswer)? onTap; |
|||
final int index; |
|||
final Function(AnswerEntity answer)? onNotifTap; |
|||
final GlobalKey? globalKey; |
|||
final GlobalKey? answerGlobalKey; |
|||
|
|||
@override |
|||
State<AnswerBoxShowCase> createState() => _AnswerBoxShowCaseState(); |
|||
} |
|||
|
|||
class _AnswerBoxShowCaseState extends State<AnswerBoxShowCase> { |
|||
bool selected = false; |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Hero( |
|||
tag: 'Hero_answer_${widget.answer.id}', |
|||
child: Material( |
|||
type: MaterialType.transparency, |
|||
child: GestureDetector( |
|||
onTap: !selected |
|||
? () { |
|||
setState(() { |
|||
selected = true; |
|||
}); |
|||
widget.onTap?.call( |
|||
widget.index == widget.correctAnswer, |
|||
widget.correctAnswer, |
|||
); |
|||
} |
|||
: null, |
|||
child: Stack( |
|||
alignment: Alignment.topCenter, |
|||
children: [ |
|||
MyShowcaseWidget( |
|||
globalKey: widget.answerGlobalKey, |
|||
description: context.translate.showcase_answer, |
|||
child: AnswerPictureBox( |
|||
selected: selected, |
|||
index: widget.index, |
|||
image: widget.answer.image ?? '', |
|||
correctAnswer: widget.correctAnswer, |
|||
onTap: () { |
|||
widget.onNotifTap?.call(widget.answer); |
|||
}, |
|||
), |
|||
), |
|||
Positioned( |
|||
left: 0, |
|||
right: 0, |
|||
bottom: 0, |
|||
child: AnswerTextBox(text: widget.answer.title ?? ''), |
|||
), |
|||
PositionedDirectional( |
|||
top: setSize( |
|||
context: context, |
|||
mobile: MySpaces.s12, |
|||
tablet: MySpaces.s20, |
|||
), |
|||
end: setSize( |
|||
context: context, |
|||
mobile: MySpaces.s8, |
|||
tablet: MySpaces.s20, |
|||
), |
|||
child: MyShowcaseWidget( |
|||
globalKey: widget.globalKey, |
|||
type: ShowcaseTooltipType.bottom, |
|||
description: context.translate.showcase_notif, |
|||
child: GestureDetector( |
|||
onTap: () { |
|||
widget.onNotifTap?.call(widget.answer); |
|||
}, |
|||
child: MyImage( |
|||
image: MyAssets.iconNotif, |
|||
size: setSize(context: context, tablet: 50), |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,33 @@ |
|||
import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; |
|||
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; |
|||
import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; |
|||
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; |
|||
import 'package:hadi_hoda_flutter/features/level/domain/entity/total_data_entity.dart'; |
|||
import 'package:hive/hive.dart'; |
|||
|
|||
abstract class IGuiderDatasource { |
|||
Future<LevelEntity> getLevel(); |
|||
} |
|||
|
|||
/// Local |
|||
class GuiderDatasourceImpl implements IGuiderDatasource { |
|||
const GuiderDatasourceImpl(); |
|||
|
|||
@override |
|||
Future<LevelEntity> getLevel() async { |
|||
try { |
|||
final String selectedLanguage = |
|||
LocalStorage.readData(key: MyConstants.selectLanguage) ?? |
|||
MyConstants.defaultLanguage; |
|||
final Box<TotalDataEntity> levelBox = Hive.box(MyConstants.levelBox); |
|||
final TotalDataEntity findData = levelBox.values.singleWhere( |
|||
(e) => e.code == selectedLanguage, |
|||
orElse: () => TotalDataEntity(), |
|||
); |
|||
final LevelEntity? findLevel = findData.levels?.first; |
|||
return findLevel ?? LevelEntity(); |
|||
} catch (e) { |
|||
throw MyException(errorMessage: '$e'); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
import 'package:flutter/foundation.dart'; |
|||
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; |
|||
import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; |
|||
import 'package:hadi_hoda_flutter/features/guider/data/datasource/guider_datasource.dart'; |
|||
import 'package:hadi_hoda_flutter/features/guider/domain/repository/guider_repository.dart'; |
|||
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; |
|||
|
|||
class GuiderRepositoryImpl implements IGuiderRepository { |
|||
final IGuiderDatasource datasource; |
|||
|
|||
const GuiderRepositoryImpl(this.datasource); |
|||
|
|||
@override |
|||
Future<DataState<LevelEntity, MyException>> getLevel() async { |
|||
try { |
|||
final LevelEntity response = await datasource.getLevel(); |
|||
return DataState.success(response); |
|||
} on MyException catch (e) { |
|||
return DataState.error(e); |
|||
} catch (e) { |
|||
if (kDebugMode) { |
|||
rethrow; |
|||
} else { |
|||
return DataState.error(MyException(errorMessage: '$e')); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,7 @@ |
|||
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; |
|||
import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; |
|||
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; |
|||
|
|||
abstract class IGuiderRepository { |
|||
Future<DataState<LevelEntity, MyException>> getLevel(); |
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
import 'package:hadi_hoda_flutter/core/error_handler/my_exception.dart'; |
|||
import 'package:hadi_hoda_flutter/core/params/no_params.dart'; |
|||
import 'package:hadi_hoda_flutter/core/usecase/usecase.dart'; |
|||
import 'package:hadi_hoda_flutter/core/utils/data_state.dart'; |
|||
import 'package:hadi_hoda_flutter/features/guider/domain/repository/guider_repository.dart'; |
|||
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; |
|||
|
|||
class GetFirstLevelUseCase implements UseCase<LevelEntity, NoParams> { |
|||
final IGuiderRepository repository; |
|||
|
|||
const GetFirstLevelUseCase(this.repository); |
|||
|
|||
@override |
|||
Future<DataState<LevelEntity, MyException>> call(NoParams params) { |
|||
return repository.getLevel(); |
|||
} |
|||
} |
|||
@ -0,0 +1,131 @@ |
|||
import 'dart:async'; |
|||
|
|||
import 'package:bloc/bloc.dart'; |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:go_router/go_router.dart'; |
|||
import 'package:hadi_hoda_flutter/core/constants/my_constants.dart'; |
|||
import 'package:hadi_hoda_flutter/core/params/no_params.dart'; |
|||
import 'package:hadi_hoda_flutter/core/routers/my_routes.dart'; |
|||
import 'package:hadi_hoda_flutter/core/status/base_status.dart'; |
|||
import 'package:hadi_hoda_flutter/core/utils/local_storage.dart'; |
|||
import 'package:hadi_hoda_flutter/core/utils/my_context.dart'; |
|||
import 'package:hadi_hoda_flutter/features/guider/domain/usecases/get_first_level_usecase.dart'; |
|||
import 'package:hadi_hoda_flutter/features/guider/presentation/bloc/guider_event.dart'; |
|||
import 'package:hadi_hoda_flutter/features/guider/presentation/bloc/guider_state.dart'; |
|||
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; |
|||
import 'package:hadi_hoda_flutter/features/question/domain/entity/question_entity.dart'; |
|||
import 'package:showcaseview/showcaseview.dart'; |
|||
|
|||
class GuiderBloc extends Bloc<GuiderEvent, GuiderState> { |
|||
/// ------------constructor------------ |
|||
GuiderBloc(this._getFirstLevelUseCase) : super(const GuiderState()) { |
|||
registerShowCase(); |
|||
on<GetFirstLevelEvent>(_getFirstLevelEvent); |
|||
} |
|||
|
|||
@override |
|||
Future<void> close() { |
|||
unRegisterShowCase(); |
|||
animationController.dispose(); |
|||
return super.close(); |
|||
} |
|||
|
|||
/// ------------UseCases------------ |
|||
final GetFirstLevelUseCase _getFirstLevelUseCase; |
|||
|
|||
/// ------------Variables------------ |
|||
final Map<String, GlobalKey> showCaseKey = { |
|||
'answer_key_0': GlobalKey(), |
|||
'answer_key_1': GlobalKey(), |
|||
'answer_key_2': GlobalKey(), |
|||
'answer_key_3': GlobalKey(), |
|||
'notif_key_0': GlobalKey(), |
|||
'notif_key_1': GlobalKey(), |
|||
'notif_key_2': GlobalKey(), |
|||
'notif_key_3': GlobalKey(), |
|||
'stepper_key': GlobalKey(), |
|||
'hadith_key': GlobalKey(), |
|||
'guide_key': GlobalKey(), |
|||
}; |
|||
String? id; |
|||
|
|||
/// ------------Controllers------------ |
|||
late final AnimationController animationController; |
|||
|
|||
/// ------------Functions------------ |
|||
void registerShowCase() { |
|||
try { |
|||
ShowcaseView.register( |
|||
onStart: (showcaseIndex, key) { |
|||
LocalStorage.saveData(key: MyConstants.firstShowcase, value: 'true'); |
|||
}, |
|||
onDismiss: (onDismiss) { |
|||
MyContext.get.goNamed( |
|||
Routes.questionPage, |
|||
pathParameters: {'id': id ?? ''}, |
|||
); |
|||
}, |
|||
onFinish: () { |
|||
MyContext.get.goNamed( |
|||
Routes.questionPage, |
|||
pathParameters: {'id': id ?? ''}, |
|||
); |
|||
}, |
|||
); |
|||
} catch (_) {} |
|||
} |
|||
|
|||
void unRegisterShowCase() { |
|||
try { |
|||
ShowcaseView.get().unregister(); |
|||
} catch (_) {} |
|||
} |
|||
|
|||
void startShowcase() { |
|||
if (LocalStorage.readData(key: MyConstants.firstShowcase) != 'true') { |
|||
try { |
|||
ShowcaseView.get().startShowCase([ |
|||
showCaseKey['answer_key_1']!, |
|||
showCaseKey['notif_key_0']!, |
|||
showCaseKey['stepper_key']!, |
|||
showCaseKey['hadith_key']!, |
|||
showCaseKey['guide_key']!, |
|||
]); |
|||
} catch (_) {} |
|||
} |
|||
} |
|||
|
|||
/// ------------Event Calls------------ |
|||
|
|||
FutureOr<void> _getFirstLevelEvent( |
|||
GetFirstLevelEvent event, |
|||
Emitter<GuiderState> emit, |
|||
) async { |
|||
id = event.id; |
|||
await _getFirstLevelUseCase(NoParams()).then( |
|||
(value) => value.fold((data) async { |
|||
final LevelEntity level = LevelEntity( |
|||
id: data.id, |
|||
order: data.order, |
|||
title: data.title, |
|||
questions: [ |
|||
...?data.questions, |
|||
QuestionEntity(order: (data.questions?.length ?? 0) + 1), |
|||
], |
|||
); |
|||
emit( |
|||
state.copyWith( |
|||
getQuestionStatus: BaseComplete(''), |
|||
levelEntity: level, |
|||
currentQuestion: data.questions?.first, |
|||
), |
|||
); |
|||
await Future.delayed(Duration(milliseconds: 300), () { |
|||
animationController.forward().then((value) { |
|||
startShowcase(); |
|||
}); |
|||
}); |
|||
}, (error) {}), |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,8 @@ |
|||
sealed class GuiderEvent { |
|||
const GuiderEvent(); |
|||
} |
|||
|
|||
class GetFirstLevelEvent extends GuiderEvent { |
|||
final String? id; |
|||
const GetFirstLevelEvent({this.id}); |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
import 'package:hadi_hoda_flutter/core/status/base_status.dart'; |
|||
import 'package:hadi_hoda_flutter/features/level/domain/entity/level_entity.dart'; |
|||
import 'package:hadi_hoda_flutter/features/question/domain/entity/question_entity.dart'; |
|||
|
|||
class GuiderState { |
|||
final BaseStatus getQuestionStatus; |
|||
final LevelEntity? levelEntity; |
|||
final QuestionEntity? currentQuestion; |
|||
|
|||
const GuiderState({ |
|||
this.getQuestionStatus = const BaseInit(), |
|||
this.levelEntity, |
|||
this.currentQuestion, |
|||
}); |
|||
|
|||
GuiderState copyWith({ |
|||
BaseStatus? getQuestionStatus, |
|||
LevelEntity? levelEntity, |
|||
QuestionEntity? currentQuestion, |
|||
}) { |
|||
return GuiderState( |
|||
getQuestionStatus: getQuestionStatus ?? this.getQuestionStatus, |
|||
levelEntity: levelEntity ?? this.levelEntity, |
|||
currentQuestion: currentQuestion ?? this.currentQuestion, |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,247 @@ |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_bloc/flutter_bloc.dart'; |
|||
import 'package:hadi_hoda_flutter/common_ui/resources/my_assets.dart'; |
|||
import 'package:hadi_hoda_flutter/common_ui/resources/my_audios.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/utils/gap.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/slide_anim.dart'; |
|||
import 'package:hadi_hoda_flutter/core/widgets/animations/slide_down_fade.dart'; |
|||
import 'package:hadi_hoda_flutter/core/widgets/animations/slide_up_fade.dart'; |
|||
import 'package:hadi_hoda_flutter/core/widgets/answer_box/answer_box_showcase.dart'; |
|||
import 'package:hadi_hoda_flutter/core/widgets/images/my_image.dart'; |
|||
import 'package:hadi_hoda_flutter/core/widgets/pop_scope/my_pop_scope.dart'; |
|||
import 'package:hadi_hoda_flutter/core/widgets/showcase/my_showcase_widget.dart'; |
|||
import 'package:hadi_hoda_flutter/features/guider/presentation/bloc/guider_bloc.dart'; |
|||
import 'package:hadi_hoda_flutter/features/guider/presentation/bloc/guider_state.dart'; |
|||
import 'package:hadi_hoda_flutter/features/question/domain/entity/answer_entity.dart'; |
|||
import 'package:hadi_hoda_flutter/features/question/presentation/ui/widgets/glassy_button.dart'; |
|||
import 'package:hadi_hoda_flutter/features/question/presentation/ui/widgets/question_stepper.dart'; |
|||
import 'package:hadi_hoda_flutter/features/question/presentation/ui/widgets/question_title.dart'; |
|||
|
|||
class GuiderPage extends StatefulWidget { |
|||
const GuiderPage({super.key}); |
|||
|
|||
@override |
|||
State<GuiderPage> createState() => _GuiderPageState(); |
|||
} |
|||
|
|||
class _GuiderPageState extends State<GuiderPage> with TickerProviderStateMixin { |
|||
|
|||
@override |
|||
void initState() { |
|||
super.initState(); |
|||
context |
|||
.read<GuiderBloc>() |
|||
.animationController = AnimationController( |
|||
vsync: this, |
|||
duration: Duration(milliseconds: 500), |
|||
reverseDuration: Duration(milliseconds: 500), |
|||
); |
|||
} |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
return Scaffold( |
|||
body: MyPopScope( |
|||
child: Directionality( |
|||
textDirection: TextDirection.ltr, |
|||
child: Container( |
|||
height: context.heightScreen, |
|||
width: context.widthScreen, |
|||
padding: EdgeInsets.symmetric( |
|||
horizontal: |
|||
setSize( |
|||
context: context, |
|||
mobile: MySpaces.s16, |
|||
tablet: MySpaces.s30, |
|||
) ?? |
|||
0, |
|||
), |
|||
decoration: BoxDecoration( |
|||
gradient: LinearGradient( |
|||
begin: Alignment.topCenter, |
|||
end: Alignment.bottomCenter, |
|||
colors: [Color(0XFF6930DA), Color(0XFF263AA1)], |
|||
), |
|||
image: DecorationImage( |
|||
image: AssetImage(MyAssets.pattern), |
|||
scale: 3, |
|||
repeat: ImageRepeat.repeat, |
|||
colorFilter: ColorFilter.mode( |
|||
Colors.black.withValues(alpha: 0.3), |
|||
BlendMode.srcIn, |
|||
), |
|||
), |
|||
), |
|||
child: Column( |
|||
children: [ |
|||
setPlatform<double>( |
|||
android: MySpaces.s20, |
|||
iOS: 50, |
|||
)?.gapHeight ?? |
|||
SizedBox.shrink(), |
|||
_topButtons(context), |
|||
MySpaces.s10.gapHeight, |
|||
Expanded( |
|||
child: Column( |
|||
children: [ |
|||
_stepper(context), |
|||
_titles(context), |
|||
MySpaces.s20.gapHeight, |
|||
Expanded(child: _answers(context)), |
|||
_bottom(context), |
|||
], |
|||
), |
|||
), |
|||
setPlatform<double>(android: MySpaces.s20)?.gapHeight ?? |
|||
SizedBox.shrink(), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _topButtons(BuildContext context) { |
|||
return SlideDownFade( |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
crossAxisAlignment: CrossAxisAlignment.center, |
|||
children: [ |
|||
GlassyButton( |
|||
image: MyAssets.home, |
|||
audio: MyAudios.back, |
|||
onTap: () {}, |
|||
), |
|||
BlocBuilder<GuiderBloc, GuiderState>( |
|||
builder: (context, state) => |
|||
QuestionTitle( |
|||
step: state.levelEntity?.order, |
|||
currentQuestion: state.currentQuestion?.order, |
|||
questionLength: state.levelEntity?.questions?.length, |
|||
), |
|||
), |
|||
GlassyButton(image: MyAssets.music, onTap: () {}), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _stepper(BuildContext context) { |
|||
return FadeAnim( |
|||
child: MyShowcaseWidget( |
|||
globalKey: context |
|||
.read<GuiderBloc>() |
|||
.showCaseKey['stepper_key']!, |
|||
description: context.translate.showcase_stepper, |
|||
child: QuestionStepper(length: 4, currentStep: 1), |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _titles(BuildContext context) { |
|||
return BlocBuilder<GuiderBloc, GuiderState>( |
|||
builder: (context, state) => |
|||
FadeAnim( |
|||
child: Text( |
|||
state.currentQuestion?.title ?? '', |
|||
textAlign: TextAlign.center, |
|||
maxLines: 3, |
|||
style: MYTextStyle.titr1.copyWith( |
|||
shadows: [ |
|||
BoxShadow( |
|||
offset: Offset(0, 2), |
|||
color: MyColors.black.withValues(alpha: 0.25), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _answers(BuildContext context) { |
|||
return BlocBuilder<GuiderBloc, GuiderState>( |
|||
builder: (context, state) => |
|||
GridView.builder( |
|||
itemCount: state.currentQuestion?.answers?.length ?? 0, |
|||
physics: NeverScrollableScrollPhysics(), |
|||
shrinkWrap: true, |
|||
clipBehavior: Clip.none, |
|||
padding: EdgeInsets.symmetric( |
|||
horizontal: setSize(context: context, tablet: 70) ?? 0, |
|||
), |
|||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( |
|||
crossAxisCount: 2, |
|||
crossAxisSpacing: MySpaces.s20, |
|||
mainAxisSpacing: 20, |
|||
childAspectRatio: 0.75, |
|||
), |
|||
itemBuilder: (context, index) => |
|||
state.currentQuestion?.answers?[index].imageId == null |
|||
? SizedBox.shrink() |
|||
: SlideAnim( |
|||
controller: context.read<GuiderBloc>().animationController, |
|||
index: index, |
|||
child: AnswerBoxShowCase( |
|||
globalKey: context |
|||
.read<GuiderBloc>() |
|||
.showCaseKey['notif_key_$index']!, |
|||
answerGlobalKey: context |
|||
.read<GuiderBloc>() |
|||
.showCaseKey['answer_key_$index']!, |
|||
index: state.currentQuestion?.answers?[index].order ?? 1, |
|||
answer: |
|||
state.currentQuestion?.answers?[index] ?? AnswerEntity(), |
|||
correctAnswer: 0, |
|||
onNotifTap: (AnswerEntity answer) {}, |
|||
onTap: (isCorrect, correctAnswer) {}, |
|||
), |
|||
), |
|||
), |
|||
); |
|||
} |
|||
|
|||
Widget _bottom(BuildContext context) { |
|||
return SlideUpFade( |
|||
child: SizedBox( |
|||
width: context.widthScreen, |
|||
child: Stack( |
|||
alignment: AlignmentDirectional.centerStart, |
|||
children: [ |
|||
MyShowcaseWidget( |
|||
globalKey: context |
|||
.read<GuiderBloc>() |
|||
.showCaseKey['guide_key']!, |
|||
description: context.translate.showcase_guide, |
|||
type: ShowcaseTooltipType.top, |
|||
child: MyImage( |
|||
image: MyAssets.globe, |
|||
fit: BoxFit.cover, |
|||
size: setSize(context: context, tablet: 120), |
|||
), |
|||
), |
|||
PositionedDirectional( |
|||
end: 0, |
|||
child: MyShowcaseWidget( |
|||
globalKey: context |
|||
.read<GuiderBloc>() |
|||
.showCaseKey['hadith_key']!, |
|||
type: ShowcaseTooltipType.topLeft, |
|||
description: context.translate.showcase_hadith, |
|||
child: GlassyButton(image: MyAssets.leaf, onTap: () {}), |
|||
), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue