From ae18a5f648f765a715a5f7e6e3d0791e31aa6dd0 Mon Sep 17 00:00:00 2001 From: "mr.mojtaba" Date: Tue, 3 Jun 2025 16:55:49 +0330 Subject: [PATCH] feat : captcha widget --- lib/presentations/common/assets.dart | 43 -------- .../local/user_local/user_local_model.dart | 2 + .../local/user_local/user_local_model.g.dart | 4 + .../lib/data/services/auth_middelware.dart | 4 +- packages/auth/lib/hive_registrar.g.dart | 3 +- .../lib/presentation/pages/modules/logic.dart | 1 + .../presentation/widget/captcha/logic.dart | 18 ++-- .../lib/presentation/widget/captcha/view.dart | 98 +++++++++++-------- tools/runner.sh | 2 - 9 files changed, 76 insertions(+), 99 deletions(-) delete mode 100644 lib/presentations/common/assets.dart diff --git a/lib/presentations/common/assets.dart b/lib/presentations/common/assets.dart deleted file mode 100644 index 2ee3b2b..0000000 --- a/lib/presentations/common/assets.dart +++ /dev/null @@ -1,43 +0,0 @@ -///This file is automatically generated. DO NOT EDIT, all your changes would be lost. -class Assets { - Assets._(); - - static const String iconsAdd = 'assets/icons/add.svg'; - static const String iconsArrowLeft = 'assets/icons/arrow_left.svg'; - static const String iconsArrowRight = 'assets/icons/arrow_right.svg'; - static const String iconsBgHeaderUserProfile = 'assets/icons/bg_header_user_profile.svg'; - static const String iconsCalendar = 'assets/icons/calendar.svg'; - static const String iconsCalendarSearch = 'assets/icons/calendar_search.svg'; - static const String iconsCall = 'assets/icons/call.svg'; - static const String iconsDiagram = 'assets/icons/diagram.svg'; - static const String iconsDownload = 'assets/icons/download.svg'; - static const String iconsEdit = 'assets/icons/edit.svg'; - static const String iconsExcelDownload = 'assets/icons/excel_download.svg'; - static const String iconsFilter = 'assets/icons/filter.svg'; - static const String iconsGps = 'assets/icons/gps.svg'; - static const String iconsInformation = 'assets/icons/information.svg'; - static const String iconsInspection = 'assets/icons/inspection.svg'; - static const String iconsKey = 'assets/icons/key.svg'; - static const String iconsLiveStock = 'assets/icons/liveStock.svg'; - static const String iconsLogout = 'assets/icons/logout.svg'; - static const String iconsMap = 'assets/icons/map.svg'; - static const String iconsMapMarker = 'assets/icons/map_marker.svg'; - static const String iconsMessageAdd = 'assets/icons/message_add.svg'; - static const String iconsPdfDownload = 'assets/icons/pdf_download.svg'; - static const String iconsPictureFrame = 'assets/icons/picture_frame.svg'; - static const String iconsProfileCircle = 'assets/icons/profile_circle.svg'; - static const String iconsProfileUser = 'assets/icons/profile_user.svg'; - static const String iconsReceiptDiscount = 'assets/icons/receipt_discount.svg'; - static const String iconsScan = 'assets/icons/scan.svg'; - static const String iconsScanBarcode = 'assets/icons/scan_barcode.svg'; - static const String iconsSearch = 'assets/icons/search.svg'; - static const String iconsSecurityTime = 'assets/icons/security_time.svg'; - static const String iconsSetting = 'assets/icons/setting.svg'; - static const String iconsTagUser = 'assets/icons/tag_user.svg'; - static const String iconsTrash = 'assets/icons/trash.svg'; - static const String iconsUser = 'assets/icons/user.svg'; - static const String iconsUserSquare = 'assets/icons/user_square.svg'; - static const String imagesInnerSplash = 'assets/images/inner_splash.webp'; - static const String imagesOutterSplash = 'assets/images/outter_splash.webp'; - -} diff --git a/packages/auth/lib/data/models/local/user_local/user_local_model.dart b/packages/auth/lib/data/models/local/user_local/user_local_model.dart index c14addc..0f603f6 100644 --- a/packages/auth/lib/data/models/local/user_local/user_local_model.dart +++ b/packages/auth/lib/data/models/local/user_local/user_local_model.dart @@ -53,4 +53,6 @@ enum Module { liveStocks, @HiveField(1) inspection, + @HiveField(2) + chicken, } diff --git a/packages/auth/lib/data/models/local/user_local/user_local_model.g.dart b/packages/auth/lib/data/models/local/user_local/user_local_model.g.dart index efaac19..8a40c52 100644 --- a/packages/auth/lib/data/models/local/user_local/user_local_model.g.dart +++ b/packages/auth/lib/data/models/local/user_local/user_local_model.g.dart @@ -66,6 +66,8 @@ class ModuleAdapter extends TypeAdapter { return Module.liveStocks; case 1: return Module.inspection; + case 2: + return Module.chicken; default: return Module.liveStocks; } @@ -78,6 +80,8 @@ class ModuleAdapter extends TypeAdapter { writer.writeByte(0); case Module.inspection: writer.writeByte(1); + case Module.chicken: + writer.writeByte(2); } } diff --git a/packages/auth/lib/data/services/auth_middelware.dart b/packages/auth/lib/data/services/auth_middelware.dart index ba907ce..14b6227 100644 --- a/packages/auth/lib/data/services/auth_middelware.dart +++ b/packages/auth/lib/data/services/auth_middelware.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:rasadyar_auth/data/di/auth_di.dart'; +import 'package:rasadyar_auth/data/models/local/user_local/user_local_model.dart'; import 'package:rasadyar_auth/data/services/token_storage_service.dart'; import 'package:rasadyar_core/core.dart'; @@ -14,7 +14,7 @@ class AuthMiddleware extends GetMiddleware { final accessToken = tokenService.accessToken.value; if (refreshToken == null || accessToken == null) { - return RouteSettings(name: AuthPaths.moduleList); + return RouteSettings(name: AuthPaths.auth, arguments: Module.chicken); } return super.redirect(route); } diff --git a/packages/auth/lib/hive_registrar.g.dart b/packages/auth/lib/hive_registrar.g.dart index b46fdff..166b5cb 100644 --- a/packages/auth/lib/hive_registrar.g.dart +++ b/packages/auth/lib/hive_registrar.g.dart @@ -7,9 +7,8 @@ import 'package:rasadyar_auth/data/models/local/user_local/user_local_model.dart extension HiveRegistrar on HiveInterface { void registerAdapters() { - registerAdapter(UserLocalModelAdapter()); registerAdapter(ModuleAdapter()); - + registerAdapter(UserLocalModelAdapter()); } } diff --git a/packages/auth/lib/presentation/pages/modules/logic.dart b/packages/auth/lib/presentation/pages/modules/logic.dart index bf9692c..56637e5 100644 --- a/packages/auth/lib/presentation/pages/modules/logic.dart +++ b/packages/auth/lib/presentation/pages/modules/logic.dart @@ -7,6 +7,7 @@ class ModulesLogic extends GetxController { List moduleList=[ ModuleModel(title: 'بازرسی', icon: Assets.icons.inspection.path, module: Module.inspection), ModuleModel(title: 'دام', icon: Assets.icons.liveStock.path, module: Module.liveStocks), + ModuleModel(title: 'مرغ', icon: Assets.icons.liveStock.path, module: Module.chicken), ]; diff --git a/packages/auth/lib/presentation/widget/captcha/logic.dart b/packages/auth/lib/presentation/widget/captcha/logic.dart index 6a89f38..a24052a 100644 --- a/packages/auth/lib/presentation/widget/captcha/logic.dart +++ b/packages/auth/lib/presentation/widget/captcha/logic.dart @@ -1,8 +1,9 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:rasadyar_auth/data/di/auth_di.dart'; import 'package:rasadyar_auth/data/models/response/captcha/captcha_response_model.dart'; import 'package:rasadyar_auth/data/repositories/auth_repository_imp.dart'; -import 'package:rasadyar_auth/data/utils/safe_call.dart'; import 'package:rasadyar_core/core.dart'; class CaptchaWidgetLogic extends GetxController with StateMixin { @@ -10,6 +11,7 @@ class CaptchaWidgetLogic extends GetxController with StateMixin formKey = GlobalKey(); AuthRepositoryImpl authRepository = diAuth.get(); + final Random random = Random(); @override void onInit() { @@ -27,15 +29,9 @@ class CaptchaWidgetLogic extends GetxController with StateMixin getCaptcha() async { change(null, status: RxStatus.loading()); textController.value.clear(); - safeCall( - call: () async => await authRepository.captcha(), - onSuccess: (value) { - captchaKey.value = value?.captchaKey; - change(value, status: RxStatus.success()); - }, - onError: (error, stackTrace) { - change(null, status: RxStatus.error(error.toString())); - }, - ); + await Future.delayed(Duration(milliseconds: 800)); + captchaKey.value = (random.nextInt(999999)+1000).toString(); + change(value, status: RxStatus.success()); + } } diff --git a/packages/auth/lib/presentation/widget/captcha/view.dart b/packages/auth/lib/presentation/widget/captcha/view.dart index d606b7b..125eb9e 100644 --- a/packages/auth/lib/presentation/widget/captcha/view.dart +++ b/packages/auth/lib/presentation/widget/captcha/view.dart @@ -1,4 +1,4 @@ -import 'dart:convert'; +import 'dart:math'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; @@ -16,35 +16,33 @@ class CaptchaWidget extends GetView { crossAxisAlignment: CrossAxisAlignment.start, children: [ GestureDetector( - onTap: controller.getCaptcha, - child: Container( - width: 135, - height: 50, - clipBehavior: Clip.antiAliasWithSaveLayer, - decoration: BoxDecoration( - color: AppColor.whiteNormalHover, - border: Border.all(color: Colors.grey.shade300), - borderRadius: BorderRadius.circular(8), - ), - child: controller.obx( - (state) => - Image.memory( - base64Decode(state?.captchaImage ?? ''), - fit: BoxFit.cover, - ), - onLoading: const Center( - child: CupertinoActivityIndicator(color: AppColor.blueNormal), + onTap: controller.getCaptcha, + child: Container( + width: 135, + height: 50, + clipBehavior: Clip.antiAliasWithSaveLayer, + decoration: BoxDecoration( + color: AppColor.whiteNormalHover, + border: Border.all(color: Colors.grey.shade300), + borderRadius: BorderRadius.circular(8), + ), + child: controller.obx( + (state) => Center( + child: Stack( + alignment: Alignment.center, + children: [ + CustomPaint(size: const Size(135, 50), painter: _CaptchaLinePainter()), + Text(controller.captchaKey.value ?? 'دوباره سعی کنید', style: AppFonts.yekan24Bold), + ], ), - onError: (error) { - return const Center( - child: Text( - 'خطا در بارگذاری کد امنیتی', - style: AppFonts.yekan13, - ), - ); - }, ), - )), + onLoading: const Center(child: CupertinoActivityIndicator(color: AppColor.blueNormal)), + onError: (error) { + return const Center(child: Text('خطا در بارگذاری کد امنیتی', style: AppFonts.yekan13)); + }, + ), + ), + ), const SizedBox(width: 8), Expanded( @@ -55,19 +53,11 @@ class CaptchaWidget extends GetView { return RTextField( label: 'کد امنیتی', controller: data.value, - keyboardType: TextInputType.numberWithOptions( - decimal: false, - signed: false, - ), + keyboardType: TextInputType.numberWithOptions(decimal: false, signed: false), maxLines: 1, maxLength: 6, - suffixIcon: - (data.value.text - .trim() - .isNotEmpty ?? false) - ? clearButton( - () => controller.textController.value.clear(), - ) + suffixIcon: (data.value.text.trim().isNotEmpty ?? false) + ? clearButton(() => controller.textController.value.clear()) : null, onSubmitted: (data) {}, @@ -86,3 +76,33 @@ class CaptchaWidget extends GetView { ); } } + +class _CaptchaLinePainter extends CustomPainter { + @override + void paint(Canvas canvas, Size size) { + final random = Random(); + final paint1 = Paint() + ..color = Color.fromRGBO(random.nextInt(255), random.nextInt(255), random.nextInt(255), 1) + ..strokeWidth = 2; + final paint2 = Paint() + ..color = Color.fromRGBO(random.nextInt(255), random.nextInt(255), random.nextInt(255), 1) + ..strokeWidth = 2; + +// First line: top-left to bottom-right + canvas.drawLine( + Offset(0, 0), + Offset(size.width, size.height), + paint1, + ); + +// Second line: bottom-left to top-right + canvas.drawLine( + Offset(0, size.height), + Offset(size.width, 0), + paint2, + ); + } + + @override + bool shouldRepaint(covariant CustomPainter oldDelegate) => false; +} diff --git a/tools/runner.sh b/tools/runner.sh index 1931741..ad699f9 100644 --- a/tools/runner.sh +++ b/tools/runner.sh @@ -1,4 +1,2 @@ cd ../ dart run build_runner build --delete-conflicting-outputs - -