chore: update devtools options to include new extensions, increment package versions, and refactor authentication logic for improved user experience

This commit is contained in:
2025-12-14 12:48:48 +03:30
parent afbd72404d
commit e7b0159ea9
28 changed files with 592 additions and 143 deletions

View File

@@ -1,5 +1,5 @@
sdk.dir=C:\\Users\\Housh11\\AppData\\Local\\Android\\sdk sdk.dir=C:\\Users\\Housh11\\AppData\\Local\\Android\\sdk
flutter.sdk=C:\\src\\flutter flutter.sdk=C:\\src\\flutter
flutter.buildMode=release flutter.buildMode=debug
flutter.versionName=1.3.36 flutter.versionName=1.3.36
flutter.versionCode=32 flutter.versionCode=32

View File

@@ -2,3 +2,5 @@ description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions: extensions:
- hive_ce: true - hive_ce: true
- provider: true
- shared_preferences: true

View File

@@ -2,3 +2,5 @@ description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions: extensions:
- hive_ce: true - hive_ce: true
- provider: true
- shared_preferences: true

View File

@@ -224,18 +224,14 @@ class AuthLogic extends GetxController with GetTickerProviderStateMixin {
if (Platform.isAndroid) { if (Platform.isAndroid) {
final info = await deviceInfo.androidInfo; final info = await deviceInfo.androidInfo;
print('Device: ${info.manufacturer} ${info.model}');
print('Android version: ${info.version.release}');
deviceName.value = deviceName.value =
'Device:${info.manufacturer} Model:${info.model} version ${info.version.release}'; 'Device:${info.manufacturer} Model:${info.model} version ${info.version.release}';
} else if (Platform.isIOS) { } else if (Platform.isIOS) {
final info = await deviceInfo.iosInfo; final info = await deviceInfo.iosInfo;
print('Device: ${info.utsname.machine} (${info.name})');
print('System version: ${info.systemVersion}');
deviceName.value = deviceName.value =
'Device:${info.utsname.machine} Model:${info.model} version ${info.systemVersion}'; 'Device:${info.utsname.machine} Model:${info.model} version ${info.systemVersion}';
} else { } else {}
print('Unsupported platform');
}
} }
} }

View File

