Browse Source

Merge pull request 'fix/gif' (#56) from fix/gif into develop

Reviewed-on: https://git.nwhco.ir/amirreza.chegini/hade_hoda_flutter/pulls/56
pull/57/head
amirreza.chegini 1 week ago
parent
commit
db5d895dfb
  1. 3
      .gitignore
  2. 33
      .metadata
  3. 13
      analysis_options.yaml
  4. 4
      compile_svg.zsh
  5. 64
      lib/common_ui/resources/my_assets.dart
  6. 2
      lib/core/routers/hero_dialog_route.dart
  7. 2
      lib/core/routers/my_routes.dart
  8. 4
      lib/core/utils/storage_path.dart
  9. 4
      lib/core/widgets/animations/fade_anim.dart
  10. 4
      lib/core/widgets/animations/fade_anim_delayed.dart
  11. 20
      lib/core/widgets/animations/globe_animation.dart
  12. 2
      lib/core/widgets/animations/rotation_anim.dart
  13. 4
      lib/core/widgets/animations/scale_anim.dart
  14. 4
      lib/core/widgets/animations/ship_anim.dart
  15. 2
      lib/core/widgets/animations/slide_anim.dart
  16. 6
      lib/core/widgets/animations/slide_down_fade.dart
  17. 6
      lib/core/widgets/animations/slide_up_fade.dart
  18. 18
      lib/core/widgets/answer_box/styles/picture_box.dart
  19. 6
      lib/core/widgets/answer_box/styles/text_box.dart
  20. 2
      lib/core/widgets/button/my_blue_button.dart
  21. 2
      lib/core/widgets/button/my_white_button.dart
  22. 2
      lib/core/widgets/button/my_yellow_button.dart
  23. 60
      lib/core/widgets/confetti/my_confetti.dart
  24. 10
      lib/core/widgets/dialog/about_us_dialog.dart
  25. 14
      lib/core/widgets/dialog/exit_dialog.dart
  26. 8
      lib/core/widgets/dialog/hadith_dialog.dart
  27. 12
      lib/core/widgets/dialog/reward_dialog.dart
  28. 6
      lib/core/widgets/error/error_state.dart
  29. 12
      lib/core/widgets/showcase/my_showcase_widget.dart
  30. 4
      lib/core/widgets/video/my_video_player.dart
  31. 4
      lib/features/download/presentation/bloc/download_bloc.dart
  32. 8
      lib/features/download/presentation/ui/download_page.dart
  33. 10
      lib/features/download/presentation/ui/widgets/download_loading_widget.dart
  34. 4
      lib/features/guider/presentation/bloc/guider_bloc.dart
  35. 22
      lib/features/guider/presentation/ui/guider_page.dart
  36. 8
      lib/features/home/presentation/ui/home_page.dart
  37. 2
      lib/features/intro/presentation/bloc/intro_bloc.dart
  38. 4
      lib/features/intro/presentation/ui/intro_page.dart
  39. 6
      lib/features/intro/presentation/ui/screens/intro_1_screen.dart
  40. 4
      lib/features/intro/presentation/ui/screens/intro_2_screen.dart
  41. 4
      lib/features/intro/presentation/ui/screens/intro_3_screen.dart
  42. 4
      lib/features/intro/presentation/ui/screens/intro_4_screen.dart
  43. 4
      lib/features/intro/presentation/ui/screens/intro_5_screen.dart
  44. 12
      lib/features/intro/presentation/ui/widgets/bubble_chat_widget.dart
  45. 4
      lib/features/language/presentation/bloc/language_bloc.dart
  46. 10
      lib/features/language/presentation/ui/language_page.dart
  47. 14
      lib/features/language/presentation/ui/widgets/language_widget.dart
  48. 2
      lib/features/level/data/datasource/level_datasource.dart
  49. 2
      lib/features/level/presentation/bloc/level_bloc.dart
  50. 8
      lib/features/level/presentation/ui/level_page.dart
  51. 2
      lib/features/level/presentation/ui/widgets/bottom_path.dart
  52. 4
      lib/features/level/presentation/ui/widgets/diamond_level.dart
  53. 30
      lib/features/level/presentation/ui/widgets/node_widget.dart
  54. 12
      lib/features/level/presentation/ui/widgets/play_button.dart
  55. 2
      lib/features/question/data/datasource/question_datasource.dart
  56. 8
      lib/features/question/presentation/bloc/question_bloc.dart
  57. 12
      lib/features/question/presentation/ui/question_page.dart
  58. 8
      lib/features/question/presentation/ui/screens/diamond_screen.dart
  59. 22
      lib/features/question/presentation/ui/screens/question_screen.dart
  60. 4
      lib/features/question/presentation/ui/widgets/glassy_button.dart
  61. 18
      lib/features/question/presentation/ui/widgets/question_stepper.dart
  62. 2
      lib/features/question/presentation/ui/widgets/question_title.dart
  63. 2
      lib/features/sample/presentation/ui/sample_page.dart
  64. 2
      lib/features/splash/presentation/bloc/splash_bloc.dart
  65. 6
      lib/features/splash/presentation/ui/splash_page.dart
  66. 6
      lib/init_bindings.dart
  67. 2
      lib/main.dart
  68. 1183
      pubspec.lock
  69. 7
      pubspec.yaml

3
.gitignore

@ -32,6 +32,9 @@ migrate_working_dir/
.pub/ .pub/
/build/ /build/
/coverage/ /coverage/
/pubspec.lock
/.metadata
/assets/svg/*.vec
# Symbolication related # Symbolication related
app.*.symbols app.*.symbols

33
.metadata

@ -1,33 +0,0 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "d693b4b9dbac2acd4477aea4555ca6dcbea44ba2"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: d693b4b9dbac2acd4477aea4555ca6dcbea44ba2
base_revision: d693b4b9dbac2acd4477aea4555ca6dcbea44ba2
- platform: android
create_revision: d693b4b9dbac2acd4477aea4555ca6dcbea44ba2
base_revision: d693b4b9dbac2acd4477aea4555ca6dcbea44ba2
- platform: ios
create_revision: d693b4b9dbac2acd4477aea4555ca6dcbea44ba2
base_revision: d693b4b9dbac2acd4477aea4555ca6dcbea44ba2
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

13
analysis_options.yaml

@ -1 +1,14 @@
include: package:flutter_lints/flutter.yaml include: package:flutter_lints/flutter.yaml
linter:
rules:
prefer_const_constructors: true
prefer_const_declarations: true
prefer_const_constructors_in_immutables: true
prefer_final_fields: true
prefer_final_locals: true
avoid_classes_with_only_static_members: true
avoid_print: true
always_declare_return_types: true
use_key_in_widget_constructors: true
require_trailing_commas: true

4
compile_svg.zsh

@ -0,0 +1,4 @@
for f in assets/svg/*.svg; do
echo "Compiling $f"
fvm dart run vector_graphics_compiler -i "$f" -o "${f}.vec"
done

64
lib/common_ui/resources/my_assets.dart

@ -41,38 +41,38 @@ class MyAssets {
static const String giftBackground = 'assets/images/gift_background.png'; static const String giftBackground = 'assets/images/gift_background.png';
/// SVG /// SVG
static const String closeBtn = 'assets/svg/close_btn.svg';
static const String musicOff = 'assets/svg/music_off.svg';
static const String musicOn = 'assets/svg/music_on.svg';
static const String button = 'assets/svg/button.svg';
static const String buttonTablet = 'assets/svg/button_tablet.svg';
static const String button2 = 'assets/svg/button_2.svg';
static const String button2Tablet = 'assets/svg/button_2_tablet.svg';
static const String button3 = 'assets/svg/button_3.svg';
static const String button3Tablet = 'assets/svg/button_3_tablet.svg';
static const String theme = 'assets/svg/theme.svg';
static const String facebook = 'assets/svg/facebook.svg';
static const String whatsapp = 'assets/svg/whatsapp.svg';
static const String youtube = 'assets/svg/youtube.svg';
static const String instagram = 'assets/svg/instagram.svg';
static const String language = 'assets/svg/language.svg';
static const String newHorizon = 'assets/svg/new_horizon.svg';
static const String home = 'assets/svg/home.svg';
static const String music = 'assets/svg/music.svg';
static const String done = 'assets/svg/done.svg';
static const String correct = 'assets/svg/correct.svg';
static const String wrong = 'assets/svg/wrong.svg';
static const String handPoint = 'assets/svg/hand_point.svg';
static const String location = 'assets/svg/location.svg';
static const String doneRounded = 'assets/svg/done_rounded.svg';
static const String lang = 'assets/svg/lang.svg';
static const String unMusic = 'assets/svg/unmusic.svg';
static const String globe = 'assets/svg/globe.svg';
static const String homeButton = 'assets/svg/home_button.svg';
static const String diamondContainer = 'assets/svg/diamond_container.svg';
static const String iconPlay = 'assets/svg/icon_play.svg';
static const String iconNotif = 'assets/svg/icon_notif.svg';
static const String iconPlayVideo = 'assets/svg/icon_play_video.svg';
static const String closeBtn = 'assets/svg/close_btn.svg.vec';
static const String musicOff = 'assets/svg/music_off.svg.vec';
static const String musicOn = 'assets/svg/music_on.svg.vec';
static const String button = 'assets/svg/button.svg.vec.vec';
static const String buttonTablet = 'assets/svg/button_tablet.svg.vec';
static const String button2 = 'assets/svg/button_2.svg.vec';
static const String button2Tablet = 'assets/svg/button_2_tablet.svg.vec';
static const String button3 = 'assets/svg/button_3.svg.vec';
static const String button3Tablet = 'assets/svg/button_3_tablet.svg.vec';
static const String theme = 'assets/svg/theme.svg.vec';
static const String facebook = 'assets/svg/facebook.svg.vec';
static const String whatsapp = 'assets/svg/whatsapp.svg.vec';
static const String youtube = 'assets/svg/youtube.svg.vec';
static const String instagram = 'assets/svg/instagram.svg.vec';
static const String language = 'assets/svg/language.svg.vec';
static const String newHorizon = 'assets/svg/new_horizon.svg.vec';
static const String home = 'assets/svg/home.svg.vec';
static const String music = 'assets/svg/music.svg.vec';
static const String done = 'assets/svg/done.svg.vec';
static const String correct = 'assets/svg/correct.svg.vec';
static const String wrong = 'assets/svg/wrong.svg.vec';
static const String handPoint = 'assets/svg/hand_point.svg.vec';
static const String location = 'assets/svg/location.svg.vec';
static const String doneRounded = 'assets/svg/done_rounded.svg.vec';
static const String lang = 'assets/svg/lang.svg.vec';
static const String unMusic = 'assets/svg/unmusic.svg.vec';
static const String globe = 'assets/svg/globe.svg.vec';
static const String homeButton = 'assets/svg/home_button.svg.vec';
static const String diamondContainer = 'assets/svg/diamond_container.svg.vec';
static const String iconPlay = 'assets/svg/icon_play.svg.vec';
static const String iconNotif = 'assets/svg/icon_notif.svg.vec';
static const String iconPlayVideo = 'assets/svg/icon_play_video.svg.vec';
static final List<String> images = [ static final List<String> images = [
backgroundHome, backgroundHome,

2
lib/core/routers/hero_dialog_route.dart

@ -25,7 +25,7 @@ class HeroDialogRoute<T> extends PageRoute<T> {
bool get maintainState => false; bool get maintainState => false;
@override @override
Color get barrierColor => Color(0XFF322386).withValues(alpha: 0.3); // Or your desired barrier color
Color get barrierColor => const Color(0XFF322386).withValues(alpha: 0.3); // Or your desired barrier color
@override @override
Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) { Widget buildPage(BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {

2
lib/core/routers/my_routes.dart

@ -95,7 +95,7 @@ GoRouter _appPages() => GoRouter(
name: Routes.languagePage, name: Routes.languagePage,
path: Routes.languagePage, path: Routes.languagePage,
builder: (context, state) => BlocProvider( builder: (context, state) => BlocProvider(
create: (context) => LanguageBloc()..add(InitLanguageEvent()),
create: (context) => LanguageBloc()..add(const InitLanguageEvent()),
child: const LanguagePage(), child: const LanguagePage(),
), ),
), ),

4
lib/core/utils/storage_path.dart

@ -3,6 +3,10 @@ import 'dart:io';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
class StoragePath { class StoragePath {
static const StoragePath _i = StoragePath._internal();
const StoragePath._internal();
factory StoragePath() => _i;
static Directory documentDir = Directory(''); static Directory documentDir = Directory('');
static Future<void> getDocumentDir() async { static Future<void> getDocumentDir() async {

4
lib/core/widgets/animations/fade_anim.dart

@ -19,8 +19,8 @@ class _FadeAnimState extends State<FadeAnim>
super.initState(); super.initState();
_controller = AnimationController( _controller = AnimationController(
vsync: this, vsync: this,
duration: Duration(milliseconds: 500),
reverseDuration: Duration(seconds: 500),
duration: const Duration(milliseconds: 500),
reverseDuration: const Duration(seconds: 500),
); );
_animation = Tween<double>( _animation = Tween<double>(
begin: 0, begin: 0,

4
lib/core/widgets/animations/fade_anim_delayed.dart

@ -24,8 +24,8 @@ class _FadeAnimDelayedState extends State<FadeAnimDelayed>
super.initState(); super.initState();
_controller = AnimationController( _controller = AnimationController(
vsync: this, vsync: this,
duration: Duration(milliseconds: 500),
reverseDuration: Duration(seconds: 500),
duration: const Duration(milliseconds: 500),
reverseDuration: const Duration(seconds: 500),
); );
_animation = Tween<double>( _animation = Tween<double>(
begin: 0, begin: 0,

20
lib/core/widgets/animations/globe_animation.dart

@ -25,8 +25,8 @@ class _GlobeAnimationState extends State<GlobeAnimation>
super.initState(); super.initState();
_controller = AnimationController( _controller = AnimationController(
vsync: this, vsync: this,
duration: Duration(seconds: 1),
reverseDuration: Duration(seconds: 1),
duration: const Duration(seconds: 1),
reverseDuration: const Duration(seconds: 1),
); );
_animation = Tween<double>( _animation = Tween<double>(
begin: 1, begin: 1,
@ -39,15 +39,15 @@ class _GlobeAnimationState extends State<GlobeAnimation>
super.didUpdateWidget(oldWidget); super.didUpdateWidget(oldWidget);
if (widget.state) { if (widget.state) {
_controller.repeat(reverse: true); _controller.repeat(reverse: true);
_timer = Timer.periodic(Duration(seconds: 1), (timer) {
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (_gradient == null) { if (_gradient == null) {
if (!mounted) return; if (!mounted) return;
setState(() { setState(() {
_gradient = RadialGradient( _gradient = RadialGradient(
colors: [ colors: [
Color(0XFFDFCD00),
Color(0XFFDFCD00).withValues(alpha: 0.35),
Color(0XFFDFCD00).withValues(alpha: 0),
const Color(0XFFDFCD00),
const Color(0XFFDFCD00).withValues(alpha: 0.35),
const Color(0XFFDFCD00).withValues(alpha: 0),
], ],
center: Alignment.center, center: Alignment.center,
); );
@ -66,9 +66,9 @@ class _GlobeAnimationState extends State<GlobeAnimation>
setState(() { setState(() {
_gradient = RadialGradient( _gradient = RadialGradient(
colors: [ colors: [
Color(0XFFDFCD00).withValues(alpha: 0),
Color(0XFFDFCD00).withValues(alpha: 0),
Color(0XFFDFCD00).withValues(alpha: 0),
const Color(0XFFDFCD00).withValues(alpha: 0),
const Color(0XFFDFCD00).withValues(alpha: 0),
const Color(0XFFDFCD00).withValues(alpha: 0),
], ],
center: Alignment.center, center: Alignment.center,
); );
@ -94,7 +94,7 @@ class _GlobeAnimationState extends State<GlobeAnimation>
alignment: Alignment.center, alignment: Alignment.center,
child: AnimatedContainer( child: AnimatedContainer(
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 500),
padding: EdgeInsets.all(MySpaces.s0),
padding: const EdgeInsets.all(MySpaces.s0),
decoration: BoxDecoration(gradient: _gradient), decoration: BoxDecoration(gradient: _gradient),
child: child, child: child,
), ),

2
lib/core/widgets/animations/rotation_anim.dart

@ -19,7 +19,7 @@ class _RotationAnimState extends State<RotationAnim>
super.initState(); super.initState();
_controller = AnimationController( _controller = AnimationController(
vsync: this, vsync: this,
duration: Duration(seconds: 20),
duration: const Duration(seconds: 20),
); );
_animation = Tween<double>( _animation = Tween<double>(
begin: 0, begin: 0,

4
lib/core/widgets/animations/scale_anim.dart

@ -20,8 +20,8 @@ class _ScaleAnimState extends State<ScaleAnim>
super.initState(); super.initState();
_controller = AnimationController( _controller = AnimationController(
vsync: this, vsync: this,
duration: Duration(milliseconds: 200),
reverseDuration: Duration(milliseconds: 200),
duration: const Duration(milliseconds: 200),
reverseDuration: const Duration(milliseconds: 200),
); );
_animation = Tween<double>( _animation = Tween<double>(
begin: 0, begin: 0,

4
lib/core/widgets/animations/ship_anim.dart

@ -22,8 +22,8 @@ class _ShipAnimState extends State<ShipAnim>
super.initState(); super.initState();
_controller = AnimationController( _controller = AnimationController(
vsync: this, vsync: this,
duration: Duration(seconds: 15),
reverseDuration: Duration(seconds: 15),
duration: const Duration(seconds: 15),
reverseDuration: const Duration(seconds: 15),
)..repeat(); )..repeat();
} }

2
lib/core/widgets/animations/slide_anim.dart

@ -19,7 +19,7 @@ class SlideAnim extends StatefulWidget {
class _SlideAnimState extends State<SlideAnim> class _SlideAnimState extends State<SlideAnim>
with SingleTickerProviderStateMixin { with SingleTickerProviderStateMixin {
late Animation<Offset> _animation; late Animation<Offset> _animation;
final List<Offset> offsetList = [
final List<Offset> offsetList = const [
Offset(-2, -2), Offset(-2, -2),
Offset(2, -2), Offset(2, -2),
Offset(-2, 2), Offset(-2, 2),

6
lib/core/widgets/animations/slide_down_fade.dart

@ -25,8 +25,8 @@ class _SlideDownFadeState extends State<SlideDownFade>
super.initState(); super.initState();
_controller = AnimationController( _controller = AnimationController(
vsync: this, vsync: this,
duration: Duration(milliseconds: 500),
reverseDuration: Duration(milliseconds: 500),
duration: const Duration(milliseconds: 500),
reverseDuration: const Duration(milliseconds: 500),
); );
_fadeAnim = Tween<double>( _fadeAnim = Tween<double>(
@ -35,7 +35,7 @@ class _SlideDownFadeState extends State<SlideDownFade>
).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn)); ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn));
_slideAnim = Tween<Offset>( _slideAnim = Tween<Offset>(
begin: Offset(0, -0.1),
begin: const Offset(0, -0.1),
end: Offset.zero, end: Offset.zero,
).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn)); ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn));
startAnim(); startAnim();

6
lib/core/widgets/animations/slide_up_fade.dart

@ -25,8 +25,8 @@ class _SlideUpFadeState extends State<SlideUpFade>
super.initState(); super.initState();
_controller = AnimationController( _controller = AnimationController(
vsync: this, vsync: this,
duration: Duration(milliseconds: 500),
reverseDuration: Duration(milliseconds: 500),
duration: const Duration(milliseconds: 500),
reverseDuration: const Duration(milliseconds: 500),
); );
_fadeAnim = Tween<double>( _fadeAnim = Tween<double>(
@ -35,7 +35,7 @@ class _SlideUpFadeState extends State<SlideUpFade>
).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn)); ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn));
_slideAnim = Tween<Offset>( _slideAnim = Tween<Offset>(
begin: Offset(0, 0.1),
begin: const Offset(0, 0.1),
end: Offset.zero, end: Offset.zero,
).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn)); ).animate(CurvedAnimation(parent: _controller, curve: Curves.easeIn));
startAnim(); startAnim();

18
lib/core/widgets/answer_box/styles/picture_box.dart

@ -42,13 +42,13 @@ class AnswerPictureBox extends StatelessWidget {
AspectRatio( AspectRatio(
aspectRatio: 1, aspectRatio: 1,
child: AnimatedSwitcher( child: AnimatedSwitcher(
duration: Duration(milliseconds: 150),
reverseDuration: Duration(milliseconds: 150),
duration: const Duration(milliseconds: 150),
reverseDuration: const Duration(milliseconds: 150),
switchInCurve: Curves.linear, switchInCurve: Curves.linear,
switchOutCurve: Curves.linear, switchOutCurve: Curves.linear,
child: selected && (index != correctAnswer) ? child: selected && (index != correctAnswer) ?
Gif( Gif(
key: Key('1'),
key: const Key('1'),
width: context.widthScreen, width: context.widthScreen,
height: context.heightScreen, height: context.heightScreen,
image: FileImage(File(image)), image: FileImage(File(image)),
@ -59,7 +59,7 @@ class AnswerPictureBox extends StatelessWidget {
colorBlendMode: BlendMode.color, colorBlendMode: BlendMode.color,
) : ) :
Gif( Gif(
key: Key('2'),
key: const Key('2'),
width: context.widthScreen, width: context.widthScreen,
height: context.heightScreen, height: context.heightScreen,
image: FileImage(File(image)), image: FileImage(File(image)),
@ -80,7 +80,7 @@ class AnswerPictureBox extends StatelessWidget {
child: Container( child: Container(
width: MySpaces.s34, width: MySpaces.s34,
alignment: Alignment.center, alignment: Alignment.center,
decoration: BoxDecoration(
decoration: const BoxDecoration(
color: Color(0XFFF2F7FF), color: Color(0XFFF2F7FF),
borderRadius: BorderRadius.vertical( borderRadius: BorderRadius.vertical(
bottom: Radius.circular(10), bottom: Radius.circular(10),
@ -89,7 +89,7 @@ class AnswerPictureBox extends StatelessWidget {
child: Text( child: Text(
'$index', '$index',
style: MYTextStyle.titr1.copyWith( style: MYTextStyle.titr1.copyWith(
color: Color(0XFF9B85D8),
color: const Color(0XFF9B85D8),
), ),
), ),
), ),
@ -114,7 +114,7 @@ class _CustomShapePainter extends CustomPainter {
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
final Paint strokePaint = Paint() final Paint strokePaint = Paint()
..color = Color(0XFFF2F7FF)
..color = const Color(0XFFF2F7FF)
..style = PaintingStyle.stroke ..style = PaintingStyle.stroke
..strokeWidth = 4; ..strokeWidth = 4;
@ -132,8 +132,8 @@ class _CustomShapeClipper extends CustomClipper<Path> {
@override @override
Path getClip(Size size) { Path getClip(Size size) {
// Original SVG dimensions to calculate the scaling factors. // Original SVG dimensions to calculate the scaling factors.
final double originalWidth = 193.0;
final double originalHeight = 189.0;
const double originalWidth = 193.0;
const double originalHeight = 189.0;
// Scaling factors to make the path responsive. // Scaling factors to make the path responsive.
final double scaleX = size.width / originalWidth; final double scaleX = size.width / originalWidth;

6
lib/core/widgets/answer_box/styles/text_box.dart

@ -13,9 +13,9 @@ class AnswerTextBox extends StatelessWidget {
clipper: WavyBannerClipper(), clipper: WavyBannerClipper(),
child: Container( child: Container(
height: 90, height: 90,
padding: EdgeInsets.symmetric(horizontal: MySpaces.s10),
padding: const EdgeInsets.symmetric(horizontal: MySpaces.s10),
alignment: Alignment.center, alignment: Alignment.center,
decoration: BoxDecoration(
decoration: const BoxDecoration(
gradient: LinearGradient( gradient: LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
@ -29,7 +29,7 @@ class AnswerTextBox extends StatelessWidget {
text, text,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: MYTextStyle.matn2.copyWith( style: MYTextStyle.matn2.copyWith(
color: Color(0XFF322386),
color: const Color(0XFF322386),
height: 1.2, height: 1.2,
), ),
maxLines: 5, maxLines: 5,

2
lib/core/widgets/button/my_blue_button.dart

@ -41,7 +41,7 @@ class MyBlueButton extends StatelessWidget {
child: Text( child: Text(
title ?? '', title ?? '',
style: MYTextStyle.button1.copyWith( style: MYTextStyle.button1.copyWith(
color: Color(0XFF1D6EFF),
color: const Color(0XFF1D6EFF),
), ),
), ),
), ),

2
lib/core/widgets/button/my_white_button.dart

@ -40,7 +40,7 @@ class MyWhiteButton extends StatelessWidget {
child: Text( child: Text(
title ?? '', title ?? '',
style: MYTextStyle.button1.copyWith( style: MYTextStyle.button1.copyWith(
color: Color(0XFFD93D16),
color: const Color(0XFFD93D16),
fontSize: setSize(context: context, tablet: 60), fontSize: setSize(context: context, tablet: 60),
), ),
), ),

2
lib/core/widgets/button/my_yellow_button.dart

@ -41,7 +41,7 @@ class MyYellowButton extends StatelessWidget {
child: Text( child: Text(
title ?? '', title ?? '',
style: MYTextStyle.button1.copyWith( style: MYTextStyle.button1.copyWith(
color: Color(0XFFD93D16),
color: const Color(0XFFD93D16),
fontSize: setSize(context: context, tablet: 60), fontSize: setSize(context: context, tablet: 60),
), ),
), ),

60
lib/core/widgets/confetti/my_confetti.dart

@ -1,60 +0,0 @@
import 'dart:math';
import 'package:confetti/confetti.dart';
import 'package:flutter/material.dart';
class MyConfetti extends StatelessWidget {
const MyConfetti({super.key, required this.controller});
final ConfettiController controller;
@override
Widget build(BuildContext context) {
return ConfettiWidget(
confettiController: controller,
shouldLoop: false,
blastDirectionality: BlastDirectionality.explosive,
blastDirection: pi / 2,
gravity: 1,
emissionFrequency: 0.5,
numberOfParticles: 15,
particleDrag: 0.1,
colors: const [
Colors.red,
Colors.orange,
Colors.yellow,
Colors.green,
Colors.blue,
Colors.purple,
Colors.pink,
Colors.cyan,
],
createParticlePath: (size) {
double degToRad(double deg) => deg * (pi / 180.0);
const numberOfPoints = 5;
final halfWidth = size.width / 2;
final externalRadius = halfWidth;
final internalRadius = halfWidth / 2.5;
final degreesPerStep = degToRad(360 / numberOfPoints);
final halfDegreesPerStep = degreesPerStep / 2;
final path = Path();
final fullAngle = degToRad(360);
path.moveTo(size.width, halfWidth);
for (double step = 0; step < fullAngle; step += degreesPerStep) {
path.lineTo(
halfWidth + externalRadius * cos(step),
halfWidth + externalRadius * sin(step),
);
path.lineTo(
halfWidth + internalRadius * cos(step + halfDegreesPerStep),
halfWidth + internalRadius * sin(step + halfDegreesPerStep),
);
}
path.close();
return path;
},
);
}
}

10
lib/core/widgets/dialog/about_us_dialog.dart

@ -15,7 +15,7 @@ import 'package:hadi_hoda_flutter/core/widgets/inkwell/my_inkwell.dart';
Future<void> showAboutUsDialog({required BuildContext context}) async { Future<void> showAboutUsDialog({required BuildContext context}) async {
await showDialog( await showDialog(
context: context, context: context,
builder: (context) => AboutUsDialog(),
builder: (context) => const AboutUsDialog(),
barrierColor: MyColors.purple.withValues(alpha: 0.82), barrierColor: MyColors.purple.withValues(alpha: 0.82),
useSafeArea: false, useSafeArea: false,
); );
@ -49,7 +49,7 @@ class AboutUsDialog extends StatelessWidget {
Text( Text(
context.translate.about_us, context.translate.about_us,
style: MYTextStyle.titr3.copyWith( style: MYTextStyle.titr3.copyWith(
color: Color(0XFF322386),
color: const Color(0XFF322386),
), ),
), ),
Expanded( Expanded(
@ -58,14 +58,14 @@ class AboutUsDialog extends StatelessWidget {
minFontSize: 12, minFontSize: 12,
maxFontSize: 20, maxFontSize: 20,
style: MYTextStyle.matn1.copyWith( style: MYTextStyle.matn1.copyWith(
color: Color(0XFF494178),
color: const Color(0XFF494178),
), ),
), ),
), ),
MyImage(
const MyImage(
image: MyAssets.newHorizon, image: MyAssets.newHorizon,
), ),
MyImage(
const MyImage(
image: MyAssets.khadijeLogo, image: MyAssets.khadijeLogo,
size: 100, size: 100,
), ),

14
lib/core/widgets/dialog/exit_dialog.dart

@ -14,7 +14,7 @@ import 'package:hadi_hoda_flutter/core/widgets/dialog/styles/dialog_button.dart'
Future<void> showExitDialog({required BuildContext context}) async { Future<void> showExitDialog({required BuildContext context}) async {
await showDialog( await showDialog(
context: context, context: context,
builder: (context) => ExitDialog(),
builder: (context) => const ExitDialog(),
barrierColor: MyColors.purple.withValues(alpha: 0.82), barrierColor: MyColors.purple.withValues(alpha: 0.82),
useSafeArea: false, useSafeArea: false,
); );
@ -41,11 +41,11 @@ class ExitDialog extends StatelessWidget {
children: [ children: [
Text( Text(
context.translate.want_to_exit, context.translate.want_to_exit,
style: MYTextStyle.titr0.copyWith(color: Color(0XFF322386)),
style: MYTextStyle.titr0.copyWith(color: const Color(0XFF322386)),
), ),
Text( Text(
context.translate.exit_dialog_desc, context.translate.exit_dialog_desc,
style: MYTextStyle.titr3.copyWith(color: Color(0XFF6272A9)),
style: MYTextStyle.titr3.copyWith(color: const Color(0XFF6272A9)),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
Row( Row(
@ -57,12 +57,12 @@ class ExitDialog extends StatelessWidget {
context.pop(); context.pop();
}, },
height: 72, height: 72,
color: Color(0XFFC0BDD3),
color: const Color(0XFFC0BDD3),
child: Text( child: Text(
context.translate.cancel, context.translate.cancel,
style: MYTextStyle.button2.copyWith( style: MYTextStyle.button2.copyWith(
shadows: [ shadows: [
BoxShadow(
const BoxShadow(
color: Color(0XFF9895AE), color: Color(0XFF9895AE),
offset: Offset(0, 3.32), offset: Offset(0, 3.32),
), ),
@ -77,12 +77,12 @@ class ExitDialog extends StatelessWidget {
SystemNavigator.pop(); SystemNavigator.pop();
}, },
height: 72, height: 72,
color: Color(0XFFD42427),
color: const Color(0XFFD42427),
child: Text( child: Text(
context.translate.exit, context.translate.exit,
style: MYTextStyle.button2.copyWith( style: MYTextStyle.button2.copyWith(
shadows: [ shadows: [
BoxShadow(
const BoxShadow(
color: Color(0XFFC82020), color: Color(0XFFC82020),
offset: Offset(0, 3.32), offset: Offset(0, 3.32),
), ),

8
lib/core/widgets/dialog/hadith_dialog.dart

@ -53,7 +53,7 @@ class HadithDialog extends StatelessWidget {
if(hadith.isNotEmpty){ if(hadith.isNotEmpty){
return ListView.separated( return ListView.separated(
itemCount: hadith.length, itemCount: hadith.length,
separatorBuilder: (context, index) => Divider(
separatorBuilder: (context, index) => const Divider(
height: 40, height: 40,
thickness: 1, thickness: 1,
endIndent: MySpaces.s20, endIndent: MySpaces.s20,
@ -64,13 +64,13 @@ class HadithDialog extends StatelessWidget {
TextSpan( TextSpan(
text: '${hadith[index].narratorName ?? ''}:\n', text: '${hadith[index].narratorName ?? ''}:\n',
style: MYTextStyle.titr1.copyWith( style: MYTextStyle.titr1.copyWith(
color: Color(0XFF494178),
color: const Color(0XFF494178),
), ),
children: [ children: [
TextSpan( TextSpan(
text: hadith[index].hadithText, text: hadith[index].hadithText,
style: MYTextStyle.matn1.copyWith( style: MYTextStyle.matn1.copyWith(
color: Color(0XFF494178),
color: const Color(0XFF494178),
), ),
), ),
], ],
@ -82,7 +82,7 @@ class HadithDialog extends StatelessWidget {
child: Text( child: Text(
context.translate.no_hadith, context.translate.no_hadith,
style: MYTextStyle.titr4.copyWith( style: MYTextStyle.titr4.copyWith(
color: Color(0XFF494178),
color: const Color(0XFF494178),
), ),
), ),
); );

12
lib/core/widgets/dialog/reward_dialog.dart

@ -62,14 +62,14 @@ class RewardDialog extends StatelessWidget {
Text( Text(
context.translate.reward, context.translate.reward,
style: MYTextStyle.titr0.copyWith( style: MYTextStyle.titr0.copyWith(
color: Color(0XFF322386),
color: const Color(0XFF322386),
fontSize: 22, fontSize: 22,
), ),
), ),
Text( Text(
prize.title ?? '', prize.title ?? '',
style: MYTextStyle.titr0.copyWith( style: MYTextStyle.titr0.copyWith(
color: Color(0XFF322386),
color: const Color(0XFF322386),
fontSize: 22, fontSize: 22,
), ),
), ),
@ -91,7 +91,7 @@ class RewardDialog extends StatelessWidget {
prize.imageURL ?? '', prize.imageURL ?? '',
fit: BoxFit.cover, fit: BoxFit.cover,
), ),
MyImage(
const MyImage(
image: MyAssets.iconPlayVideo, image: MyAssets.iconPlayVideo,
), ),
], ],
@ -129,7 +129,7 @@ class _CustomShapePainter extends CustomPainter {
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
final Paint strokePaint = Paint() final Paint strokePaint = Paint()
..color = Color(0XFFF2F7FF)
..color = const Color(0XFFF2F7FF)
..style = PaintingStyle.stroke ..style = PaintingStyle.stroke
..strokeWidth = 4; ..strokeWidth = 4;
@ -147,8 +147,8 @@ class _CustomShapeClipper extends CustomClipper<Path> {
@override @override
Path getClip(Size size) { Path getClip(Size size) {
// Original SVG dimensions to calculate the scaling factors. // Original SVG dimensions to calculate the scaling factors.
final double originalWidth = 193.0;
final double originalHeight = 189.0;
const double originalWidth = 193.0;
const double originalHeight = 189.0;
// Scaling factors to make the path responsive. // Scaling factors to make the path responsive.
final double scaleX = size.width / originalWidth; final double scaleX = size.width / originalWidth;

6
lib/core/widgets/error/error_state.dart

@ -17,19 +17,19 @@ class ErrorState extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Column( return Column(
children: [ children: [
Spacer(),
const Spacer(),
Text( Text(
context.translate.lost_connection, context.translate.lost_connection,
style: MYTextStyle.button1, style: MYTextStyle.button1,
), ),
MyImage(image: MyAssets.error),
const MyImage(image: MyAssets.error),
MySpaces.s40.gapHeight, MySpaces.s40.gapHeight,
Text( Text(
context.translate.connected_to_internet, context.translate.connected_to_internet,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: MYTextStyle.matn3, style: MYTextStyle.matn3,
), ),
Spacer(),
const Spacer(),
MyBlueButton( MyBlueButton(
title: context.translate.retry, title: context.translate.retry,
onTap: onTap, onTap: onTap,

12
lib/core/widgets/showcase/my_showcase_widget.dart

@ -20,7 +20,7 @@ enum ShowcaseTooltipType {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
spacing: MySpaces.s4, spacing: MySpaces.s4,
children: [ children: [
MyImage(
const MyImage(
image: MyAssets.handPoint, image: MyAssets.handPoint,
size: 50, size: 50,
), ),
@ -44,7 +44,7 @@ enum ShowcaseTooltipType {
Transform.flip( Transform.flip(
flipY: true, flipY: true,
flipX: true, flipX: true,
child: MyImage(
child: const MyImage(
image: MyAssets.handPoint, image: MyAssets.handPoint,
size: 50, size: 50,
), ),
@ -63,7 +63,7 @@ enum ShowcaseTooltipType {
), ),
Transform.rotate( Transform.rotate(
angle: 2.5, angle: 2.5,
child: MyImage(
child: const MyImage(
image: MyAssets.handPoint, image: MyAssets.handPoint,
size: 50, size: 50,
), ),
@ -98,8 +98,8 @@ class MyShowcaseWidget extends StatelessWidget {
return Showcase( return Showcase(
key: globalKey ?? GlobalKey(), key: globalKey ?? GlobalKey(),
disableBarrierInteraction: false, disableBarrierInteraction: false,
targetShapeBorder: CircleBorder(),
overlayColor: Color(0XFF0F0041),
targetShapeBorder: const CircleBorder(),
overlayColor: const Color(0XFF0F0041),
overlayOpacity: 0.82, overlayOpacity: 0.82,
/// ToolTip /// ToolTip
tooltipPadding: EdgeInsets.zero, tooltipPadding: EdgeInsets.zero,
@ -108,7 +108,7 @@ class MyShowcaseWidget extends StatelessWidget {
targetTooltipGap: 0, targetTooltipGap: 0,
toolTipSlideEndDistance: MySpaces.s6, toolTipSlideEndDistance: MySpaces.s6,
toolTipMargin: 0, toolTipMargin: 0,
tooltipActionConfig: TooltipActionConfig(
tooltipActionConfig: const TooltipActionConfig(
gapBetweenContentAndAction: 0, gapBetweenContentAndAction: 0,
), ),
tooltipActions: [ tooltipActions: [

4
lib/core/widgets/video/my_video_player.dart

@ -30,7 +30,7 @@ class _MyVideoPlayerState extends State<MyVideoPlayer> {
_mainAudioService.stop(); _mainAudioService.stop();
_effectAudioService.stop(); _effectAudioService.stop();
_controller = PodPlayerController( _controller = PodPlayerController(
podPlayerConfig: PodPlayerConfig(
podPlayerConfig: const PodPlayerConfig(
autoPlay: false, autoPlay: false,
isLooping: false, isLooping: false,
wakelockEnabled: true, wakelockEnabled: true,
@ -62,7 +62,7 @@ class _MyVideoPlayerState extends State<MyVideoPlayer> {
matchVideoAspectRatioToFrame: true, matchVideoAspectRatioToFrame: true,
matchFrameAspectRatioToVideo: true, matchFrameAspectRatioToVideo: true,
videoAspectRatio: _controller.videoPlayerValue?.aspectRatio ?? 16 / 9, videoAspectRatio: _controller.videoPlayerValue?.aspectRatio ?? 16 / 9,
podProgressBarConfig: PodProgressBarConfig(),
podProgressBarConfig: const PodProgressBarConfig(),
onToggleFullScreen: (isFullScreen) async { onToggleFullScreen: (isFullScreen) async {
if (isFullScreen) { if (isFullScreen) {
await MyDevice.setAllOrientations(); await MyDevice.setAllOrientations();

4
lib/features/download/presentation/bloc/download_bloc.dart

@ -40,7 +40,7 @@ class DownloadBloc extends Bloc<DownloadEvent, DownloadState> {
final LoadingStreamUseCase _loadingStreamUseCase; final LoadingStreamUseCase _loadingStreamUseCase;
/// ------------Variables------------ /// ------------Variables------------
Stream<DownloadEntity> loadingStream = Stream.empty();
Stream<DownloadEntity> loadingStream = const Stream.empty();
/// ------------Controllers------------ /// ------------Controllers------------
@ -51,7 +51,7 @@ class DownloadBloc extends Bloc<DownloadEvent, DownloadState> {
GetImagesEvent event, GetImagesEvent event,
Emitter<DownloadState> emit, Emitter<DownloadState> emit,
) async { ) async {
emit(state.copyWith(getFilesStatus: BaseInit()));
emit(state.copyWith(getFilesStatus: const BaseInit()));
await _getImagesUseCase(NoParams()).then((value) { await _getImagesUseCase(NoParams()).then((value) {
value.fold( value.fold(
(data) { (data) {

8
lib/features/download/presentation/ui/download_page.dart

@ -25,7 +25,7 @@ class DownloadPage extends StatelessWidget {
height: context.heightScreen, height: context.heightScreen,
width: context.widthScreen, width: context.widthScreen,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient(
gradient: const LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [ colors: [
@ -34,7 +34,7 @@ class DownloadPage extends StatelessWidget {
], ],
), ),
image: DecorationImage( image: DecorationImage(
image: AssetImage(MyAssets.pattern),
image: const AssetImage(MyAssets.pattern),
scale: 3, scale: 3,
repeat: ImageRepeat.repeat, repeat: ImageRepeat.repeat,
colorFilter: ColorFilter.mode( colorFilter: ColorFilter.mode(
@ -74,7 +74,7 @@ class DownloadPage extends StatelessWidget {
} }
Widget _image() { Widget _image() {
return Stack(
return const Stack(
children: [ children: [
MyImage( MyImage(
image: MyAssets.hadiHoda, image: MyAssets.hadiHoda,
@ -101,7 +101,7 @@ class DownloadPage extends StatelessWidget {
style: MYTextStyle.titr0, style: MYTextStyle.titr0,
), ),
StreamBuilder<DownloadEntity>( StreamBuilder<DownloadEntity>(
initialData: DownloadEntity(),
initialData: const DownloadEntity(),
stream: context.read<DownloadBloc>().loadingStream, stream: context.read<DownloadBloc>().loadingStream,
builder: (context, snapshot) => Text( builder: (context, snapshot) => Text(
'${context.translate.downloading_data} (${snapshot.data?.count.toMB ?? 0.0}mb / ${snapshot.data?.total.toMB ?? 0.0}mb)', '${context.translate.downloading_data} (${snapshot.data?.count.toMB ?? 0.0}mb / ${snapshot.data?.total.toMB ?? 0.0}mb)',

10
lib/features/download/presentation/ui/widgets/download_loading_widget.dart

@ -19,7 +19,7 @@ class DownloadLoadingWidget extends StatelessWidget {
child: Container( child: Container(
width: 300, width: 300,
height: 60, height: 60,
padding: EdgeInsets.symmetric(
padding: const EdgeInsets.symmetric(
vertical: MySpaces.s4, vertical: MySpaces.s4,
horizontal: MySpaces.s2, horizontal: MySpaces.s2,
), ),
@ -34,7 +34,7 @@ class DownloadLoadingWidget extends StatelessWidget {
), ),
), ),
child: StreamBuilder<DownloadEntity>( child: StreamBuilder<DownloadEntity>(
initialData: DownloadEntity(),
initialData: const DownloadEntity(),
stream: loadingStream, stream: loadingStream,
builder: (context, snapshot) { builder: (context, snapshot) {
return Row( return Row(
@ -49,12 +49,12 @@ class DownloadLoadingWidget extends StatelessWidget {
end: 260 - ((snapshot.data?.percent ?? 0) * 260 / 100), end: 260 - ((snapshot.data?.percent ?? 0) * 260 / 100),
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Color(0xFF1F59BD).withValues(alpha: 0.25),
color: const Color(0xFF1F59BD).withValues(alpha: 0.25),
), ),
child: ClipPath( child: ClipPath(
clipper: BubbleClip(), clipper: BubbleClip(),
child: Container( child: Container(
decoration: BoxDecoration(
decoration: const BoxDecoration(
gradient: RadialGradient( gradient: RadialGradient(
radius: 2, radius: 2,
colors: [ colors: [
@ -74,7 +74,7 @@ class DownloadLoadingWidget extends StatelessWidget {
child: Text( child: Text(
'${snapshot.data?.percent?.toInt() ?? 0}%', '${snapshot.data?.percent?.toInt() ?? 0}%',
style: MYTextStyle.titr4.copyWith( style: MYTextStyle.titr4.copyWith(
color: Color(0XFF6E83A8),
color: const Color(0XFF6E83A8),
), ),
), ),
), ),

4
lib/features/guider/presentation/bloc/guider_bloc.dart

@ -115,12 +115,12 @@ class GuiderBloc extends Bloc<GuiderEvent, GuiderState> {
); );
emit( emit(
state.copyWith( state.copyWith(
getQuestionStatus: BaseComplete(''),
getQuestionStatus: const BaseComplete(''),
levelEntity: level, levelEntity: level,
currentQuestion: data.questions?.first, currentQuestion: data.questions?.first,
), ),
); );
await Future.delayed(Duration(milliseconds: 300), () {
await Future.delayed(const Duration(milliseconds: 300), () {
animationController.forward().then((value) { animationController.forward().then((value) {
startShowcase(); startShowcase();
}); });

22
lib/features/guider/presentation/ui/guider_page.dart

@ -40,8 +40,8 @@ class _GuiderPageState extends State<GuiderPage> with TickerProviderStateMixin {
.read<GuiderBloc>() .read<GuiderBloc>()
.animationController = AnimationController( .animationController = AnimationController(
vsync: this, vsync: this,
duration: Duration(milliseconds: 500),
reverseDuration: Duration(milliseconds: 500),
duration: const Duration(milliseconds: 500),
reverseDuration: const Duration(milliseconds: 500),
); );
} }
@ -64,13 +64,13 @@ class _GuiderPageState extends State<GuiderPage> with TickerProviderStateMixin {
0, 0,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient(
gradient: const LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [Color(0XFF6930DA), Color(0XFF263AA1)], colors: [Color(0XFF6930DA), Color(0XFF263AA1)],
), ),
image: DecorationImage( image: DecorationImage(
image: AssetImage(MyAssets.pattern),
image: const AssetImage(MyAssets.pattern),
scale: 3, scale: 3,
repeat: ImageRepeat.repeat, repeat: ImageRepeat.repeat,
colorFilter: ColorFilter.mode( colorFilter: ColorFilter.mode(
@ -85,7 +85,7 @@ class _GuiderPageState extends State<GuiderPage> with TickerProviderStateMixin {
android: MySpaces.s20, android: MySpaces.s20,
iOS: 50, iOS: 50,
)?.gapHeight ?? )?.gapHeight ??
SizedBox.shrink(),
const SizedBox.shrink(),
_topButtons(context), _topButtons(context),
MySpaces.s10.gapHeight, MySpaces.s10.gapHeight,
Expanded( Expanded(
@ -100,7 +100,7 @@ class _GuiderPageState extends State<GuiderPage> with TickerProviderStateMixin {
), ),
), ),
setPlatform<double>(android: MySpaces.s20)?.gapHeight ?? setPlatform<double>(android: MySpaces.s20)?.gapHeight ??
SizedBox.shrink(),
const SizedBox.shrink(),
], ],
), ),
), ),
@ -141,7 +141,7 @@ class _GuiderPageState extends State<GuiderPage> with TickerProviderStateMixin {
.read<GuiderBloc>() .read<GuiderBloc>()
.showCaseKey['stepper_key']!, .showCaseKey['stepper_key']!,
description: context.translate.showcase_stepper, description: context.translate.showcase_stepper,
child: QuestionStepper(length: 4, currentStep: 1),
child: const QuestionStepper(length: 4, currentStep: 1),
), ),
); );
} }
@ -157,7 +157,7 @@ class _GuiderPageState extends State<GuiderPage> with TickerProviderStateMixin {
style: MYTextStyle.titr1.copyWith( style: MYTextStyle.titr1.copyWith(
shadows: [ shadows: [
BoxShadow( BoxShadow(
offset: Offset(0, 2),
offset: const Offset(0, 2),
color: MyColors.black.withValues(alpha: 0.25), color: MyColors.black.withValues(alpha: 0.25),
), ),
], ],
@ -172,13 +172,13 @@ class _GuiderPageState extends State<GuiderPage> with TickerProviderStateMixin {
builder: (context, state) => builder: (context, state) =>
GridView.builder( GridView.builder(
itemCount: state.currentQuestion?.answers?.length ?? 0, itemCount: state.currentQuestion?.answers?.length ?? 0,
physics: NeverScrollableScrollPhysics(),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
clipBehavior: Clip.none, clipBehavior: Clip.none,
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: setSize(context: context, tablet: 70) ?? 0, horizontal: setSize(context: context, tablet: 70) ?? 0,
), ),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisCount: 2,
crossAxisSpacing: MySpaces.s20, crossAxisSpacing: MySpaces.s20,
mainAxisSpacing: 20, mainAxisSpacing: 20,
@ -186,7 +186,7 @@ class _GuiderPageState extends State<GuiderPage> with TickerProviderStateMixin {
), ),
itemBuilder: (context, index) => itemBuilder: (context, index) =>
state.currentQuestion?.answers?[index].imageId == null state.currentQuestion?.answers?[index].imageId == null
? SizedBox.shrink()
? const SizedBox.shrink()
: SlideAnim( : SlideAnim(
controller: context.read<GuiderBloc>().animationController, controller: context.read<GuiderBloc>().animationController,
index: index, index: index,

8
lib/features/home/presentation/ui/home_page.dart

@ -21,7 +21,7 @@ class HomePage extends StatelessWidget {
return Scaffold( return Scaffold(
body: MyPopScope( body: MyPopScope(
child: DecoratedBox( child: DecoratedBox(
decoration: BoxDecoration(
decoration: const BoxDecoration(
image: DecorationImage( image: DecorationImage(
image: AssetImage(MyAssets.backgroundHome), image: AssetImage(MyAssets.backgroundHome),
fit: BoxFit.cover, fit: BoxFit.cover,
@ -47,7 +47,7 @@ class HomePage extends StatelessWidget {
top: setPlatform(android: MySpaces.s36, iOS: 50), top: setPlatform(android: MySpaces.s36, iOS: 50),
end: MySpaces.s16, end: MySpaces.s16,
child: SlideDownFade( child: SlideDownFade(
delay: Duration(milliseconds: 200),
delay: const Duration(milliseconds: 200),
child: StreamBuilder<double>( child: StreamBuilder<double>(
initialData: 1, initialData: 1,
stream: context.read<HomeBloc>().volumeStream, stream: context.read<HomeBloc>().volumeStream,
@ -67,7 +67,7 @@ class HomePage extends StatelessWidget {
Positioned _image(BuildContext context) { Positioned _image(BuildContext context) {
return Positioned( return Positioned(
top: setSize(context: context, mobile: 0.1.h, tablet: 0.15.h), top: setSize(context: context, mobile: 0.1.h, tablet: 0.15.h),
child: Stack(
child: const Stack(
children: [ children: [
MyImage( MyImage(
image: MyAssets.hadiHoda, image: MyAssets.hadiHoda,
@ -91,7 +91,7 @@ class HomePage extends StatelessWidget {
right: MySpaces.s16, right: MySpaces.s16,
child: SafeArea( child: SafeArea(
child: SlideUpFade( child: SlideUpFade(
delay: Duration(milliseconds: 200),
delay: const Duration(milliseconds: 200),
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,

2
lib/features/intro/presentation/bloc/intro_bloc.dart

@ -37,7 +37,7 @@ class IntroBloc extends Bloc<IntroEvent, IntroState> {
/// ------------UseCases------------ /// ------------UseCases------------
/// ------------Variables------------ /// ------------Variables------------
final List<Widget> intros = [
final List<Widget> intros = const [
Intro1Screen(key: Key('0')), Intro1Screen(key: Key('0')),
Intro2Screen(key: Key('1')), Intro2Screen(key: Key('1')),
Intro3Screen(key: Key('2')), Intro3Screen(key: Key('2')),

4
lib/features/intro/presentation/ui/intro_page.dart

@ -31,8 +31,8 @@ class IntroPage extends StatelessWidget {
BlocBuilder<IntroBloc, IntroState> _mainScreen() { BlocBuilder<IntroBloc, IntroState> _mainScreen() {
return BlocBuilder<IntroBloc, IntroState>( return BlocBuilder<IntroBloc, IntroState>(
builder: (context, state) => AnimatedSwitcher( builder: (context, state) => AnimatedSwitcher(
duration: Duration(milliseconds: 200),
reverseDuration: Duration(milliseconds: 200),
duration: const Duration(milliseconds: 200),
reverseDuration: const Duration(milliseconds: 200),
switchInCurve: Curves.linear, switchInCurve: Curves.linear,
switchOutCurve: Curves.linear, switchOutCurve: Curves.linear,
child: context.read<IntroBloc>().intros[state.currentIntro], child: context.read<IntroBloc>().intros[state.currentIntro],

6
lib/features/intro/presentation/ui/screens/intro_1_screen.dart

@ -12,12 +12,12 @@ class Intro1Screen extends StatelessWidget {
return SizedBox.expand( return SizedBox.expand(
child: PodVideoPlayer( child: PodVideoPlayer(
controller: context.read<IntroBloc>().podController1, controller: context.read<IntroBloc>().podController1,
overlayBuilder: (options) => SizedBox.shrink(),
overlayBuilder: (options) => const SizedBox.shrink(),
alwaysShowProgressBar: false, alwaysShowProgressBar: false,
videoAspectRatio: context.widthScreen / context.heightScreen, videoAspectRatio: context.widthScreen / context.heightScreen,
frameAspectRatio: context.widthScreen / context.heightScreen, frameAspectRatio: context.widthScreen / context.heightScreen,
backgroundColor: Color(0XFF00154C),
onLoading: (context) => SizedBox.shrink(),
backgroundColor: const Color(0XFF00154C),
onLoading: (context) => const SizedBox.shrink(),
), ),
); );
} }

4
lib/features/intro/presentation/ui/screens/intro_2_screen.dart

@ -13,12 +13,12 @@ class Intro2Screen extends StatelessWidget {
return SizedBox.expand( return SizedBox.expand(
child: PodVideoPlayer( child: PodVideoPlayer(
controller: context.read<IntroBloc>().podController2, controller: context.read<IntroBloc>().podController2,
overlayBuilder: (options) => SizedBox.shrink(),
overlayBuilder: (options) => const SizedBox.shrink(),
alwaysShowProgressBar: false, alwaysShowProgressBar: false,
videoAspectRatio: context.widthScreen / context.heightScreen, videoAspectRatio: context.widthScreen / context.heightScreen,
frameAspectRatio: context.widthScreen / context.heightScreen, frameAspectRatio: context.widthScreen / context.heightScreen,
backgroundColor: MyColors.transparent, backgroundColor: MyColors.transparent,
onLoading: (context) => SizedBox.shrink(),
onLoading: (context) => const SizedBox.shrink(),
), ),
); );
} }

4
lib/features/intro/presentation/ui/screens/intro_3_screen.dart

@ -13,12 +13,12 @@ class Intro3Screen extends StatelessWidget {
return SizedBox.expand( return SizedBox.expand(
child: PodVideoPlayer( child: PodVideoPlayer(
controller: context.read<IntroBloc>().podController3, controller: context.read<IntroBloc>().podController3,
overlayBuilder: (options) => SizedBox.shrink(),
overlayBuilder: (options) => const SizedBox.shrink(),
alwaysShowProgressBar: false, alwaysShowProgressBar: false,
videoAspectRatio: context.widthScreen / context.heightScreen, videoAspectRatio: context.widthScreen / context.heightScreen,
frameAspectRatio: context.widthScreen / context.heightScreen, frameAspectRatio: context.widthScreen / context.heightScreen,
backgroundColor: MyColors.transparent, backgroundColor: MyColors.transparent,
onLoading: (context) => SizedBox.shrink(),
onLoading: (context) => const SizedBox.shrink(),
), ),
); );
} }

4
lib/features/intro/presentation/ui/screens/intro_4_screen.dart

@ -13,12 +13,12 @@ class Intro4Screen extends StatelessWidget {
return SizedBox.expand( return SizedBox.expand(
child: PodVideoPlayer( child: PodVideoPlayer(
controller: context.read<IntroBloc>().podController4, controller: context.read<IntroBloc>().podController4,
overlayBuilder: (options) => SizedBox.shrink(),
overlayBuilder: (options) => const SizedBox.shrink(),
alwaysShowProgressBar: false, alwaysShowProgressBar: false,
videoAspectRatio: context.widthScreen / context.heightScreen, videoAspectRatio: context.widthScreen / context.heightScreen,
frameAspectRatio: context.widthScreen / context.heightScreen, frameAspectRatio: context.widthScreen / context.heightScreen,
backgroundColor: MyColors.transparent, backgroundColor: MyColors.transparent,
onLoading: (context) => SizedBox.shrink(),
onLoading: (context) => const SizedBox.shrink(),
), ),
); );
} }

4
lib/features/intro/presentation/ui/screens/intro_5_screen.dart

@ -13,12 +13,12 @@ class Intro5Screen extends StatelessWidget {
return SizedBox.expand( return SizedBox.expand(
child: PodVideoPlayer( child: PodVideoPlayer(
controller: context.read<IntroBloc>().podController5, controller: context.read<IntroBloc>().podController5,
overlayBuilder: (options) => SizedBox.shrink(),
overlayBuilder: (options) => const SizedBox.shrink(),
alwaysShowProgressBar: false, alwaysShowProgressBar: false,
videoAspectRatio: context.widthScreen / context.heightScreen, videoAspectRatio: context.widthScreen / context.heightScreen,
frameAspectRatio: context.widthScreen / context.heightScreen, frameAspectRatio: context.widthScreen / context.heightScreen,
backgroundColor: MyColors.transparent, backgroundColor: MyColors.transparent,
onLoading: (context) => SizedBox.shrink(),
onLoading: (context) => const SizedBox.shrink(),
), ),
); );
} }

12
lib/features/intro/presentation/ui/widgets/bubble_chat_widget.dart

@ -21,15 +21,15 @@ class BubbleChatWidget extends StatelessWidget {
clipper: _ShapeClipper(flip: flip), clipper: _ShapeClipper(flip: flip),
child: Container( child: Container(
width: width, width: width,
padding: EdgeInsets.only(
padding: const EdgeInsets.only(
left: MySpaces.s18, left: MySpaces.s18,
right: MySpaces.s18, right: MySpaces.s18,
top: MySpaces.s16, top: MySpaces.s16,
bottom: MySpaces.s28, bottom: MySpaces.s28,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
color: Color(0XFFF5E8D7).withValues(alpha: 0.5),
borderRadius: BorderRadius.all(Radius.circular(20)),
color: const Color(0XFFF5E8D7).withValues(alpha: 0.5),
borderRadius: const BorderRadius.all(Radius.circular(20)),
border: Border.all( border: Border.all(
width: 1, width: 1,
color: MyColors.white.withValues(alpha: 0.5), color: MyColors.white.withValues(alpha: 0.5),
@ -55,9 +55,9 @@ class _ShapeClipper extends CustomClipper<Path> {
@override @override
Path getClip(Size size) { Path getClip(Size size) {
var path = Path();
double w = size.width;
double h = size.height;
final Path path = Path();
final double w = size.width;
final double h = size.height;
// The drawing logic remains exactly the same // The drawing logic remains exactly the same
path.moveTo(w * 0.92, 0); path.moveTo(w * 0.92, 0);

4
lib/features/language/presentation/bloc/language_bloc.dart

@ -49,9 +49,9 @@ class LanguageBloc extends Bloc<LanguageEvent, LanguageState> {
value: state.selectedLang.code ?? MyConstants.defaultLanguage, value: state.selectedLang.code ?? MyConstants.defaultLanguage,
), ),
]); ]);
AppBloc appBloc = locator();
final AppBloc appBloc = locator();
appBloc.add( appBloc.add(
ChangeLocaleEvent(state.selectedLang.locale ?? Locale('en', 'US')));
ChangeLocaleEvent(state.selectedLang.locale ?? const Locale('en', 'US')));
if (Directory( if (Directory(
'${StoragePath.documentDir.path}/${state.selectedLang '${StoragePath.documentDir.path}/${state.selectedLang

10
lib/features/language/presentation/ui/language_page.dart

@ -26,13 +26,13 @@ class LanguagePage extends StatelessWidget {
height: context.heightScreen, height: context.heightScreen,
width: context.widthScreen, width: context.widthScreen,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient(
gradient: const LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [Color(0XFF00154C), Color(0XFF150532)], colors: [Color(0XFF00154C), Color(0XFF150532)],
), ),
image: DecorationImage( image: DecorationImage(
image: AssetImage(MyAssets.pattern),
image: const AssetImage(MyAssets.pattern),
scale: 3, scale: 3,
repeat: ImageRepeat.repeat, repeat: ImageRepeat.repeat,
colorFilter: ColorFilter.mode( colorFilter: ColorFilter.mode(
@ -61,7 +61,7 @@ class LanguagePage extends StatelessWidget {
spacing: MySpaces.s10, spacing: MySpaces.s10,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
MyImage(image: MyAssets.lang, size: 28),
const MyImage(image: MyAssets.lang, size: 28),
Expanded( Expanded(
child: AutoSizeText( child: AutoSizeText(
context.translate.select_language, context.translate.select_language,
@ -69,7 +69,7 @@ class LanguagePage extends StatelessWidget {
maxFontSize: 20, maxFontSize: 20,
maxLines: 1, maxLines: 1,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: MYTextStyle.titr0.copyWith(color: Color(0XFF847AC4)),
style: MYTextStyle.titr0.copyWith(color: const Color(0XFF847AC4)),
), ),
), ),
], ],
@ -108,7 +108,7 @@ class LanguagePage extends StatelessWidget {
Widget _btn(BuildContext context) { Widget _btn(BuildContext context) {
return MyBlueButton( return MyBlueButton(
onTap: () => context.read<LanguageBloc>().add(SaveLevelsEvent()),
onTap: () => context.read<LanguageBloc>().add(const SaveLevelsEvent()),
title: context.translate.select, title: context.translate.select,
); );
} }

14
lib/features/language/presentation/ui/widgets/language_widget.dart

@ -19,7 +19,7 @@ class LanguageWidget extends StatelessWidget {
onTap: onTap, onTap: onTap,
title: Text(title ?? ''), title: Text(title ?? ''),
titleTextStyle: MYTextStyle.titr1, titleTextStyle: MYTextStyle.titr1,
contentPadding: EdgeInsets.symmetric(
contentPadding: const EdgeInsets.symmetric(
vertical: MySpaces.s12, vertical: MySpaces.s12,
horizontal: 30, horizontal: 30,
), ),
@ -31,20 +31,20 @@ class LanguageWidget extends StatelessWidget {
? Container( ? Container(
height: 17, height: 17,
width: 17, width: 17,
padding: EdgeInsets.all(3),
padding: const EdgeInsets.all(3),
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
border: Border.all(width: 1, color: Color(0XFF3CFF3C)),
gradient: LinearGradient(
border: Border.all(width: 1, color: const Color(0XFF3CFF3C)),
gradient: const LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [Color(0XFF48D336), Color(0XFF2D7C23)], colors: [Color(0XFF48D336), Color(0XFF2D7C23)],
), ),
), ),
child: MyImage(image: MyAssets.doneRounded),
child: const MyImage(image: MyAssets.doneRounded),
) )
: SizedBox(height: 17, width: 17),
shape: RoundedRectangleBorder(
: const SizedBox(height: 17, width: 17),
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12)), borderRadius: BorderRadius.all(Radius.circular(12)),
), ),
selectedTileColor: MyColors.white.withValues(alpha: 0.2), selectedTileColor: MyColors.white.withValues(alpha: 0.2),

2
lib/features/level/data/datasource/level_datasource.dart

@ -26,7 +26,7 @@ class LocalLevelDatasourceImpl implements ILevelDatasource {
); );
return findData.nodes ?? []; return findData.nodes ?? [];
} catch (_) { } catch (_) {
throw MyException(errorMessage: 'Operation Failed');
throw const MyException(errorMessage: 'Operation Failed');
} }
} }
} }

2
lib/features/level/presentation/bloc/level_bloc.dart

@ -240,7 +240,7 @@ class LevelBloc extends Bloc<LevelEvent, LevelState> {
} }
int get diamonds { int get diamonds {
int currentLevel = int.parse(
final int currentLevel = int.parse(
LocalStorage.readData(key: MyConstants.currentLevel) ?? '1', LocalStorage.readData(key: MyConstants.currentLevel) ?? '1',
); );
return currentLevel - 1; return currentLevel - 1;

8
lib/features/level/presentation/ui/level_page.dart

@ -193,7 +193,7 @@ class LevelPage extends StatelessWidget {
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
Positioned.fill(
const Positioned.fill(
child: LevelPath(), child: LevelPath(),
), ),
Positioned.fill(child: _levelLocation(context)), Positioned.fill(child: _levelLocation(context)),
@ -243,7 +243,7 @@ class LevelPage extends StatelessWidget {
} }
Widget _ship(BuildContext context) { Widget _ship(BuildContext context) {
return ShipAnim(
return const ShipAnim(
child: MyImage(image: MyAssets.ship), child: MyImage(image: MyAssets.ship),
); );
} }
@ -278,7 +278,7 @@ class LevelPage extends StatelessWidget {
size: setSize(context: context, tablet: 80), size: setSize(context: context, tablet: 80),
), ),
), ),
Spacer(),
const Spacer(),
DiamondLevel( DiamondLevel(
diamonds: context.read<LevelBloc>().diamonds, diamonds: context.read<LevelBloc>().diamonds,
), ),
@ -299,7 +299,7 @@ class LevelPage extends StatelessWidget {
} }
Widget _background(BuildContext context) { Widget _background(BuildContext context) {
return MyImage(
return const MyImage(
image: MyAssets.mapBackground, image: MyAssets.mapBackground,
fit: BoxFit.cover, fit: BoxFit.cover,
); );

2
lib/features/level/presentation/ui/widgets/bottom_path.dart

@ -10,7 +10,7 @@ class BottomPath extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return CustomPaint( return CustomPaint(
painter: _Path(),
painter: const _Path(),
size: Size( size: Size(
context.widthScreen * 0.76, context.widthScreen * 0.76,
context.heightScreen * 0.64, context.heightScreen * 0.64,

4
lib/features/level/presentation/ui/widgets/diamond_level.dart

@ -32,7 +32,7 @@ class DiamondLevel extends StatelessWidget {
MySpaces.s16.gapWidth, MySpaces.s16.gapWidth,
ShaderMask( ShaderMask(
blendMode: BlendMode.modulate, blendMode: BlendMode.modulate,
shaderCallback: (bounds) => LinearGradient(
shaderCallback: (bounds) => const LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [Color(0XFF4BA5EA), Color(0XFF0C4EE9)], colors: [Color(0XFF4BA5EA), Color(0XFF0C4EE9)],
@ -44,7 +44,7 @@ class DiamondLevel extends StatelessWidget {
shadows: [ shadows: [
BoxShadow( BoxShadow(
color: MyColors.black.withValues(alpha: 0.25), color: MyColors.black.withValues(alpha: 0.25),
offset: Offset(0, 1.43),
offset: const Offset(0, 1.43),
blurRadius: 1.43, blurRadius: 1.43,
), ),
], ],

30
lib/features/level/presentation/ui/widgets/node_widget.dart

@ -21,15 +21,15 @@ enum LevelType {
}; };
static Map<LevelType, Color> get textShadowColor => { static Map<LevelType, Color> get textShadowColor => {
LevelType.unFinished: Color(0XFF5B5B5B),
LevelType.finished: Color(0XFF096D7B),
LevelType.current: Color(0XFF91500D),
LevelType.unFinished: const Color(0XFF5B5B5B),
LevelType.finished: const Color(0XFF096D7B),
LevelType.current: const Color(0XFF91500D),
}; };
static Map<LevelType, Color> get textColor => { static Map<LevelType, Color> get textColor => {
LevelType.unFinished: Color(0XFFEDEDED),
LevelType.finished: Color(0XFFFFF2D0),
LevelType.current: Color(0XFFFFF2D0),
LevelType.unFinished: const Color(0XFFEDEDED),
LevelType.finished: const Color(0XFFFFF2D0),
LevelType.current: const Color(0XFFFFF2D0),
}; };
} }
@ -66,10 +66,10 @@ class NodeWidget extends StatelessWidget {
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
if (getReward(node.prize?.afterLevel ?? 1)) ...{ if (getReward(node.prize?.afterLevel ?? 1)) ...{
MyImage(image: MyAssets.giftBackground, size: 70),
MyImage(image: MyAssets.gift, size: 50),
const MyImage(image: MyAssets.giftBackground, size: 70),
const MyImage(image: MyAssets.gift, size: 50),
} else ...{ } else ...{
MyImage(image: MyAssets.giftDisable, size: 50),
const MyImage(image: MyAssets.giftDisable, size: 50),
}, },
], ],
), ),
@ -97,7 +97,7 @@ class NodeWidget extends StatelessWidget {
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [ colors: [
Color(0XFFFFFFFF),
const Color(0XFFFFFFFF),
LevelType.textColor[type(node.level?.order ?? 1)] ?? LevelType.textColor[type(node.level?.order ?? 1)] ??
MyColors.white, MyColors.white,
], ],
@ -118,7 +118,7 @@ class NodeWidget extends StatelessWidget {
node.level?.order ?? 1, node.level?.order ?? 1,
)] ?? )] ??
MyColors.white, MyColors.white,
offset: Offset(0, 2.97),
offset: const Offset(0, 2.97),
), ),
], ],
), ),
@ -138,17 +138,17 @@ class NodeWidget extends StatelessWidget {
child: Container( child: Container(
height: setSize(context: context, mobile: 17, tablet: 24), height: setSize(context: context, mobile: 17, tablet: 24),
width: setSize(context: context, mobile: 17, tablet: 24), width: setSize(context: context, mobile: 17, tablet: 24),
padding: EdgeInsets.all(3),
padding: const EdgeInsets.all(3),
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
border: Border.all(width: 1, color: Color(0XFF3CFF3C)),
gradient: LinearGradient(
border: Border.all(width: 1, color: const Color(0XFF3CFF3C)),
gradient: const LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [Color(0XFF48D336), Color(0XFF2D7C23)], colors: [Color(0XFF48D336), Color(0XFF2D7C23)],
), ),
), ),
child: MyImage(image: MyAssets.doneRounded),
child: const MyImage(image: MyAssets.doneRounded),
), ),
), ),
], ],

12
lib/features/level/presentation/ui/widgets/play_button.dart

@ -20,16 +20,16 @@ class PlayButton extends StatelessWidget {
child: Stack( child: Stack(
alignment: Alignment.center, alignment: Alignment.center,
children: [ children: [
MyImage(image: MyAssets.button2),
const MyImage(image: MyAssets.button2),
Positioned( Positioned(
top: MySpaces.s2, top: MySpaces.s2,
child: Row( child: Row(
spacing: MySpaces.s4, spacing: MySpaces.s4,
children: [ children: [
MyImage(image: MyAssets.iconPlay),
const MyImage(image: MyAssets.iconPlay),
ShaderMask( ShaderMask(
blendMode: BlendMode.modulate, blendMode: BlendMode.modulate,
shaderCallback: (bounds) => LinearGradient(
shaderCallback: (bounds) => const LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [Color(0XFFF9601F), Color(0XFFD93D16)], colors: [Color(0XFFF9601F), Color(0XFFD93D16)],
@ -40,8 +40,8 @@ class PlayButton extends StatelessWidget {
style: MYTextStyle.button1.copyWith( style: MYTextStyle.button1.copyWith(
shadows: [ shadows: [
BoxShadow( BoxShadow(
color: Color(0XFFFFFFAB).withValues(alpha: 0.40),
offset: Offset(0, 2.61),
color: const Color(0XFFFFFFAB).withValues(alpha: 0.40),
offset: const Offset(0, 2.61),
), ),
], ],
), ),
@ -54,7 +54,7 @@ class PlayButton extends StatelessWidget {
bottom: MySpaces.s20, bottom: MySpaces.s20,
child: Text( child: Text(
'${context.translate.step} ${level.order ?? 0}', '${context.translate.step} ${level.order ?? 0}',
style: MYTextStyle.matn3.copyWith(color: Color(0XFFD8490B)),
style: MYTextStyle.matn3.copyWith(color: const Color(0XFFD8490B)),
), ),
), ),
], ],

2
lib/features/question/data/datasource/question_datasource.dart

@ -49,7 +49,7 @@ class QuestionDatasourceImpl implements IQuestionDatasource {
orElse: () => TotalDataEntity(), orElse: () => TotalDataEntity(),
); );
if(index > (findData.nodes?.length ?? 0)){ if(index > (findData.nodes?.length ?? 0)){
throw MyException();
throw const MyException();
} }
final NodeEntity? findLevel = findData.nodes?.singleWhere( final NodeEntity? findLevel = findData.nodes?.singleWhere(
(e) => e.level?.order == index, (e) => e.level?.order == index,

8
lib/features/question/presentation/bloc/question_bloc.dart

@ -29,7 +29,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> {
this._getNextLevelUseCase, this._getNextLevelUseCase,
this._mainAudioService, this._mainAudioService,
this._effectAudioService, this._effectAudioService,
) : super(QuestionState()) {
) : super(const QuestionState()) {
volumeStream = _mainAudioService.volumeStream(); volumeStream = _mainAudioService.volumeStream();
playingStream = _mainAudioService.playingStream(); playingStream = _mainAudioService.playingStream();
initAudios(); initAudios();
@ -238,7 +238,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> {
], ],
); );
emit(state.copyWith( emit(state.copyWith(
getQuestionStatus: BaseComplete(''),
getQuestionStatus: const BaseComplete(''),
levelEntity: level, levelEntity: level,
currentQuestion: data.questions?.first, currentQuestion: data.questions?.first,
)); ));
@ -268,7 +268,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> {
e.order == event.correctAnswer) ?? AnswerEntity(), e.order == event.correctAnswer) ?? AnswerEntity(),
showConfetti: true, showConfetti: true,
); );
await Future.delayed(Duration(seconds: 1), () async {
await Future.delayed(const Duration(seconds: 1), () async {
final QuestionEntity? findPreQuestion = state.currentQuestion; final QuestionEntity? findPreQuestion = state.currentQuestion;
final int findIndex = (findPreQuestion?.order ?? 1); final int findIndex = (findPreQuestion?.order ?? 1);
emit( emit(
@ -291,7 +291,7 @@ class QuestionBloc extends Bloc<QuestionEvent, QuestionState> {
} else { } else {
showingAnswerSequence(show: true); showingAnswerSequence(show: true);
answerAnimationController.reverse(); answerAnimationController.reverse();
await Future.delayed(Duration(seconds: 1));
await Future.delayed(const Duration(seconds: 1));
imageAnimationController.forward(); imageAnimationController.forward();
await playQuestionAudio(); await playQuestionAudio();
imageAnimationController.reverse(); imageAnimationController.reverse();

12
lib/features/question/presentation/ui/question_page.dart

@ -33,13 +33,13 @@ class QuestionPage extends StatelessWidget {
tablet: MySpaces.s30) ?? 0, tablet: MySpaces.s30) ?? 0,
), ),
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient(
gradient: const LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [Color(0XFF6930DA), Color(0XFF263AA1)], colors: [Color(0XFF6930DA), Color(0XFF263AA1)],
), ),
image: DecorationImage( image: DecorationImage(
image: AssetImage(MyAssets.pattern),
image: const AssetImage(MyAssets.pattern),
scale: 3, scale: 3,
repeat: ImageRepeat.repeat, repeat: ImageRepeat.repeat,
colorFilter: ColorFilter.mode( colorFilter: ColorFilter.mode(
@ -50,7 +50,7 @@ class QuestionPage extends StatelessWidget {
), ),
child: Column( child: Column(
children: [ children: [
setPlatform<double>(android: MySpaces.s20, iOS: 50)?.gapHeight ?? SizedBox.shrink(),
setPlatform<double>(android: MySpaces.s20, iOS: 50)?.gapHeight ?? const SizedBox.shrink(),
_topButtons(context), _topButtons(context),
MySpaces.s10.gapHeight, MySpaces.s10.gapHeight,
Expanded( Expanded(
@ -61,14 +61,14 @@ class QuestionPage extends StatelessWidget {
builder: (context, state) { builder: (context, state) {
if (state.currentQuestion?.order == if (state.currentQuestion?.order ==
state.levelEntity?.questions?.length) { state.levelEntity?.questions?.length) {
return DiamondScreen();
return const DiamondScreen();
} else { } else {
return QuestionScreen();
return const QuestionScreen();
} }
}, },
), ),
), ),
setPlatform<double>(android: MySpaces.s20,)?.gapHeight ?? SizedBox.shrink(),
setPlatform<double>(android: MySpaces.s20,)?.gapHeight ?? const SizedBox.shrink(),
], ],
), ),
), ),

8
lib/features/question/presentation/ui/screens/diamond_screen.dart

@ -41,7 +41,7 @@ class DiamondScreen extends StatelessWidget {
Lottie.asset( Lottie.asset(
MyAnimations.lightPurple, MyAnimations.lightPurple,
), ),
MyImage(
const MyImage(
image: MyAssets.diamondBig, image: MyAssets.diamondBig,
), ),
Positioned( Positioned(
@ -58,7 +58,7 @@ class DiamondScreen extends StatelessWidget {
style: MYTextStyle.titr0, style: MYTextStyle.titr0,
), ),
ShaderMask( ShaderMask(
shaderCallback: (bounds) => LinearGradient(
shaderCallback: (bounds) => const LinearGradient(
begin: Alignment.centerLeft, begin: Alignment.centerLeft,
end: Alignment.centerRight, end: Alignment.centerRight,
colors: [ colors: [
@ -72,7 +72,7 @@ class DiamondScreen extends StatelessWidget {
shadows: [ shadows: [
BoxShadow( BoxShadow(
color: MyColors.black.withValues(alpha: 0.25), color: MyColors.black.withValues(alpha: 0.25),
offset: Offset(0, 1.22),
offset: const Offset(0, 1.22),
blurRadius: 0.82, blurRadius: 0.82,
), ),
], ],
@ -150,7 +150,7 @@ class DiamondScreen extends StatelessWidget {
Widget _ship(BuildContext context) { Widget _ship(BuildContext context) {
return ShipAnim(
return const ShipAnim(
child: MyImage(image: MyAssets.ship), child: MyImage(image: MyAssets.ship),
); );
} }

22
lib/features/question/presentation/ui/screens/question_screen.dart

@ -42,14 +42,14 @@ class _QuestionScreenState extends State<QuestionScreen> with TickerProviderStat
WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addObserver(this);
context.read<QuestionBloc>().answerAnimationController = AnimationController( context.read<QuestionBloc>().answerAnimationController = AnimationController(
vsync: this, vsync: this,
duration: Duration(milliseconds: 500),
reverseDuration: Duration(milliseconds: 500),
duration: const Duration(milliseconds: 500),
reverseDuration: const Duration(milliseconds: 500),
); );
context.read<QuestionBloc>().imageAnimationController = AnimationController( context.read<QuestionBloc>().imageAnimationController = AnimationController(
vsync: this, vsync: this,
duration: Duration(milliseconds: 500),
reverseDuration: Duration(milliseconds: 500),
duration: const Duration(milliseconds: 500),
reverseDuration: const Duration(milliseconds: 500),
); );
if(LocalStorage.readData(key: MyConstants.firstShowcase) == 'true') { if(LocalStorage.readData(key: MyConstants.firstShowcase) == 'true') {
context.read<QuestionBloc>().imageAnimationController.forward(); context.read<QuestionBloc>().imageAnimationController.forward();
@ -93,10 +93,10 @@ class _QuestionScreenState extends State<QuestionScreen> with TickerProviderStat
Widget _questionImage(BuildContext context) { Widget _questionImage(BuildContext context) {
return Column( return Column(
children: [ children: [
Spacer(),
const Spacer(),
BlocBuilder<QuestionBloc, QuestionState>( BlocBuilder<QuestionBloc, QuestionState>(
builder: (context, state) => FadeAnimDelayed( builder: (context, state) => FadeAnimDelayed(
duration: Duration(seconds: 1),
duration: const Duration(seconds: 1),
child: FadeAnimController( child: FadeAnimController(
key: Key('${state.currentQuestion?.image}'), key: Key('${state.currentQuestion?.image}'),
controller: context.read<QuestionBloc>().imageAnimationController, controller: context.read<QuestionBloc>().imageAnimationController,
@ -111,7 +111,7 @@ class _QuestionScreenState extends State<QuestionScreen> with TickerProviderStat
), ),
), ),
), ),
Spacer(),
const Spacer(),
], ],
); );
} }
@ -141,7 +141,7 @@ class _QuestionScreenState extends State<QuestionScreen> with TickerProviderStat
style: MYTextStyle.titr1.copyWith( style: MYTextStyle.titr1.copyWith(
shadows: [ shadows: [
BoxShadow( BoxShadow(
offset: Offset(0, 2),
offset: const Offset(0, 2),
color: MyColors.black.withValues(alpha: 0.25), color: MyColors.black.withValues(alpha: 0.25),
), ),
], ],
@ -161,13 +161,13 @@ class _QuestionScreenState extends State<QuestionScreen> with TickerProviderStat
previous.currentQuestion?.id != current.currentQuestion?.id, previous.currentQuestion?.id != current.currentQuestion?.id,
builder: (context, state) => GridView.builder( builder: (context, state) => GridView.builder(
itemCount: state.currentQuestion?.answers?.length ?? 0, itemCount: state.currentQuestion?.answers?.length ?? 0,
physics: NeverScrollableScrollPhysics(),
physics: const NeverScrollableScrollPhysics(),
shrinkWrap: true, shrinkWrap: true,
clipBehavior: Clip.none, clipBehavior: Clip.none,
padding: EdgeInsets.symmetric( padding: EdgeInsets.symmetric(
horizontal: setSize(context: context, tablet: 70) ?? 0, horizontal: setSize(context: context, tablet: 70) ?? 0,
), ),
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2, crossAxisCount: 2,
crossAxisSpacing: MySpaces.s20, crossAxisSpacing: MySpaces.s20,
mainAxisSpacing: 20, mainAxisSpacing: 20,
@ -175,7 +175,7 @@ class _QuestionScreenState extends State<QuestionScreen> with TickerProviderStat
), ),
itemBuilder: (context, index) => itemBuilder: (context, index) =>
state.currentQuestion?.answers?[index].imageId == null state.currentQuestion?.answers?[index].imageId == null
? SizedBox.shrink()
? const SizedBox.shrink()
: SlideAnim( : SlideAnim(
key: Key('${state.currentQuestion?.id}'), key: Key('${state.currentQuestion?.id}'),
controller: context.read<QuestionBloc>().answerAnimationController, controller: context.read<QuestionBloc>().answerAnimationController,

4
lib/features/question/presentation/ui/widgets/glassy_button.dart

@ -25,7 +25,7 @@ class GlassyButton extends StatelessWidget {
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [ colors: [
Colors.white.withValues(alpha: 0.3), Colors.white.withValues(alpha: 0.3),
Color(0XFF6930DA).withValues(alpha: 0.1),
const Color(0XFF6930DA).withValues(alpha: 0.1),
], ],
), ),
border: Border.all(color: Colors.white.withValues(alpha: 0.3)), border: Border.all(color: Colors.white.withValues(alpha: 0.3)),
@ -33,7 +33,7 @@ class GlassyButton extends StatelessWidget {
child: MyInkwell( child: MyInkwell(
onTap: onTap, onTap: onTap,
audio: audio, audio: audio,
borderRadius: BorderRadius.all(Radius.circular(100)),
borderRadius: const BorderRadius.all(Radius.circular(100)),
child: Padding( child: Padding(
padding: EdgeInsets.all( padding: EdgeInsets.all(
setSize(context: context, mobile: MySpaces.s12, tablet: MySpaces.s20) ?? 0, setSize(context: context, mobile: MySpaces.s12, tablet: MySpaces.s20) ?? 0,

18
lib/features/question/presentation/ui/widgets/question_stepper.dart

@ -15,7 +15,7 @@ class QuestionStepper extends StatelessWidget {
height: 70, height: 70,
child: EasyStepper( child: EasyStepper(
activeStep: currentStep - 1, activeStep: currentStep - 1,
lineStyle: LineStyle(
lineStyle: const LineStyle(
lineLength: 20, lineLength: 20,
lineType: LineType.normal, lineType: LineType.normal,
defaultLineColor: Color(0XFFDFDDF6), defaultLineColor: Color(0XFFDFDDF6),
@ -29,36 +29,36 @@ class QuestionStepper extends StatelessWidget {
showLoadingAnimation: false, showLoadingAnimation: false,
stepRadius: 18, stepRadius: 18,
showStepBorder: false, showStepBorder: false,
padding: EdgeInsets.all(0),
padding: const EdgeInsets.all(0),
enableStepTapping: false, enableStepTapping: false,
steps: List.generate( steps: List.generate(
length, length,
(index) => EasyStep( (index) => EasyStep(
customStep: index == length - 1 customStep: index == length - 1
? MyImage(image: MyAssets.diamond, size: 50)
? const MyImage(image: MyAssets.diamond, size: 50)
: ClipPath( : ClipPath(
clipper: _StepperClipper(), clipper: _StepperClipper(),
child: Container( child: Container(
height: 32, height: 32,
width: 32, width: 32,
padding: EdgeInsets.all(4),
decoration: BoxDecoration(
padding: const EdgeInsets.all(4),
decoration: const BoxDecoration(
color: Color(0XFFDFDDF6), color: Color(0XFFDFDDF6),
shape: BoxShape.circle, shape: BoxShape.circle,
), ),
child: ClipPath( child: ClipPath(
clipper: _StepperClipper(), clipper: _StepperClipper(),
child: Container( child: Container(
padding: EdgeInsets.all(6),
padding: const EdgeInsets.all(6),
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: index < currentStep - 1 color: index < currentStep - 1
? Color(0XFF21B738)
? const Color(0XFF21B738)
: index == currentStep - 1 : index == currentStep - 1
? Color(0XFF847AC4)
? const Color(0XFF847AC4)
: Colors.transparent, : Colors.transparent,
), ),
child: index < currentStep - 1 ? MyImage(image: MyAssets.done) : null,
child: index < currentStep - 1 ? const MyImage(image: MyAssets.done) : null,
), ),
), ),
), ),

2
lib/features/question/presentation/ui/widgets/question_title.dart

@ -31,7 +31,7 @@ class QuestionTitle extends StatelessWidget {
BoxShadow( BoxShadow(
color: MyColors.black.withValues(alpha: 0.25), color: MyColors.black.withValues(alpha: 0.25),
blurRadius: 0.82, blurRadius: 0.82,
offset: Offset(0, 1.22),
offset: const Offset(0, 1.22),
), ),
], ],
), ),

2
lib/features/sample/presentation/ui/sample_page.dart

@ -5,7 +5,7 @@ class SamplePage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold(
return const Scaffold(
body: Center( body: Center(
child: Text('Sample Page'), child: Text('Sample Page'),
), ),

2
lib/features/splash/presentation/bloc/splash_bloc.dart

@ -21,7 +21,7 @@ class SplashBloc extends Bloc<SplashEvent, SplashState> {
Future<void> goToHomePage(BuildContext context) async { Future<void> goToHomePage(BuildContext context) async {
await preCacheImages(); await preCacheImages();
await Future.delayed( await Future.delayed(
Duration(seconds: 2),
const Duration(seconds: 2),
() { () {
if (context.mounted) { if (context.mounted) {
context.goNamed(Routes.homePage); context.goNamed(Routes.homePage);

6
lib/features/splash/presentation/ui/splash_page.dart

@ -32,7 +32,7 @@ class _SplashPageState extends State<SplashPage> {
height: context.heightScreen, height: context.heightScreen,
width: context.widthScreen, width: context.widthScreen,
decoration: BoxDecoration( decoration: BoxDecoration(
gradient: LinearGradient(
gradient: const LinearGradient(
begin: Alignment.topCenter, begin: Alignment.topCenter,
end: Alignment.bottomCenter, end: Alignment.bottomCenter,
colors: [ colors: [
@ -41,7 +41,7 @@ class _SplashPageState extends State<SplashPage> {
], ],
), ),
image: DecorationImage( image: DecorationImage(
image: AssetImage(MyAssets.pattern),
image: const AssetImage(MyAssets.pattern),
scale: 3, scale: 3,
repeat: ImageRepeat.repeat, repeat: ImageRepeat.repeat,
colorFilter: ColorFilter.mode( colorFilter: ColorFilter.mode(
@ -62,7 +62,7 @@ class _SplashPageState extends State<SplashPage> {
} }
Widget _image() { Widget _image() {
return Stack(
return const Stack(
children: [ children: [
MyImage( MyImage(
image: MyAssets.hadiHoda, image: MyAssets.hadiHoda,

6
lib/init_bindings.dart

@ -70,18 +70,18 @@ void initBindings() {
locator.registerLazySingleton<LoadingStreamUseCase>(() => LoadingStreamUseCase(locator())); locator.registerLazySingleton<LoadingStreamUseCase>(() => LoadingStreamUseCase(locator()));
/// Guider Feature /// Guider Feature
locator.registerLazySingleton<IGuiderDatasource>(() => GuiderDatasourceImpl());
locator.registerLazySingleton<IGuiderDatasource>(() => const GuiderDatasourceImpl());
locator.registerLazySingleton<IGuiderRepository>(() => GuiderRepositoryImpl(locator())); locator.registerLazySingleton<IGuiderRepository>(() => GuiderRepositoryImpl(locator()));
locator.registerLazySingleton<GetFirstLevelUseCase>(() => GetFirstLevelUseCase(locator())); locator.registerLazySingleton<GetFirstLevelUseCase>(() => GetFirstLevelUseCase(locator()));
/// Question Feature /// Question Feature
locator.registerLazySingleton<IQuestionDatasource>(() => QuestionDatasourceImpl());
locator.registerLazySingleton<IQuestionDatasource>(() => const QuestionDatasourceImpl());
locator.registerLazySingleton<IQuestionRepository>(() => QuestionRepositoryImpl(locator())); locator.registerLazySingleton<IQuestionRepository>(() => QuestionRepositoryImpl(locator()));
locator.registerLazySingleton<GetLevelUseCase>(() => GetLevelUseCase(locator())); locator.registerLazySingleton<GetLevelUseCase>(() => GetLevelUseCase(locator()));
locator.registerLazySingleton<GetNextLevelUseCase>(() => GetNextLevelUseCase(locator())); locator.registerLazySingleton<GetNextLevelUseCase>(() => GetNextLevelUseCase(locator()));
/// Level Feature /// Level Feature
locator.registerLazySingleton<ILevelDatasource>(() => LocalLevelDatasourceImpl());
locator.registerLazySingleton<ILevelDatasource>(() => const LocalLevelDatasourceImpl());
locator.registerLazySingleton<ILevelRepository>(() => LevelRepositoryImpl(locator())); locator.registerLazySingleton<ILevelRepository>(() => LevelRepositoryImpl(locator()));
locator.registerLazySingleton<GetLevelsUseCase>(() => GetLevelsUseCase(locator())); locator.registerLazySingleton<GetLevelsUseCase>(() => GetLevelsUseCase(locator()));
} }

2
lib/main.dart

@ -44,7 +44,7 @@ class MainApp extends StatelessWidget {
themeMode: ThemeService.getTheme(), themeMode: ThemeService.getTheme(),
locale: state.locale, locale: state.locale,
supportedLocales: MyConstants.languages.map( supportedLocales: MyConstants.languages.map(
(e) => e.locale ?? Locale('en', 'US'),
(e) => e.locale ?? const Locale('en', 'US'),
), ),
routerConfig: appPages, routerConfig: appPages,
localizationsDelegates: const [ localizationsDelegates: const [

1183
pubspec.lock
File diff suppressed because it is too large
View File

7
pubspec.yaml

@ -1,7 +1,7 @@
name: hadi_hoda_flutter name: hadi_hoda_flutter
description: "A new Flutter project." description: "A new Flutter project."
publish_to: 'none' publish_to: 'none'
version: 0.2.1+1
version: 0.3.1+1
environment: environment:
sdk: ^3.9.2 sdk: ^3.9.2
@ -9,7 +9,6 @@ environment:
dependencies: dependencies:
auto_size_text: ^3.0.0 auto_size_text: ^3.0.0
bloc: ^9.0.0 bloc: ^9.0.0
confetti: ^0.8.0
dio: ^5.9.0 dio: ^5.9.0
easy_stepper: ^0.8.5+1 easy_stepper: ^0.8.5+1
equatable: ^2.0.7 equatable: ^2.0.7
@ -52,9 +51,7 @@ flutter:
- assets/animations/ - assets/animations/
- assets/audios/ - assets/audios/
- assets/videos/ - assets/videos/
- path: assets/svg/
transformers:
- package: vector_graphics_compiler
- assets/svg/
fonts: fonts:

Loading…
Cancel
Save