feat: add step 5 page and update active stepper logic in poultry farm inspection

doc: some utils in core
This commit is contained in:
2025-11-22 14:12:21 +03:30
parent a47263d98e
commit 6be57e058c
20 changed files with 168 additions and 51 deletions

View File

@@ -73,5 +73,5 @@ export 'utils/logger_utils.dart';
export 'utils/map_utils.dart';
export 'utils/network/network.dart';
export 'utils/route_utils.dart';
export 'utils/separator_input_formatter.dart';
export 'utils/text_input_formatter/separator_input_formatter.dart';
export 'utils/utils.dart';

View File

@@ -4,6 +4,11 @@ import 'package:dio/dio.dart';
import 'package:flutter/services.dart';
import 'package:path_provider/path_provider.dart';
/// A class that allows you to download and install an APK file.
/// Example:
/// ```dart
/// await ApkUpdater.downloadAndInstall();
/// ```
class ApkUpdater {
static const _channel = MethodChannel('apk_installer');
@@ -13,7 +18,6 @@ class ApkUpdater {
final dir = await getExternalStorageDirectory();
final path = "${dir!.path}/update.apk";
final file = File(path);
await dio.download(apkUrl, path);

View File

@@ -1,5 +1,10 @@
import 'package:rasadyar_core/core.dart';
/// Pick a camera image.
/// Example:
/// ```dart
/// await pickCameraImage();
/// ```
Future<XFile?> pickCameraImage({
double? maxWidth,
double? maxHeight,
@@ -21,6 +26,11 @@ Future<XFile?> pickCameraImage({
return tmpImage;
}
/// Pick a gallery image.
/// Example:
/// ```dart
/// await pickGalleryImage();
/// ```
Future<XFile?> pickGalleryImage({
double? maxWidth,
double? maxHeight,

View File

@@ -2,12 +2,16 @@ import 'package:intl/intl.dart';
import 'package:persian_datetime_picker/persian_datetime_picker.dart';
extension XDateTime2 on DateTime {
get formattedJalaliDate {
/// Convert the date time to a Jalali date.
/// Example: DateTime(2025, 1, 1) -> '1404/01/01'
String get formattedJalaliDate {
final jalaliDate = Jalali.fromDateTime(this);
return "${jalaliDate.year}/${jalaliDate.month.toString().padLeft(2, '0')}/${jalaliDate.day.toString().padLeft(2, '0')}";
}
get formattedYHMS {
/// Convert the date time to a YHMS date.
/// Example: DateTime(2025, 1, 1) -> '2025-01-01 00:00:00'
String get formattedYHMS {
return DateFormat('yyyy-MM-dd HH:mm:ss').format(this);
}
}

View File

@@ -1,14 +1,17 @@
import 'package:intl/intl.dart';
extension XNumExtension on num? {
/// Convert the number to a string with comma separator.
/// Example: 1000 -> '۱,۰۰۰'
String get separatedByCommaFa {
final formatter = NumberFormat('#,###', 'fa_IR');
return this == null ? '':formatter.format(this);
return this == null ? '' : formatter.format(this);
}
/// Convert the number to a string with comma separator.
/// Example: 1000 -> '1,000'
String get separatedByComma {
final formatter = NumberFormat('#,###', 'en_US');
return this == null ? '':formatter.format(this);
return this == null ? '' : formatter.format(this);
}
}

View File

@@ -2,49 +2,92 @@ import 'package:intl/intl.dart';
import 'package:persian_datetime_picker/persian_datetime_picker.dart';
extension XString on String? {
/// Convert the string to a number with comma separator.
/// Example: '1000' -> '1,000'
/// Example: '1000000' -> '1,000,000'
/// Example: '1000000000' -> '1,000,000,000'
String get separatedByComma {
final formatter = NumberFormat('#,###');
final number = num.tryParse(this ?? '');
return number != null ? formatter.format(number) : (this ?? '');
}
/// Clear the comma from the string.
/// Example: '1,000' -> '1000'
/// Example: '1,000,000' -> '1000000'
/// Example: '1,000,000,000' -> '1000000000'
String get clearComma {
return (this ?? '').replaceAll(RegExp(r'\D'), '');
}
/// Add the count extension to the string.
/// Example: '1' -> '1 قطعه'
/// Example: '10' -> '10 قطعه'
/// Example: '100' -> '100 قطعه'
String get addCountEXT {
return '$this قطعه';
}
/// Add the day extension to the string.
/// Example: '1' -> '1 روزه'
/// Example: '10' -> '10 روزه'
/// Example: '100' -> '100 روزه'
String get addDayEXT {
return '$thisروزه';
}
/// Add the kg extension to the string.
/// Example: '1' -> '1 کیلوگرم'
/// Example: '10' -> '10 کیلوگرم'
/// Example: '100' -> '100 کیلوگرم'
String get addKgFa {
return '${this ?? 0}کیلوگرم ';
}
/// Add the kg extension to the string.
/// Example: '1' -> '1 کیلوگرم'
/// Example: '10' -> '10 کیلوگرم'
/// Example: '100' -> '100 کیلوگرم'
String get addKgFaWithParentheses {
return '${this ?? 0} (کیلوگرم)';
}
/// Add the kg extension to the string.
/// Example: '1' -> '1 KG'
/// Example: '10' -> '10 KG'
/// Example: '100' -> '100 KG'
String get addKg {
return '$this KG';
}
/// Add the real extension to the string.
/// Example: '1' -> '1 ریال'
/// Example: '10' -> '10 ریال'
/// Example: '100' -> '100 ریال'
String get addReal {
return ' $this ریال';
}
/// Convert the string to a DateTime.
/// Example: '2025-01-01' -> DateTime(2025, 1, 1)
/// Example: '2025-01-01 12:00:00' -> DateTime(2025, 1, 1, 12, 0, 0)
DateTime get toDateTime => DateTime.parse(this ?? '');
/// Convert the string to a Jalali date.
/// Example: '2025/01/01' -> '1404-01-01'
/// Example: '2025-01-01' -> '1404-01-01'
/// Example: '2025-01-01 12:00:00' -> '1404-01-01 12:00:00'
String get formattedJalaliDate {
String tmp = (this != null && this!.contains("/")) ? this!.replaceAll("/", "-") : (this ?? "");
String tmp = (this != null && this!.contains("/"))
? this!.replaceAll("/", "-")
: (this ?? "");
final dateTime = DateTime.parse(tmp);
final jalaliDate = Jalali.fromDateTime(dateTime);
return "${jalaliDate.year}/${jalaliDate.month.toString().padLeft(2, '0')}/${jalaliDate.day.toString().padLeft(2, '0')}";
}
/// Convert the string to a Jalali date and time.
/// Example: '2025-01-01 12:00:00' -> Jalali(year: 1404, month: 1, day: 1, hour: 12, minute: 0, second: 0)
String get formattedJalaliDateYHMS {
final dateTime = DateTime.parse(this ?? '');
final jalaliDate = Jalali.fromDateTime(dateTime);
@@ -55,15 +98,35 @@ extension XString on String? {
return DateFormat('yyyy-MM-dd HH:mm:ss').format(toDateTime);
}
/// Convert the string to a Jalali date.
/// Example: '2025-01-01' -> Jalali(year: 1404, month: 1, day: 1)
/// Example: '2025-01-01 12:00:00' -> Jalali(year: 1404, month: 1, day: 1, hour: 12, minute: 0, second: 0)
Jalali get toJalali {
final dateTime = DateTime.parse(this ?? '');
return Jalali.fromDateTime(dateTime);
}
/// Get the version number from the string.
/// Example: '1.0.0' -> 100
/// Example: '1.0.0.0' -> 1000
int get versionNumber => int.parse(this?.replaceAll(".", '') ?? '0');
/// Check if the string is a valid version number.
/// Example: '۹' -> true
/// Example: '۱۲۳۴۵۶۷۸۹۰' -> true
/// Example: '1234567890' -> false
bool get isDifferentDigits {
final regex = RegExp(r'[۰-۹٠-٩]');
return regex.hasMatch(this ?? '');
}
/// Normalize the string to remove extra spaces and convert to lowercase.
/// Example: " Hello World " -> "hello world"
/// Example: "Hello World" -> "hello world"
/// Example: "hello world" -> "hello world"
/// Example: "HELLO WORLD" -> "hello world"
/// Example: "Hello World" -> "hello world"
/// Example: "Hello World" -> "hello world"
String? get normalize =>
this?.toLowerCase().trim().replaceAll(RegExp(r'\s+'), ' ');
}

View File

@@ -2,9 +2,16 @@ import 'dart:io';
import 'logger_utils.dart';
/// Get the file size in KB.
/// Example:
/// ```dart
/// getFileSizeInKB('path/to/file.jpg');
/// ```
void getFileSizeInKB(String filePath, {String? tag}) {
final file = File(filePath);
final bytes = file.lengthSync();
var size = (bytes / 1024).ceil();
iLog('${tag ?? 'Picked'} image Size: $size , fileName : ${file.path.split('/').last}');
}
iLog(
'${tag ?? 'Picked'} image Size: $size , fileName : ${file.path.split('/').last}',
);
}

View File

@@ -1,5 +1,6 @@
import 'package:rasadyar_core/presentation/utils/data_time_utils.dart';
/// Build a query params map.
Map<String, dynamic> buildQueryParams({
Map<String, dynamic>? queryParams,
String? search,
@@ -49,6 +50,7 @@ Map<String, dynamic> buildQueryParams({
return params;
}
/// Build a raw query params map.
Map<String, dynamic>? buildRawQueryParams({
Map<String, dynamic>? queryParams,
String? search,
@@ -101,20 +103,21 @@ Map<String, dynamic>? buildRawQueryParams({
}
if (centerLat != null) {
params['center_lat'] = centerLat ?? '';
params['center_lat'] = centerLat;
}
if (centerLng != null) {
params['center_lon'] = centerLng ?? '';
params['center_lon'] = centerLng;
}
if (radius != null) {
params['radius'] = radius ?? '';
params['radius'] = radius;
}
return params.keys.isEmpty ? null : params;
}
/// A map of English digits to Persian digits.
const Map<String, String> digitMap = {
'۰': '0',
'۱': '1',

View File

@@ -2,12 +2,12 @@ import 'dart:math';
final _random = Random();
/// Generate a random integer between min and max.
int randomInt(int min, int max) {
return min + _random.nextInt(max - min + 1);
}
/// Generate a random double between min and max.
double randomDouble(double min, double max) {
return min + _random.nextDouble() * (max - min);
}

View File

@@ -1,5 +1,10 @@
import 'package:flutter/foundation.dart';
/// Parse a list in isolate.
/// Example:
/// ```dart
/// await parseListInIsolate<T>(list, fromJson);
/// ```
List<T> _parserList<T>(Map<String, dynamic> args) {
final list = args['list'] as List<dynamic>;
final T Function(Map<String, dynamic>) fromJson =
@@ -8,6 +13,11 @@ List<T> _parserList<T>(Map<String, dynamic> args) {
return list.map<T>((e) => fromJson(e as Map<String, dynamic>)).toList();
}
/// Parse a list in isolate.
/// Example:
/// ```dart
/// await parseListInIsolate<T>(list, fromJson);
/// ```
Future<List<T>> parseListInIsolate<T>(
List<dynamic> list,
T Function(Map<String, dynamic>) fromJson,

View File

@@ -1,27 +0,0 @@
import 'package:flutter/services.dart';
import 'package:intl/intl.dart';
class SeparatorInputFormatter extends TextInputFormatter {
final NumberFormat _formatter;
SeparatorInputFormatter() : _formatter = NumberFormat('#,###');
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
if (newValue.text.isEmpty) {
return newValue;
}
String tmpText = newValue.text;
String cleanedText = tmpText.replaceAll(RegExp(r'\D'), '');
int? number = int.tryParse(cleanedText);
if (number == null) {
return oldValue;
}
String formattedText = _formatter.format(number);
int selectionIndex = formattedText.length;
return TextEditingValue(
text: formattedText,
selection: TextSelection.collapsed(offset: selectionIndex),
);
}
}

View File

@@ -1,8 +1,14 @@
import 'package:flutter/services.dart';
/// A text input formatter that allows only one decimal point and one digit before the decimal point.
/// Example: '1234567890' -> '1234567890'
/// Example: '1234567890.1234567890' -> '1234567890.1'
class FirstDigitDecimalFormatter extends TextInputFormatter {
@override
TextEditingValue formatEditUpdate(TextEditingValue oldValue, TextEditingValue newValue) {
TextEditingValue formatEditUpdate(
TextEditingValue oldValue,
TextEditingValue newValue,
) {
String digit = newValue.text.replaceAll(RegExp(r'[^0-9]'), "");
late String res;

View File

@@ -2,6 +2,11 @@ import 'package:flutter/services.dart';
import '../map_utils.dart';
/// A text input formatter that converts English digits to Persian digits.
/// Example: '1234567890' -> '۱۲۳۴۵۶۷۸۹۰'
/// Example: '۱۲۳۴۵۶۷۸۹۰' -> '۱۲۳۴۵۶۷۸۹۰'
/// Example: '1234567890.1234567890' -> '۱۲۳۴۵۶۷۸۹۰.۱۲۳۴۵۶۷۸۹۰'
/// Example: '۱۲۳۴۵۶۷۸۹۰.۱۲۳۴۵۶۷۸۹۰' -> '۱۲۳۴۵۶۷۸۹۰.۱۲۳۴۵۶۷۸۹۰'
class PersianFormatter extends TextInputFormatter {
String _convert(String input) {
final buffer = StringBuffer();

View File

@@ -13,6 +13,6 @@ export 'network/network.dart';
export 'number_utils.dart';
export 'parser.dart';
export 'route_utils.dart';
export 'separator_input_formatter.dart';
export 'text_input_formatter/separator_input_formatter.dart';
export 'text_input_formatter/first_digit_decimal_formatter.dart';
export 'text_input_formatter/persian_formatter.dart';