@@ -43,12 +43,16 @@ class AuthPage extends GetView<AuthLogic> {
Text( Text(
'به سامانه رصدطیور خوش آمدید!', 'به سامانه رصدطیور خوش آمدید!',
textAlign: TextAlign.right, textAlign: TextAlign.right,
style: AppFonts.yekan25Bold.copyWith(color: AppColor.darkGreyDarkActive), style: AppFonts.yekan25Bold.copyWith(
color: AppColor.darkGreyDarkActive,
),
), ),
Text( Text(
'سامانه رصد و پایش زنجیره تامین، تولید و توزیع کالا های اساسی', 'سامانه رصد و پایش زنجیره تامین، تولید و توزیع کالا های اساسی',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDarkActive), style: AppFonts.yekan16.copyWith(
color: AppColor.darkGreyDarkActive,
),
), ),
], ],
), ),
@@ -80,7 +84,9 @@ class AuthPage extends GetView<AuthLogic> {
vecPath: Assets.vec.rasadToyorSvg.path, vecPath: Assets.vec.rasadToyorSvg.path,
width: 85.w, width: 85.w,
height: 85.h, height: 85.h,
titleStyle: AppFonts.yekan20Bold.copyWith(color: Color(0xFF4665AF)), titleStyle: AppFonts.yekan20Bold.copyWith(
color: Color(0xFF4665AF),
),
title: 'رصدطیور', title: 'رصدطیور',
), ),
SizedBox(height: 20.h), SizedBox(height: 20.h),
@@ -91,7 +97,9 @@ class AuthPage extends GetView<AuthLogic> {
children: [ children: [
TextSpan( TextSpan(
text: 'مطالعه بیانیه ', text: 'مطالعه بیانیه ',
style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyDark), style: AppFonts.yekan16.copyWith(
color: AppColor.darkGreyDark,
),
), ),
TextSpan( TextSpan(
recognizer: TapGestureRecognizer() recognizer: TapGestureRecognizer()
@@ -104,7 +112,9 @@ class AuthPage extends GetView<AuthLogic> {
); );
}, },
text: 'حریم خصوصی', text: 'حریم خصوصی',
style: AppFonts.yekan16.copyWith(color: AppColor.blueNormal), style: AppFonts.yekan16.copyWith(
color: AppColor.blueNormal,
),
), ),
], ],
), ),
@@ -128,6 +138,7 @@ class AuthPage extends GetView<AuthLogic> {
child: Column( child: Column(
children: [ children: [
RTextField( RTextField(
height: 40.h,
label: 'نام کاربری', label: 'نام کاربری',
maxLength: 11, maxLength: 11,
maxLines: 1, maxLines: 1,
@@ -150,7 +161,8 @@ class AuthPage extends GetView<AuthLogic> {
padding: const EdgeInsets.fromLTRB(0, 8, 6, 8), padding: const EdgeInsets.fromLTRB(0, 8, 6, 8),
child: Assets.vec.callSvg.svg(width: 12, height: 12), child: Assets.vec.callSvg.svg(width: 12, height: 12),
), ),
suffixIcon: controller.usernameController.value.text.trim().isNotEmpty suffixIcon:
controller.usernameController.value.text.trim().isNotEmpty
? clearButton(() { ? clearButton(() {
controller.usernameController.value.clear(); controller.usernameController.value.clear();
controller.usernameController.refresh(); controller.usernameController.refresh();
@@ -165,7 +177,9 @@ class AuthPage extends GetView<AuthLogic> {
return null; return null;
}, },
style: AppFonts.yekan13, style: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith(color: AppColor.redNormal), errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal,
),
labelStyle: AppFonts.yekan13, labelStyle: AppFonts.yekan13,
boxConstraints: const BoxConstraints( boxConstraints: const BoxConstraints(
maxHeight: 40, maxHeight: 40,
@@ -177,6 +191,7 @@ class AuthPage extends GetView<AuthLogic> {
const SizedBox(height: 26), const SizedBox(height: 26),
ObxValue( ObxValue(
(passwordController) => RTextField( (passwordController) => RTextField(
height: 40.h,
label: 'رمز عبور', label: 'رمز عبور',
filled: false, filled: false,
obscure: true, obscure: true,
@@ -199,7 +214,9 @@ class AuthPage extends GetView<AuthLogic> {
return null; return null;
}, },
style: AppFonts.yekan13, style: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith(color: AppColor.redNormal), errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal,
),
labelStyle: AppFonts.yekan13, labelStyle: AppFonts.yekan13,
prefixIcon: Padding( prefixIcon: Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8), padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
@@ -226,19 +243,26 @@ class AuthPage extends GetView<AuthLogic> {
ObxValue((data) { ObxValue((data) {
return Checkbox( return Checkbox(
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
visualDensity: VisualDensity(horizontal: -4, vertical: 4), visualDensity: VisualDensity(
horizontal: -4,
vertical: 4,
),
tristate: true, tristate: true,
value: data.value, value: data.value,
onChanged: (value) { onChanged: (value) {
data.value = value ?? false; data.value = value ?? false;
}, },
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(4)), shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4),
),
activeColor: AppColor.blueNormal, activeColor: AppColor.blueNormal,
); );
}, controller.rememberMe), }, controller.rememberMe),
Text( Text(
'مرا به خاطر بسپار', 'مرا به خاطر بسپار',
style: AppFonts.yekan14.copyWith(color: AppColor.darkGreyDark), style: AppFonts.yekan14.copyWith(
color: AppColor.darkGreyDark,
),
), ),
], ],
), ),
@@ -283,11 +307,16 @@ class AuthPage extends GetView<AuthLogic> {
children: [ children: [
Text( Text(
'بيانيه حريم خصوصی', 'بيانيه حريم خصوصی',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), style: AppFonts.yekan16Bold.copyWith(
color: AppColor.blueNormal,
),
), ),
Text( Text(
'اطلاعات مربوط به هر شخص، حریم خصوصی وی محسوب می‌شود. حفاظت و حراست از اطلاعات شخصی در سامانه رصد یار، نه تنها موجب حفظ امنیت کاربران می‌شود، بلکه باعث اعتماد بیشتر و مشارکت آنها در فعالیت‌های جاری می‌گردد. هدف از این بیانیه، آگاه ساختن شما درباره ی نوع و نحوه ی استفاده از اطلاعاتی است که در هنگام استفاده از سامانه رصد یار ، از جانب شما دریافت می‌گردد. شرکت هوشمند سازان خود را ملزم به رعایت حریم خصوصی همه شهروندان و کاربران سامانه دانسته و آن دسته از اطلاعات کاربران را که فقط به منظور ارائه خدمات کفایت می‌کند، دریافت کرده و از انتشار آن یا در اختیار قرار دادن آن به دیگران خودداری مینماید.', 'اطلاعات مربوط به هر شخص، حریم خصوصی وی محسوب می‌شود. حفاظت و حراست از اطلاعات شخصی در سامانه رصد یار، نه تنها موجب حفظ امنیت کاربران می‌شود، بلکه باعث اعتماد بیشتر و مشارکت آنها در فعالیت‌های جاری می‌گردد. هدف از این بیانیه، آگاه ساختن شما درباره ی نوع و نحوه ی استفاده از اطلاعاتی است که در هنگام استفاده از سامانه رصد یار ، از جانب شما دریافت می‌گردد. شرکت هوشمند سازان خود را ملزم به رعایت حریم خصوصی همه شهروندان و کاربران سامانه دانسته و آن دسته از اطلاعات کاربران را که فقط به منظور ارائه خدمات کفایت می‌کند، دریافت کرده و از انتشار آن یا در اختیار قرار دادن آن به دیگران خودداری مینماید.',
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark, height: 1.8), style: AppFonts.yekan14.copyWith(
color: AppColor.bgDark,
height: 1.8,
),
), ),
], ],
), ),
@@ -307,7 +336,9 @@ class AuthPage extends GetView<AuthLogic> {
children: [ children: [
Text( Text(
'چگونگی جمع آوری و استفاده از اطلاعات کاربران', 'چگونگی جمع آوری و استفاده از اطلاعات کاربران',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), style: AppFonts.yekan16Bold.copyWith(
color: AppColor.blueNormal,
),
), ),
Text( Text(
'''الف: اطلاعاتی که شما خود در اختيار این سامانه قرار می‌دهيد، شامل موارد زيرهستند: '''الف: اطلاعاتی که شما خود در اختيار این سامانه قرار می‌دهيد، شامل موارد زيرهستند:
@@ -319,7 +350,10 @@ class AuthPage extends GetView<AuthLogic> {
⦁ تعداد بازدیدهای روزانه در درگاه. ⦁ تعداد بازدیدهای روزانه در درگاه.
⦁ هدف ما از دریافت این اطلاعات استفاده از آنها در تحلیل عملکرد کاربران درگاه می باشد تا بتوانیم در خدمت رسانی بهتر عمل کنیم. ⦁ هدف ما از دریافت این اطلاعات استفاده از آنها در تحلیل عملکرد کاربران درگاه می باشد تا بتوانیم در خدمت رسانی بهتر عمل کنیم.
''', ''',
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark, height: 1.8), style: AppFonts.yekan14.copyWith(
color: AppColor.bgDark,
height: 1.8,
),
), ),
], ],
), ),
@@ -339,11 +373,16 @@ class AuthPage extends GetView<AuthLogic> {
children: [ children: [
Text( Text(
'امنیت اطلاعات', 'امنیت اطلاعات',
style: AppFonts.yekan16Bold.copyWith(color: AppColor.blueNormal), style: AppFonts.yekan16Bold.copyWith(
color: AppColor.blueNormal,
),
), ),
Text( Text(
'متعهدیم که امنیت اطلاعات شما را تضمین نماییم و برای جلوگیری از هر نوع دسترسی غیرمجاز و افشای اطلاعات شما از همه شیوه‌‌های لازم استفاده می‌کنیم تا امنیت اطلاعاتی را که به صورت آنلاین گردآوری می‌کنیم، حفظ شود. لازم به ذکر است در سامانه ما، ممکن است به سایت های دیگری لینک شوید، وقتی که شما از طریق این لینک‌ها از سامانه ما خارج می‌شوید، توجه داشته باشید که ما بر دیگر سایت ها کنترل نداریم و سازمان تعهدی بر حفظ حریم شخصی آنان در سایت مقصد نخواهد داشت و مراجعه کنندگان میبایست به بیانیه حریم شخصی آن سایت ها مراجعه نمایند.', 'متعهدیم که امنیت اطلاعات شما را تضمین نماییم و برای جلوگیری از هر نوع دسترسی غیرمجاز و افشای اطلاعات شما از همه شیوه‌‌های لازم استفاده می‌کنیم تا امنیت اطلاعاتی را که به صورت آنلاین گردآوری می‌کنیم، حفظ شود. لازم به ذکر است در سامانه ما، ممکن است به سایت های دیگری لینک شوید، وقتی که شما از طریق این لینک‌ها از سامانه ما خارج می‌شوید، توجه داشته باشید که ما بر دیگر سایت ها کنترل نداریم و سازمان تعهدی بر حفظ حریم شخصی آنان در سایت مقصد نخواهد داشت و مراجعه کنندگان میبایست به بیانیه حریم شخصی آن سایت ها مراجعه نمایند.',
style: AppFonts.yekan14.copyWith(color: AppColor.bgDark, height: 1.8), style: AppFonts.yekan14.copyWith(
color: AppColor.bgDark,
height: 1.8,
),
), ),
], ],
), ),

View File

@@ -43,6 +43,8 @@ class ProfileLogic extends GetxController {
RxBool isUserInformationOpen = true.obs; RxBool isUserInformationOpen = true.obs;
RxBool isUnitInformationOpen = false.obs; RxBool isUnitInformationOpen = false.obs;
ScrollController scrollController = ScrollController();
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
@@ -177,4 +179,79 @@ class ProfileLogic extends GetxController {
Get.offAllNamed(newRole); Get.offAllNamed(newRole);
} }
void scrollToSelectedItem(
int index, {
double chipWidth = 100,
double spacing = 8,
GlobalKey? itemKey,
}) {
if (!scrollController.hasClients) {
WidgetsBinding.instance.addPostFrameCallback((_) {
_performScroll(index, chipWidth, spacing, itemKey);
});
} else {
_performScroll(index, chipWidth, spacing, itemKey);
}
}
void _performScroll(
int index,
double chipWidth,
double spacing,
GlobalKey? itemKey,
) {
if (!scrollController.hasClients) return;
double targetOffset;
// If we have a GlobalKey, use it for precise positioning
if (itemKey?.currentContext != null) {
final RenderBox? renderBox =
itemKey!.currentContext?.findRenderObject() as RenderBox?;
if (renderBox != null) {
final position = renderBox.localToGlobal(Offset.zero);
final scrollPosition = scrollController.position;
final viewportWidth = scrollPosition.viewportDimension;
final chipWidth = renderBox.size.width;
// Get the scroll position of the item
final itemScrollPosition = position.dx - scrollPosition.pixels;
// Center the item
targetOffset =
scrollPosition.pixels +
itemScrollPosition -
(viewportWidth / 2) +
(chipWidth / 2);
} else {
// Fallback to estimated position
targetOffset = _calculateEstimatedPosition(index, chipWidth, spacing);
}
} else {
// Use estimated position
targetOffset = _calculateEstimatedPosition(index, chipWidth, spacing);
}
scrollController.animateTo(
targetOffset.clamp(0.0, scrollController.position.maxScrollExtent),
duration: const Duration(milliseconds: 300),
curve: Curves.easeInOut,
);
}
double _calculateEstimatedPosition(
int index,
double chipWidth,
double spacing,
) {
final double itemPosition = (chipWidth + spacing) * index;
final double viewportWidth = scrollController.position.viewportDimension;
return itemPosition - (viewportWidth / 2) + (chipWidth / 2);
}
@override
void onClose() {
scrollController.dispose();
super.onClose();
}
} }

View File

@@ -877,6 +877,7 @@ class ProfilePage extends GetView<ProfileLogic> {
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
padding: EdgeInsets.symmetric(horizontal: 8.w), padding: EdgeInsets.symmetric(horizontal: 8.w),
physics: BouncingScrollPhysics(), physics: BouncingScrollPhysics(),
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
spacing: 8.w, spacing: 8.w,

View File

@@ -1,5 +1,3 @@
import 'dart:math';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:rasadyar_chicken/features/common/presentation/page/auth/logic.dart'; import 'package:rasadyar_chicken/features/common/presentation/page/auth/logic.dart';
@@ -12,16 +10,17 @@ class CaptchaWidget extends GetView<CaptchaWidgetLogic> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Row( return SizedBox(
crossAxisAlignment: CrossAxisAlignment.start, height: 50.h,
child: Row(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
GestureDetector( GestureDetector(
onTap: controller.getCaptcha, onTap: controller.getCaptcha,
child: Container( child: Container(
width: 135, width: 135.w,
height: 50, height: 50.h,
alignment: Alignment.center, alignment: Alignment.center,
clipBehavior: Clip.antiAliasWithSaveLayer,
decoration: BoxDecoration( decoration: BoxDecoration(
color: AppColor.whiteNormalHover, color: AppColor.whiteNormalHover,
border: Border.all(color: Colors.grey.shade300), border: Border.all(color: Colors.grey.shade300),
@@ -30,7 +29,10 @@ class CaptchaWidget extends GetView<CaptchaWidgetLogic> {
child: controller.obx( child: controller.obx(
(state) => Text( (state) => Text(
state ?? '', state ?? '',
style: AppFonts.yekan20Bold.copyWith(color: Colors.black, letterSpacing: 2.5), style: AppFonts.yekan20Bold.copyWith(
color: Colors.black,
letterSpacing: 2.5,
),
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
onLoading: const Center( onLoading: const Center(
@@ -38,7 +40,10 @@ class CaptchaWidget extends GetView<CaptchaWidgetLogic> {
), ),
onError: (error) { onError: (error) {
return Center( return Center(
child: Text('خطا ', style: AppFonts.yekan13.copyWith(color: Colors.red)), child: Text(
'خطا ',
style: AppFonts.yekan13.copyWith(color: Colors.red),
),
); );
}, },
), ),
@@ -51,19 +56,24 @@ class CaptchaWidget extends GetView<CaptchaWidgetLogic> {
key: controller.formKey, key: controller.formKey,
autovalidateMode: AutovalidateMode.disabled, autovalidateMode: AutovalidateMode.disabled,
child: RTextField( child: RTextField(
height: 50.h,
label: 'کد امنیتی', label: 'کد امنیتی',
controller: controller.textController, controller: controller.textController,
focusedBorder: OutlineInputBorder( focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8), borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: AppColor.textColor, width: 1), borderSide: BorderSide(color: AppColor.textColor, width: 1),
), ),
keyboardType: TextInputType.numberWithOptions(decimal: false, signed: false), keyboardType: TextInputType.numberWithOptions(
decimal: false,
signed: false,
),
filled: false,
borderColor: Colors.grey.shade300,
maxLines: 1, maxLines: 1,
maxLength: 6, maxLength: 6,
suffixIcon: (controller.textController.text.trim().isNotEmpty ?? false) suffixIcon: (controller.textController.text.trim().isNotEmpty)
? clearButton(() => controller.textController.clear()) ? clearButton(() => controller.textController.clear())
: null, : null,
validator: (value) { validator: (value) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return 'کد امنیتی را وارد کنید'; return 'کد امنیتی را وارد کنید';
@@ -82,28 +92,7 @@ class CaptchaWidget extends GetView<CaptchaWidgetLogic> {
), ),
), ),
], ],
),
); );
} }
} }
class _CaptchaLinePainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
final random = Random();
final paint1 = Paint()
..color = Colors.deepOrange
..strokeWidth = 2;
final paint2 = Paint()
..color = Colors.blue
..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;
}

View File

@@ -1,6 +1,6 @@
name: rasadyar_chicken name: rasadyar_chicken
description: A starting point for Dart libraries or applications. description: A starting point for Dart libraries or applications.
version: 1.3.20 version: 1.4.0
environment: environment:
sdk: ^3.10.0 sdk: ^3.10.0

View File

@@ -3,7 +3,7 @@ import 'package:mocktail/mocktail.dart';
import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote.dart'; import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote.dart';
import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart';
import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart';
import 'package:rasadyar_chicken/data/repositories/auth/auth_repository_imp.dart'; import 'package:rasadyar_chicken/features/common/data/repositories/auth/auth_repository_imp.dart';
class MockAuthRemoteDataSource extends Mock implements AuthRemoteDataSource {} class MockAuthRemoteDataSource extends Mock implements AuthRemoteDataSource {}

View File

@@ -3,7 +3,7 @@ import 'package:mocktail/mocktail.dart';
import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote.dart'; import 'package:rasadyar_chicken/features/common/data/datasources/remote/auth/auth_remote.dart';
import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart'; import 'package:rasadyar_chicken/features/common/data/model/response/user_info/user_info_model.dart';
import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart'; import 'package:rasadyar_chicken/features/common/data/model/response/user_profile_model/user_profile_model.dart';
import 'package:rasadyar_chicken/data/repositories/auth/auth_repository_imp.dart';
class MockAuthRemoteDataSource extends Mock implements AuthRemoteDataSource {} class MockAuthRemoteDataSource extends Mock implements AuthRemoteDataSource {}

View File

@@ -2,3 +2,5 @@ description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions: extensions:
- hive_ce: true - hive_ce: true
- provider: true
- shared_preferences: true

View File

@@ -2,6 +2,7 @@ import 'package:rasadyar_core/core.dart';
part 'app_model.g.dart'; part 'app_model.g.dart';
@HiveType(typeId: appModelTypeId) @HiveType(typeId: appModelTypeId)
class AppModel extends HiveObject { class AppModel extends HiveObject {
@HiveField(0, defaultValue: true) @HiveField(0, defaultValue: true)
@@ -16,7 +17,12 @@ class AppModel extends HiveObject {
@HiveField(3) @HiveField(3)
List<TargetPage>? targetPages; List<TargetPage>? targetPages;
AppModel({this.isFirstRun, this.isDarkMode, this.selectedModule, this.targetPages}); AppModel({
this.isFirstRun,
this.isDarkMode,
this.selectedModule,
this.targetPages,
});
@override @override
String toString() { String toString() {

View File

@@ -0,0 +1,39 @@
# Generated by Hive CE
# Manual modifications may be necessary for certain migrations
# Check in to version control
nextTypeId: 3
types:
AppModel:
typeId: 0
nextIndex: 4
fields:
isFirstRun:
index: 0
isDarkMode:
index: 1
selectedModule:
index: 2
targetPages:
index: 3
TargetPage:
typeId: 1
nextIndex: 4
fields:
route:
index: 0
functions:
index: 1
module:
index: 2
selectedRole:
index: 3
Module:
typeId: 2
nextIndex: 3
fields:
liveStocks:
index: 0
inspection:
index: 1
chicken:
index: 2

View File

@@ -0,0 +1,15 @@
import 'package:hive_ce_flutter/hive_flutter.dart';
import 'package:rasadyar_core/data/model/local/app_model/app_model.dart';
import 'package:rasadyar_core/data/model/local/user_local/user_local_model.dart';
@GenerateAdapters([
AdapterSpec<AppModel>(),
AdapterSpec<TargetPage>(),
AdapterSpec<UserLocalModel>(),
AdapterSpec<Module>(),
])
part 'hive_adapters.g.dart';

View File

@@ -0,0 +1,185 @@
// GENERATED CODE - DO NOT MODIFY BY HAND
part of 'hive_adapters.dart';
// **************************************************************************
// AdaptersGenerator
// **************************************************************************
class AppModelAdapter extends TypeAdapter<AppModel> {
@override
final typeId = 0;
@override
AppModel read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return AppModel(
isFirstRun: fields[0] == null ? true : fields[0] as bool?,
isDarkMode: fields[1] as bool?,
selectedModule: fields[2] as Module?,
targetPages: (fields[3] as List?)?.cast<TargetPage>(),
);
}
@override
void write(BinaryWriter writer, AppModel obj) {
writer
..writeByte(4)
..writeByte(0)
..write(obj.isFirstRun)
..writeByte(1)
..write(obj.isDarkMode)
..writeByte(2)
..write(obj.selectedModule)
..writeByte(3)
..write(obj.targetPages);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AppModelAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class TargetPageAdapter extends TypeAdapter<TargetPage> {
@override
final typeId = 1;
@override
TargetPage read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return TargetPage(
route: fields[0] as String?,
functions: (fields[1] as List?)?.cast<String>(),
module: fields[2] as Module?,
)..selectedRole = fields[3] as String?;
}
@override
void write(BinaryWriter writer, TargetPage obj) {
writer
..writeByte(4)
..writeByte(0)
..write(obj.route)
..writeByte(1)
..write(obj.functions)
..writeByte(2)
..write(obj.module)
..writeByte(3)
..write(obj.selectedRole);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is TargetPageAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class UserLocalModelAdapter extends TypeAdapter<UserLocalModel> {
@override
final typeId = 2;
@override
UserLocalModel read(BinaryReader reader) {
final numOfFields = reader.readByte();
final fields = <int, dynamic>{
for (int i = 0; i < numOfFields; i++) reader.readByte(): reader.read(),
};
return UserLocalModel(
username: fields[0] as String?,
password: fields[1] as String?,
token: fields[2] as String?,
refreshToken: fields[3] as String?,
module: fields[4] as Module?,
backend: fields[5] as String?,
roles: (fields[6] as List?)?.cast<String>(),
);
}
@override
void write(BinaryWriter writer, UserLocalModel obj) {
writer
..writeByte(7)
..writeByte(0)
..write(obj.username)
..writeByte(1)
..write(obj.password)
..writeByte(2)
..write(obj.token)
..writeByte(3)
..write(obj.refreshToken)
..writeByte(4)
..write(obj.module)
..writeByte(5)
..write(obj.backend)
..writeByte(6)
..write(obj.roles);
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is UserLocalModelAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}
class ModuleAdapter extends TypeAdapter<Module> {
@override
final typeId = 3;
@override
Module read(BinaryReader reader) {
switch (reader.readByte()) {
case 0:
return Module.liveStocks;
case 1:
return Module.inspection;
case 2:
return Module.chicken;
default:
return Module.liveStocks;
}
}
@override
void write(BinaryWriter writer, Module obj) {
switch (obj) {
case Module.liveStocks:
writer.writeByte(0);
case Module.inspection:
writer.writeByte(1);
case Module.chicken:
writer.writeByte(2);
}
}
@override
int get hashCode => typeId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ModuleAdapter &&
runtimeType == other.runtimeType &&
typeId == other.typeId;
}

View File

@@ -0,0 +1,57 @@
# Generated by Hive CE
# Manual modifications may be necessary for certain migrations
# Check in to version control
nextTypeId: 4
types:
AppModel:
typeId: 0
nextIndex: 4
fields:
isFirstRun:
index: 0
isDarkMode:
index: 1
selectedModule:
index: 2
targetPages:
index: 3
TargetPage:
typeId: 1
nextIndex: 4
fields:
route:
index: 0
functions:
index: 1
module:
index: 2
selectedRole:
index: 3
UserLocalModel:
typeId: 2
nextIndex: 7
fields:
username:
index: 0
password:
index: 1
token:
index: 2
refreshToken:
index: 3
module:
index: 4
backend:
index: 5
roles:
index: 6
Module:
typeId: 3
nextIndex: 3
fields:
liveStocks:
index: 0
inspection:
index: 1
chicken:
index: 2

View File

@@ -9,8 +9,11 @@ import 'package:rasadyar_core/data/model/local/user_local/user_local_model.dart'
extension HiveRegistrar on HiveInterface { extension HiveRegistrar on HiveInterface {
void registerAdapters() { void registerAdapters() {
registerAdapter(AppModelAdapter()); registerAdapter(AppModelAdapter());
registerAdapter(ModuleAdapter()); registerAdapter(ModuleAdapter());
registerAdapter(TargetPageAdapter()); registerAdapter(TargetPageAdapter());
registerAdapter(UserLocalModelAdapter()); registerAdapter(UserLocalModelAdapter());
} }
} }
@@ -18,8 +21,12 @@ extension HiveRegistrar on HiveInterface {
extension IsolatedHiveRegistrar on IsolatedHiveInterface { extension IsolatedHiveRegistrar on IsolatedHiveInterface {
void registerAdapters() { void registerAdapters() {
registerAdapter(AppModelAdapter()); registerAdapter(AppModelAdapter());
registerAdapter(AppModelAdapter());
registerAdapter(ModuleAdapter());
registerAdapter(ModuleAdapter()); registerAdapter(ModuleAdapter());
registerAdapter(TargetPageAdapter()); registerAdapter(TargetPageAdapter());
registerAdapter(TargetPageAdapter());
registerAdapter(UserLocalModelAdapter());
registerAdapter(UserLocalModelAdapter()); registerAdapter(UserLocalModelAdapter());
} }
} }

View File

@@ -2,6 +2,8 @@ import 'package:rasadyar_core/core.dart';
part 'user_local_model.g.dart'; part 'user_local_model.g.dart';
@HiveType(typeId: authUserLocalModelTypeId) @HiveType(typeId: authUserLocalModelTypeId)
class UserLocalModel extends HiveObject { class UserLocalModel extends HiveObject {
@HiveField(0) @HiveField(0)

View File

@@ -0,0 +1,23 @@
# Generated by Hive CE
# Manual modifications may be necessary for certain migrations
# Check in to version control
nextTypeId: 1
types:
UserLocalModel:
typeId: 0
nextIndex: 7
fields:
username:
index: 0
password:
index: 1
token:
index: 2
refreshToken:
index: 3
module:
index: 4
backend:
index: 5
roles:
index: 6

View File

@@ -1,5 +1,6 @@
import 'package:rasadyar_core/core.dart'; import 'package:rasadyar_core/core.dart';
import 'package:rasadyar_core/hive_registrar.g.dart'; import 'package:rasadyar_core/data/model/local/hive_registrar.g.dart';
class GService extends GetxService { class GService extends GetxService {
final String _boxName = "appBox"; final String _boxName = "appBox";
@@ -42,14 +43,18 @@ class GService extends GetxService {
if (isFirstTime()) { if (isFirstTime()) {
return null; return null;
} }
var res = box.values.first.targetPages?.firstWhereOrNull((element) => element.module == module); var res = box.values.first.targetPages?.firstWhereOrNull(
(element) => element.module == module,
);
return res; return res;
} }
Future<void> saveRoute(Module module, String route) async { Future<void> saveRoute(Module module, String route) async {
AppModel model = box.values.first; AppModel model = box.values.first;
TargetPage? targetPage = model.targetPages?.firstWhere((element) => element.module == module); TargetPage? targetPage = model.targetPages?.firstWhere(
(element) => element.module == module,
);
if (targetPage != null) { if (targetPage != null) {
targetPage.route = route; targetPage.route = route;
model.save(); model.save();
@@ -62,7 +67,9 @@ class GService extends GetxService {
Future<void> saveRole(Module module, String role) async { Future<void> saveRole(Module module, String role) async {
AppModel model = box.values.first; AppModel model = box.values.first;
TargetPage? targetPage = model.targetPages?.firstWhere((element) => element.module == module); TargetPage? targetPage = model.targetPages?.firstWhere(
(element) => element.module == module,
);
if (targetPage != null) { if (targetPage != null) {
targetPage.selectedRole = role; targetPage.selectedRole = role;
model.save(); model.save();

View File

@@ -201,8 +201,8 @@ class _RTextFieldState extends State<RTextField> {
child: Padding( child: Padding(
padding: widget.padding ?? EdgeInsets.zero, padding: widget.padding ?? EdgeInsets.zero,
child: TextFormField( child: TextFormField(
textAlignVertical: TextAlignVertical.center,
controller: widget.controller, controller: widget.controller,
focusNode: widget.focusNode, focusNode: widget.focusNode,
textAlign: widget.textAlign ?? TextAlign.start, textAlign: widget.textAlign ?? TextAlign.start,
readOnly: widget.readonly, readOnly: widget.readonly,
@@ -229,8 +229,12 @@ class _RTextFieldState extends State<RTextField> {
textInputAction: widget.textInputAction, textInputAction: widget.textInputAction,
autofillHints: widget.autofillHints, autofillHints: widget.autofillHints,
decoration: InputDecoration( decoration: InputDecoration(
contentPadding: const EdgeInsets.symmetric(horizontal: 16), contentPadding: EdgeInsets.symmetric(
horizontal: 16,
vertical: widget.height / 3,
),
errorStyle: widget.errorStyle, errorStyle: widget.errorStyle,
errorMaxLines: 1, errorMaxLines: 1,
isDense: widget.isDense, isDense: widget.isDense,
suffix: widget.suffix, suffix: widget.suffix,

View File

@@ -93,7 +93,7 @@ dependencies:
json_annotation: ^4.9.0 json_annotation: ^4.9.0
dependency_overrides: dependency_overrides:
analyzer: ^8.0.0 # Ensures analyzer ^8.0.0 is used despite other conflicts analyzer: ^8.0.0
dev_dependencies: dev_dependencies:

View File

@@ -2,3 +2,5 @@ description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions: extensions:
- hive_ce: true - hive_ce: true
- provider: true
- shared_preferences: true

View File

@@ -2,3 +2,5 @@ description: This file stores settings for Dart & Flutter DevTools.
documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
extensions: extensions:
- hive_ce: true - hive_ce: true
- provider: true
- shared_preferences: true

View File

@@ -1354,7 +1354,7 @@ packages:
path: "packages/chicken" path: "packages/chicken"
relative: true relative: true
source: path source: path
version: "1.3.20" version: "1.4.0"
rasadyar_core: rasadyar_core:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@@ -1,10 +1,10 @@
name: rasadyar_app name: rasadyar_app
description: "A new Flutter project." description: "A new Flutter project."
publish_to: 'none' publish_to: "none"
version: 1.3.36+32 version: 1.3.36+32
environment: environment:
sdk: ^3.9.2 sdk: ^3.10.0
dependencies: dependencies:
flutter: flutter:
@@ -26,7 +26,6 @@ dependencies:
rasadyar_chicken: rasadyar_chicken:
path: ./packages/chicken path: ./packages/chicken
##code generation ##code generation
freezed_annotation: ^3.1.0 freezed_annotation: ^3.1.0
json_annotation: ^4.9.0 json_annotation: ^4.9.0
@@ -48,13 +47,9 @@ dev_dependencies:
mocktail: ^1.0.4 mocktail: ^1.0.4
get_test: ^4.0.1 get_test: ^4.0.1
flutter: flutter:
uses-material-design: true uses-material-design: true
assets: assets:
- assets/icons/ - assets/icons/
- assets/images/ - assets/images/
@@ -62,13 +57,11 @@ flutter:
- assets/vec/ - assets/vec/
- assets/anim/ - assets/anim/
fonts: fonts:
- family: yekan - family: yekan
fonts: fonts:
- asset: fonts/iranyekanregularfanum.ttf - asset: fonts/iranyekanregularfanum.ttf
flutter_gen: flutter_gen:
output: packages/core/lib/presentation/common output: packages/core/lib/presentation/common
line_length: 120 line_length: 120
@@ -77,4 +70,3 @@ flutter_gen:
image: true image: true
flutter_svg: true flutter_svg: true
lottie: true lottie: true