feat : map

This commit is contained in:
2025-04-09 17:05:38 +03:30
parent e83388670c
commit 0286725ac6
41 changed files with 1120 additions and 91 deletions

View File

@@ -1,4 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:label="rasadyar_app"
android:name="${applicationName}"

View File

@@ -0,0 +1 @@
<svg id="Capa_1" enable-background="new 0 0 512 512" height="512" viewBox="0 0 512 512" width="512" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="212.562" x2="256.62" y1="372.319" y2="372.319"><stop offset="0" stop-color="#a996eb"/><stop offset="1" stop-color="#d7d1eb"/></linearGradient><linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="263.927" x2="230.973" y1="227.163" y2="272.151"><stop offset="0" stop-color="#7662bd"/><stop offset="1" stop-color="#7662bd" stop-opacity="0"/></linearGradient><radialGradient id="SVGID_3_" cx="258.197" cy="91.638" gradientUnits="userSpaceOnUse" r="125.028"><stop offset="0" stop-color="#ff4757"/><stop offset="1" stop-color="#ab2c37"/></radialGradient><radialGradient id="SVGID_4_" cx="298.176" cy="59.42" gradientUnits="userSpaceOnUse" r="125.028"><stop offset="0" stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></radialGradient><g><path d="m219.855 232.637 28.848 272.797c.926 8.755 13.668 8.755 14.594 0l28.848-272.797z" fill="url(#SVGID_1_)"/><path d="m292.145 232.637h-72.291l2.913 27.54c36.405-3.856 68.056-15.04 68.056-15.04z" fill="url(#SVGID_2_)"/><g><circle cx="256" cy="125.028" fill="url(#SVGID_3_)" r="125.028"/><circle cx="256" cy="125.028" fill="url(#SVGID_4_)" opacity=".5" r="125.028"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,109 @@
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:latlong2/latlong.dart';
class ClusterParams {
final List<LatLng> points;
final double clusterRadiusMeters;
ClusterParams({
required this.points,
required this.clusterRadiusMeters,
});
}
class Cluster {
final LatLng center;
final List<LatLng> members;
Cluster(this.center, this.members);
}
// Use a more efficient quadtree-based clustering algorithm
Future<List<Cluster>> clusterMarkersQuadtreeIsolate(ClusterParams params) async {
return compute(_clusterMarkersQuadtree, params);
}
List<Cluster> _clusterMarkersQuadtree(ClusterParams params) {
final points = params.points;
final radius = params.clusterRadiusMeters;
final distance = const Distance();
final List<Cluster> clusters = [];
// Skip clustering if we have a small number of points
if (points.length < 100) {
return points.map((p) => Cluster(p, [p])).toList();
}
// Find bounds
double minLat = points[0].latitude;
double maxLat = points[0].latitude;
double minLng = points[0].longitude;
double maxLng = points[0].longitude;
for (final point in points) {
minLat = min(minLat, point.latitude);
maxLat = max(maxLat, point.latitude);
minLng = min(minLng, point.longitude);
maxLng = max(maxLng, point.longitude);
}
// Build spatial grid for faster lookups (simple spatial index)
// Convert geographic distance to approximate degrees
final double radiusDegLat = radius / 111000; // ~111km per degree latitude
final double radiusDegLng = radius / (111000 * cos(minLat * pi / 180)); // Adjust for longitude
final int gridLatSize = ((maxLat - minLat) / radiusDegLat).ceil();
final int gridLngSize = ((maxLng - minLng) / radiusDegLng).ceil();
// Create spatial grid
final List<List<List<LatLng>>> grid = List.generate(
gridLatSize + 1,
(_) => List.generate(gridLngSize + 1, (_) => <LatLng>[])
);
// Add points to grid cells
for (final point in points) {
final int latIdx = ((point.latitude - minLat) / radiusDegLat).floor();
final int lngIdx = ((point.longitude - minLng) / radiusDegLng).floor();
grid[latIdx][lngIdx].add(point);
}
// Process grid cells in batches
final Set<LatLng> processed = {};
for (int latIdx = 0; latIdx < gridLatSize; latIdx++) {
for (int lngIdx = 0; lngIdx < gridLngSize; lngIdx++) {
final cellPoints = grid[latIdx][lngIdx];
for (final point in cellPoints) {
if (processed.contains(point)) continue;
// Find nearby points
final List<LatLng> neighbors = [];
neighbors.add(point);
processed.add(point);
// Check current and adjacent cells for neighbors
for (int adjLat = max(0, latIdx - 1); adjLat <= min(gridLatSize - 1, latIdx + 1); adjLat++) {
for (int adjLng = max(0, lngIdx - 1); adjLng <= min(gridLngSize - 1, lngIdx + 1); adjLng++) {
for (final neighbor in grid[adjLat][adjLng]) {
if (!processed.contains(neighbor) && distance(point, neighbor) <= radius) {
neighbors.add(neighbor);
processed.add(neighbor);
}
}
}
}
// Calculate cluster center
if (neighbors.isNotEmpty) {
final avgLat = neighbors.map((p) => p.latitude).reduce((a, b) => a + b) / neighbors.length;
final avgLng = neighbors.map((p) => p.longitude).reduce((a, b) => a + b) / neighbors.length;
clusters.add(Cluster(LatLng(avgLat, avgLng), neighbors));
}
}
}
}
return clusters;
}

View File

@@ -0,0 +1,57 @@
import 'dart:math';
import 'package:flutter/foundation.dart';
import 'package:latlong2/latlong.dart';
class GridGenParams {
final LatLng center;
final int count;
final double spacingMeters;
const GridGenParams({
required this.center,
required this.count,
required this.spacingMeters,
});
}Future<List<LatLng>> generateGridMarkersIsolate(GridGenParams params) async {
return compute(_generateGridMarkersOptimized, params);
}
List<LatLng> _generateGridMarkersOptimized(GridGenParams params) {
final List<LatLng> result = [];
final Distance distance = const Distance();
// Pre-calculate the grid dimensions
final int gridSize = sqrt(params.count).ceil();
final double halfWidth = (gridSize * params.spacingMeters) / 2;
final double halfHeight = (gridSize * params.spacingMeters) / 2;
// Calculate top-left corner of the grid
final LatLng topLeft = distance.offset(
distance.offset(params.center, -halfHeight, 0), // south
-halfWidth, 270 // west
);
// Generate grid in batches for better memory management
const int batchSize = 10000;
for (int batch = 0; batch < (params.count / batchSize).ceil(); batch++) {
final int startIdx = batch * batchSize;
final int endIdx = min((batch + 1) * batchSize, params.count);
for (int i = startIdx; i < endIdx; i++) {
final int row = i ~/ gridSize;
final int col = i % gridSize;
final double dx = col * params.spacingMeters;
final double dy = row * params.spacingMeters;
final LatLng point = distance.offset(
distance.offset(topLeft, dy, 180), // south
dx, 90 // east
);
result.add(point);
}
}
return result.sublist(0, min(result.length, params.count));
}

View File

@@ -0,0 +1,16 @@
import 'package:rasadyar_core/core.dart';
import 'package:supervision/presentation/filter/logic.dart';
import 'package:supervision/presentation/filter/view.dart';
import 'package:supervision/presentation/routes/app_routes.dart';
sealed class SupervisionPages {
SupervisionPages._();
static final pages = [
GetPage(
name: SupervisionRoutes.supervision,
page: () => SupervisionFilterPage(),
binding: BindingsBuilder.put(() => BazresiLogic()),
),
];
}

View File

@@ -0,0 +1,7 @@
sealed class SupervisionRoutes {
SupervisionRoutes._();
static const supervision = '/supervision';
}

View File

@@ -0,0 +1,59 @@
import 'package:flutter/material.dart';
class AnimatedClusterMarker extends StatefulWidget {
final int count;
const AnimatedClusterMarker({super.key, required this.count});
@override
State<AnimatedClusterMarker> createState() => _AnimatedClusterMarkerState();
}
class _AnimatedClusterMarkerState extends State<AnimatedClusterMarker>
with SingleTickerProviderStateMixin {
late AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: const Duration(milliseconds: 300),
)..forward(); // start animation
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ScaleTransition(
scale: CurvedAnimation(parent: _controller, curve: Curves.easeOutBack),
child: Opacity(
opacity: _controller.value,
child: Container(
width: 40,
height: 40,
alignment: Alignment.center,
decoration: BoxDecoration(
color: Colors.blueAccent,
shape: BoxShape.circle,
border: Border.all(color: Colors.white, width: 2),
),
child: Text(
widget.count.toString(),
style: const TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
),
),
);
}
}

View File

@@ -0,0 +1,7 @@
library;
export 'presentation/filter/logic.dart';
export 'presentation/filter/view.dart';
export 'presentation/routes/app_pages.dart';
export 'presentation/routes/app_routes.dart';

View File

@@ -0,0 +1,17 @@
name: supervision
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0
environment:
sdk: ^3.7.0
dependencies:
flutter:
sdk: flutter
rasadyar_core:
path: ./../../packages/core
flutter_map: ^8.1.1
location: ^8.0.0
latlong2: ^0.9.1
geolocator: ^13.0.4

View File

@@ -0,0 +1,3 @@
# 0.1.0+1
- TODO: Describe initial release.

View File

@@ -0,0 +1 @@
Hello moji

View File

@@ -0,0 +1 @@
TODO: Add your license here.

View File

@@ -0,0 +1,27 @@
# flutter_ddd_module
[![Powered by Mason](https://img.shields.io/endpoint?url=https%3A%2F%2Ftinyurl.com%2Fmason-badge)](https://github.com/felangel/mason)
A new brick created with the Mason CLI.
_Generated by [mason][1] 🧱_
## Getting Started 🚀
This is a starting point for a new brick.
A few resources to get you started if this is your first brick template:
- [Official Mason Documentation][2]
- [Code generation with Mason Blog][3]
- [Very Good Livestream: Felix Angelov Demos Mason][4]
- [Flutter Package of the Week: Mason][5]
- [Observable Flutter: Building a Mason brick][6]
- [Meet Mason: Flutter Vikings 2022][7]
[1]: https://github.com/felangel/mason
[2]: https://docs.brickhub.dev
[3]: https://verygood.ventures/blog/code-generation-with-mason
[4]: https://youtu.be/G4PTjA6tpTU
[5]: https://youtu.be/qjA0JFiPMnQ
[6]: https://youtu.be/o8B1EfcUisw
[7]: https://youtu.be/LXhgiF5HiQg

View File

@@ -0,0 +1 @@
Hello {{name}}!

View File

@@ -0,0 +1,20 @@
name: {{feature_name}}
description: {{feature_name}} feature module
version: 0.0.1
publish_to: 'none'
environment:
sdk: '>=3.0.0 <4.0.0'
flutter: ">=3.10.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
flutter:
uses-material-design: true

View File

@@ -0,0 +1,33 @@
name: flutter_ddd_module
description: A new brick created with the Mason CLI.
# The following defines the brick repository url.
# Uncomment and update the following line before publishing the brick.
# repository: https://github.com/my_org/my_repo
# The following defines the version and build number for your brick.
# A version number is three numbers separated by dots, like 1.2.34
# followed by an optional build number (separated by a +).
version: 0.1.0+1
# The following defines the environment for the current brick.
# It includes the version of mason that the brick requires.
environment:
mason: ^0.1.1
# Variables specify dynamic values that your brick depends on.
# Zero or more variables can be specified for a given brick.
# Each variable has:
# * a type (string, number, boolean, enum, array, or list)
# * an optional short description
# * an optional default value
# * an optional list of default values (array only)
# * an optional prompt phrase used when asking for the variable
# * a list of values (enums only)
# * an optional separator (list only)
vars:
name:
type: string
description: Your name
default: Dash
prompt: What is your name?

View File

@@ -0,0 +1,20 @@
name:
description: feature module
version: 0.0.1
publish_to: 'none'
environment:
sdk: '>=3.0.0 <4.0.0'
flutter: ">=3.10.0"
dependencies:
flutter:
sdk: flutter
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
flutter:
uses-material-design: true

View File

@@ -45,5 +45,7 @@
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>NSLocationWhenInUseUsageDescription</key>
<string>This app needs access to your location.</string>
</dict>
</plist>

View File

@@ -11,70 +11,84 @@ class AppFonts {
static const FontWeight bold = FontWeight.w600;
static const double _height = 1.20;
static const TextStyle yekan61Regular = TextStyle(
static const TextStyle yekan61 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 61,
height: _height,
);
static const TextStyle yekan49Regular = TextStyle(
static const TextStyle yekan49 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 48,
height: _height,
);
static const TextStyle yekan39Regular = TextStyle(
static const TextStyle yekan39 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 39,
height: _height,
);
static const TextStyle yekan31Regular = TextStyle(
static const TextStyle yekan31 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 31,
height: _height,
);
static const TextStyle yekan25Regular = TextStyle(
static const TextStyle yekan25 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 25,
height: _height,
);
static const TextStyle yekan24Regular = TextStyle(
static const TextStyle yekan24 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 24,
height: _height,
);
static const TextStyle yekan20Regular = TextStyle(
static const TextStyle yekan20 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 20,
height: _height,
);
static const TextStyle yekan16Regular = TextStyle(
static const TextStyle yekan18 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 18,
height: _height,
);
static const TextStyle yekan16 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 16,
height: _height,
);
static const TextStyle yekan13Regular = TextStyle(
static const TextStyle yekan14 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 13,
height: _height,
);
static const TextStyle yekan10Regular = TextStyle(
static const TextStyle yekan13 = TextStyle(
fontFamily: yekan,
fontWeight: regular,
fontSize: 13,
height: _height,
);
static const TextStyle yekan10 = TextStyle(
// Rounded from 10.24
fontFamily: yekan,
fontWeight: regular,

View File

@@ -10,6 +10,7 @@ class Assets {
static const String iconsEdit = 'assets/icons/edit.svg';
static const String iconsFilter = 'assets/icons/filter.svg';
static const String iconsKey = 'assets/icons/key.svg';
static const String iconsMapMarker = 'assets/icons/map_marker.svg';
static const String iconsScan = 'assets/icons/scan.svg';
static const String iconsTrash = 'assets/icons/trash.svg';
static const String iconsUser = 'assets/icons/user.svg';

View File

@@ -1,15 +0,0 @@
import 'package:get/get.dart';
class AuthWithOtpLogic extends GetxController {
@override
void onReady() {
// TODO: implement onReady
super.onReady();
}
@override
void onClose() {
// TODO: implement onClose
super.onClose();
}
}

View File

@@ -1,15 +0,0 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'logic.dart';
class AuthWithOtpPage extends StatelessWidget {
const AuthWithOtpPage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
final AuthWithOtpLogic logic = Get.put(AuthWithOtpLogic());
return Container();
}
}

View File

@@ -1,17 +1,60 @@
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rasadyar_app/presentation/widget/captcha/captcha_widget.dart';
enum AuthType { useAndPass, otp }
enum AuthStatus { init }
enum OtpStatus { init, sent, verified, reSend }
class AuthWithUseAndPassLogic extends GetxController {
Rx<GlobalKey<FormState>> formKey = GlobalKey<FormState>().obs;
Rx<GlobalKey<FormState>> formKeyOtp = GlobalKey<FormState>().obs;
Rx<GlobalKey<FormState>> formKeySentOtp = GlobalKey<FormState>().obs;
Rx<TextEditingController> phoneNumberController = TextEditingController().obs;
Rx<TextEditingController> passwordController = TextEditingController().obs;
Rx<TextEditingController> phoneOtpNumberController =
TextEditingController().obs;
Rx<TextEditingController> otpCodeController = TextEditingController().obs;
CaptchaController captchaController = CaptchaController();
CaptchaController captchaOtpController = CaptchaController();
RxnString phoneNumber = RxnString(null);
RxnString password = RxnString(null);
RxBool isOnError = false.obs;
RxBool hidePassword = true.obs;
Rx<AuthType> authType = AuthType.useAndPass.obs;
Rx<AuthStatus> authStatus = AuthStatus.init.obs;
Rx<OtpStatus> otpStatus = OtpStatus.init.obs;
RxInt secondsRemaining = 120.obs;
Timer? _timer;
void startTimer() {
_timer?.cancel();
secondsRemaining.value = 120;
_timer = Timer.periodic(const Duration(seconds: 1), (timer) {
if (secondsRemaining.value > 0) {
secondsRemaining.value--;
} else {
timer.cancel();
}
});
}
void stopTimer() {
_timer?.cancel();
}
String get timeFormatted {
final minutes = secondsRemaining.value ~/ 60;
final seconds = secondsRemaining.value % 60;
return '${minutes.toString().padLeft(2, '0')}:${seconds.toString().padLeft(2, '0')}';
}
@override
void onReady() {
@@ -21,7 +64,7 @@ class AuthWithUseAndPassLogic extends GetxController {
@override
void onClose() {
// TODO: implement onClose
_timer?.cancel();
super.onClose();
}
}

View File

@@ -1,4 +1,5 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:logger/logger.dart';
@@ -9,25 +10,89 @@ import 'package:rasadyar_app/presentation/common/assets.dart';
import 'package:rasadyar_app/presentation/widget/buttons/elevated.dart';
import 'package:rasadyar_app/presentation/widget/captcha/captcha_widget.dart';
import 'package:rasadyar_app/presentation/widget/vec_widget.dart';
import 'package:supervision/supervision.dart';
import 'logic.dart';
class AuthWithUseAndPassPage extends GetView<AuthWithUseAndPassLogic> {
AuthWithUseAndPassPage({super.key});
const AuthWithUseAndPassPage({super.key});
@override
Widget build(BuildContext context) {
final AuthWithUseAndPassLogic logic = Get.put(AuthWithUseAndPassLogic());
return Scaffold(
body: SingleChildScrollView(
child: Column(
children: [SizedBox(height: 80), logoWidget(), loginForm()],
children: [
SizedBox(height: 80),
logoWidget(),
ObxValue((types) {
switch (types.value) {
case AuthType.otp:
return otpForm();
case AuthType.useAndPass:
return useAndPassFrom();
}
}, controller.authType),
SizedBox(height: 50),
RichText(
text: TextSpan(
children: [
TextSpan(
text: 'مطالعه بیانیه ',
style: AppFonts.yekan14.copyWith(
color: AppColor.darkGreyDark,
),
),
TextSpan(
recognizer: TapGestureRecognizer()..onTap = () {},
text: 'حریم خصوصی',
style: AppFonts.yekan14.copyWith(
color: AppColor.blueNormal,
),
),
],
),
),
SizedBox(height: 18),
ObxValue((types) {
return RichText(
text: TextSpan(
children: [
TextSpan(
recognizer:
TapGestureRecognizer()
..onTap = () {
if (controller.authType.value == AuthType.otp) {
controller.authType.value = AuthType.useAndPass;
if (controller.otpStatus.value !=
OtpStatus.init) {
controller.otpStatus.value = OtpStatus.init;
}
} else {
controller.authType.value = AuthType.otp;
}
},
text:
controller.authType.value == AuthType.otp
? 'ورود با رمز ثابت'
: 'ورود با رمز یکبار مصرف',
style: AppFonts.yekan14.copyWith(
color: AppColor.blueNormal,
),
),
],
),
);
}, controller.authType),
],
),
),
);
}
Widget loginForm() {
Widget useAndPassFrom() {
return ObxValue((data) {
return Padding(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 50),
@@ -44,8 +109,8 @@ class AuthWithUseAndPassPage extends GetView<AuthWithUseAndPassLogic> {
gapPadding: 11,
),
labelText: 'شماره موبایل',
labelStyle: AppFonts.yekan13Regular,
errorStyle: AppFonts.yekan13Regular.copyWith(
labelStyle: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal,
),
@@ -79,6 +144,7 @@ class AuthWithUseAndPassPage extends GetView<AuthWithUseAndPassLogic> {
if (controller.isOnError.value) {
controller.isOnError.value = !controller.isOnError.value;
data.value.currentState?.reset();
data.refresh();
phoneController.value.text = value;
}
@@ -93,7 +159,7 @@ class AuthWithUseAndPassPage extends GetView<AuthWithUseAndPassLogic> {
}
return null;
},
style: AppFonts.yekan13Regular,
style: AppFonts.yekan13,
);
}, controller.phoneNumberController),
@@ -109,8 +175,8 @@ class AuthWithUseAndPassPage extends GetView<AuthWithUseAndPassLogic> {
gapPadding: 11,
),
labelText: 'رمز عبور',
labelStyle: AppFonts.yekan13Regular,
errorStyle: AppFonts.yekan13Regular.copyWith(
labelStyle: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal,
),
@@ -157,10 +223,9 @@ class AuthWithUseAndPassPage extends GetView<AuthWithUseAndPassLogic> {
}
return null;
},
style: AppFonts.yekan13Regular,
style: AppFonts.yekan13,
);
}, controller.passwordController),
SizedBox(height: 26),
CaptchaWidget(controller: controller.captchaController),
@@ -173,7 +238,7 @@ class AuthWithUseAndPassPage extends GetView<AuthWithUseAndPassLogic> {
di.get<Logger>().t(controller.captchaController.validate());
if (data.value.currentState?.validate() == true &&
controller.captchaController.validate()) {
print("==============>ssakldjaskljdklasjd");
Get.toNamed(SupervisionRoutes.supervision);
}
},
width: Get.width,
@@ -186,6 +251,257 @@ class AuthWithUseAndPassPage extends GetView<AuthWithUseAndPassLogic> {
}, controller.formKey);
}
Widget otpForm() {
return ObxValue((status) {
switch (status.value) {
case OtpStatus.init:
return sendCodeForm();
case OtpStatus.sent:
case OtpStatus.verified:
case OtpStatus.reSend:
return confirmCodeForm();
}
}, controller.otpStatus);
}
Widget sendCodeForm() {
return ObxValue((data) {
return Form(
key: data.value,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 50),
child: Column(
children: [
SizedBox(height: 26),
ObxValue((phoneController) {
return TextFormField(
controller: phoneController.value,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
gapPadding: 11,
),
labelText: 'شماره موبایل',
labelStyle: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal,
),
prefixIconConstraints: BoxConstraints(
maxHeight: 40,
minHeight: 40,
maxWidth: 40,
minWidth: 40,
),
prefixIcon: Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 6, 8),
child: vecWidget(Assets.vecCallSvg),
),
suffix:
phoneController.value.text.trim().isNotEmpty
? clearButton(() {
phoneController.value.clear();
phoneController.refresh();
})
: null,
counterText: '',
),
keyboardType: TextInputType.numberWithOptions(
decimal: false,
signed: false,
),
maxLines: 1,
maxLength: 11,
onChanged: (value) {
if (controller.isOnError.value) {
controller.isOnError.value = !controller.isOnError.value;
data.value.currentState?.reset();
data.refresh();
phoneController.value.text = value;
}
phoneController.refresh();
},
textInputAction: TextInputAction.next,
validator: (value) {
if (value == null) {
return '⚠️ شماره موبایل را وارد کنید';
} else if (value.length < 11) {
return '⚠️ شماره موبایل باید 11 رقم باشد';
}
return null;
},
style: AppFonts.yekan13,
);
}, controller.phoneOtpNumberController),
SizedBox(height: 26),
CaptchaWidget(controller: controller.captchaOtpController),
SizedBox(height: 23),
RElevated(
text: 'ارسال رمز یکبار مصرف',
onPressed: () {
if (data.value.currentState?.validate() == true &&
controller.captchaOtpController.validate()) {
controller.otpStatus.value = OtpStatus.sent;
controller.startTimer();
}
},
width: Get.width,
height: 48,
),
],
),
),
);
}, controller.formKeyOtp);
}
Widget confirmCodeForm() {
return ObxValue((data) {
return Form(
key: data.value,
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 30, vertical: 50),
child: Column(
children: [
SizedBox(height: 26),
ObxValue((passwordController) {
return TextFormField(
controller: passwordController.value,
obscureText: controller.hidePassword.value,
decoration: InputDecoration(
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
gapPadding: 11,
),
labelText: 'رمز عبور',
labelStyle: AppFonts.yekan13,
errorStyle: AppFonts.yekan13.copyWith(
color: AppColor.redNormal,
),
prefixIconConstraints: BoxConstraints(
maxHeight: 34,
minHeight: 34,
maxWidth: 34,
minWidth: 34,
),
prefixIcon: Padding(
padding: const EdgeInsets.fromLTRB(0, 8, 8, 8),
child: vecWidget(Assets.vecKeySvg),
),
suffix:
passwordController.value.text.trim().isNotEmpty
? GestureDetector(
onTap: () {
controller.hidePassword.value =
!controller.hidePassword.value;
},
child: Icon(
controller.hidePassword.value
? CupertinoIcons.eye
: CupertinoIcons.eye_slash,
),
)
: null,
counterText: '',
),
textInputAction: TextInputAction.done,
keyboardType: TextInputType.visiblePassword,
maxLines: 1,
onChanged: (value) {
if (controller.isOnError.value) {
controller.isOnError.value = !controller.isOnError.value;
data.value.currentState?.reset();
passwordController.value.text = value;
}
passwordController.refresh();
},
validator: (value) {
if (value == null || value.isEmpty) {
return '⚠️ رمز عبور را وارد کنید'; // "Please enter the password"
}
return null;
},
style: AppFonts.yekan13,
);
}, controller.passwordController),
SizedBox(height: 23),
ObxValue((timer) {
if (timer.value == 0) {
return TextButton(
onPressed: () {
controller.otpStatus.value = OtpStatus.reSend;
controller.startTimer();
},
child: Text(
style: AppFonts.yekan13.copyWith(
color: AppColor.blueNormal,
),
'ارسال مجدد کد یکبار مصرف',
),
);
} else {
return Text(
'اعتبار رمز ارسال شده ${controller.timeFormatted}',
style: AppFonts.yekan13,
);
}
}, controller.secondsRemaining),
RichText(
text: TextSpan(
children: [
TextSpan(
text: ' کد ارسال شده به شماره ',
style: AppFonts.yekan14.copyWith(
color: AppColor.darkGreyDark,
),
),
TextSpan(
text: controller.phoneOtpNumberController.value.text,
style: AppFonts.yekan13Bold.copyWith(
color: AppColor.darkGreyDark,
),
),
TextSpan(
recognizer:
TapGestureRecognizer()
..onTap = () {
controller.otpStatus.value = OtpStatus.init;
controller.captchaOtpController.clear();
},
text: ' ویرایش',
style: AppFonts.yekan14.copyWith(
color: AppColor.blueNormal,
),
),
],
),
),
SizedBox(height: 23),
RElevated(
text: 'ورود',
onPressed: () {
if (controller.formKeyOtp.value.currentState?.validate() ==
true &&
controller.captchaOtpController.validate()) {}
},
width: Get.width,
height: 48,
),
],
),
),
);
}, controller.formKeySentOtp);
}
Widget logoWidget() {
return Column(
children: [
@@ -193,9 +509,7 @@ class AuthWithUseAndPassPage extends GetView<AuthWithUseAndPassLogic> {
Image.asset(Assets.imagesInnerSplash, width: 120, height: 120),
Text(
'سامانه رصدیار',
style: AppFonts.yekan16Regular.copyWith(
color: AppColor.darkGreyNormal,
),
style: AppFonts.yekan16.copyWith(color: AppColor.darkGreyNormal),
),
],
);

View File

@@ -1,6 +1,7 @@
import 'package:flutter/animation.dart';
import 'package:get/get.dart';
import 'package:rasadyar_app/presentation/routes/app_pages.dart';
import 'package:supervision/supervision.dart';
class SplashLogic extends GetxController with GetTickerProviderStateMixin {
late final AnimationController scaleController;
@@ -54,7 +55,7 @@ class SplashLogic extends GetxController with GetTickerProviderStateMixin {
void onReady() {
super.onReady();
Future.delayed(const Duration(seconds: 1), () {
Get.offAllNamed(AppPaths.authWithUserAndPass);
Get.offAllNamed(SupervisionRoutes.supervision);
});
}

View File

@@ -68,7 +68,7 @@ class _SystemDesignPageState extends State<SystemDesignPage> {
return ListTile(
title: Text(
"inputs",
style: AppFonts.yekan20Regular.copyWith(color: Colors.red),
style: AppFonts.yekan20.copyWith(color: Colors.red),
),
);
},
@@ -79,11 +79,11 @@ class _SystemDesignPageState extends State<SystemDesignPage> {
children: [
RTextField(
hintText: 'حجم کشتار را در روز به قطعه وارد کنید',
hintStyle: AppFonts.yekan13Regular,
hintStyle: AppFonts.yekan13,
),
RTextField(
label: 'تلفن مرغداری',
labelStyle: AppFonts.yekan10Regular,
labelStyle: AppFonts.yekan10,
),
],
),
@@ -98,7 +98,7 @@ class _SystemDesignPageState extends State<SystemDesignPage> {
return ListTile(
title: Text(
"tab",
style: AppFonts.yekan20Regular.copyWith(color: Colors.red),
style: AppFonts.yekan20.copyWith(color: Colors.red),
),
);
},
@@ -119,7 +119,7 @@ class _SystemDesignPageState extends State<SystemDesignPage> {
return ListTile(
title: Text(
"پیجینیشن",
style: AppFonts.yekan20Regular.copyWith(color: Colors.red),
style: AppFonts.yekan20.copyWith(color: Colors.red),
),
);
},
@@ -134,7 +134,7 @@ class _SystemDesignPageState extends State<SystemDesignPage> {
return ListTile(
title: Text(
"Outlined Fab ",
style: AppFonts.yekan20Regular.copyWith(color: Colors.green),
style: AppFonts.yekan20.copyWith(color: Colors.green),
),
);
},
@@ -166,7 +166,7 @@ class _SystemDesignPageState extends State<SystemDesignPage> {
return ListTile(
title: Text(
"Fab",
style: AppFonts.yekan20Regular.copyWith(color: Colors.green),
style: AppFonts.yekan20.copyWith(color: Colors.green),
),
);
},
@@ -234,7 +234,7 @@ class _SystemDesignPageState extends State<SystemDesignPage> {
return ListTile(
title: Text(
"دکمه ها",
style: AppFonts.yekan20Regular.copyWith(color: Colors.green),
style: AppFonts.yekan20.copyWith(color: Colors.green),
),
);
},

View File

@@ -1,10 +1,9 @@
import 'package:get/get.dart';
import 'package:rasadyar_app/presentation/pages/auth/auth_with_otp/logic.dart';
import 'package:rasadyar_app/presentation/pages/auth/auth_with_otp/view.dart';
import 'package:rasadyar_app/presentation/pages/auth/auth_with_use_and_pass/logic.dart';
import 'package:rasadyar_app/presentation/pages/auth/auth_with_use_and_pass/view.dart';
import 'package:rasadyar_app/presentation/pages/splash/logic.dart';
import 'package:rasadyar_app/presentation/pages/splash/view.dart';
import 'package:supervision/supervision.dart';
part 'app_paths.dart';
@@ -19,15 +18,12 @@ sealed class AppPages {
page: () => SplashPage(),
binding: BindingsBuilder.put(() => SplashLogic()),
),
GetPage(
name: AppPaths.authWithOtp,
page: () => AuthWithOtpPage(),
binding: BindingsBuilder.put(() => AuthWithOtpLogic()),
),
GetPage(
name: AppPaths.authWithUserAndPass,
page: () => AuthWithUseAndPassPage(),
binding: BindingsBuilder.put(() => AuthWithUseAndPassLogic()),
),
...SupervisionPages.pages,
];
}

View File

@@ -48,7 +48,7 @@ class _RElevatedState extends State<RElevated> {
),
fixedSize: Size(widget.width, widget.height),
padding: EdgeInsets.zero,
textStyle: widget.textStyle ?? AppFonts.yekan24Regular,
textStyle: widget.textStyle ?? AppFonts.yekan24,
),
child: Text(widget.text),
);

View File

@@ -92,7 +92,7 @@ class _ROutlinedElevatedState extends State<ROutlinedElevated> {
padding: WidgetStatePropertyAll(EdgeInsets.zero),
textStyle: WidgetStatePropertyAll(
widget.textStyle ??
AppFonts.yekan24Regular.copyWith(color: AppColor.blueNormal),
AppFonts.yekan24.copyWith(color: AppColor.blueNormal),
),
),
child: Text(widget.text),

View File

@@ -7,12 +7,12 @@ class RTextButton extends StatefulWidget {
super.key,
required this.text,
required this.onPressed,
foregroundColor,
backgroundColor,
borderColor,
disabledBackgroundColor,
radius,
textStyle,
this.foregroundColor,
this.backgroundColor,
this.borderColor,
this.disabledBackgroundColor,
this.radius,
this.textStyle,
this.width = 150.0,
this.height = 56.0,
});
@@ -67,7 +67,7 @@ class _RTextButtonState extends State<RTextButton> {
padding: WidgetStatePropertyAll(EdgeInsets.zero),
textStyle: WidgetStatePropertyAll(
widget.textStyle ??
AppFonts.yekan24Regular.copyWith(color: AppColor.blueNormal),
AppFonts.yekan24.copyWith(color: AppColor.blueNormal),
),
),
onPressed:widget.onPressed,

View File

@@ -177,7 +177,7 @@ class _CaptchaWidgetState extends State<CaptchaWidget> {
),
Text(
widget.controller.captchaCode.toString(),
style: AppFonts.yekan24Regular,
style: AppFonts.yekan24,
),
],
),
@@ -203,8 +203,8 @@ class _CaptchaWidgetState extends State<CaptchaWidget> {
gapPadding: 11,
),
labelText: 'کد امنیتی',
labelStyle: AppFonts.yekan13Regular,
errorStyle: AppFonts.yekan10Regular.copyWith(
labelStyle: AppFonts.yekan13,
errorStyle: AppFonts.yekan10.copyWith(
color: AppColor.redNormal,
fontSize: 8,
),
@@ -249,7 +249,7 @@ class _CaptchaWidgetState extends State<CaptchaWidget> {
}
return null;
},
style: AppFonts.yekan13Regular,
style: AppFonts.yekan13,
),
),
),

View File

@@ -45,7 +45,7 @@ class _PaginationFromUntilState extends State<PaginationFromUntil> {
'$current از $total',
textAlign: TextAlign.center,
textDirection: TextDirection.rtl,
style: AppFonts.yekan16Regular.copyWith(
style: AppFonts.yekan16.copyWith(
color: AppColor.blueNormal,
),
),

View File

@@ -64,7 +64,7 @@ class _RShowMoreState extends State<RShowMore>
child: Text(
_toggled ? 'کمتر' : 'مشاهده بیشتر',
key: ValueKey(_toggled),
style: AppFonts.yekan10Regular.copyWith(color: AppColor.blueNormal),
style: AppFonts.yekan10.copyWith(color: AppColor.blueNormal),
),
),
SizedBox(height: 50,)

View File

@@ -70,14 +70,14 @@ class _CupertinoSegmentedControlDemoState2
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50)
),
child: Text('لاشه', style: AppFonts.yekan13Regular),
child: Text('لاشه', style: AppFonts.yekan13),
),
1: Container(
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(50)
),
child: Text('زنده', style: AppFonts.yekan13Regular),
child: Text('زنده', style: AppFonts.yekan13),
),
};

View File

@@ -0,0 +1,3 @@
library ;
export 'package:get/get.dart';

View File

@@ -0,0 +1,61 @@
name: rasadyar_core
description: "A new Flutter project."
publish_to: 'none'
version: 1.0.0+1
environment:
sdk: ^3.7.0
dependencies:
flutter:
sdk: flutter
cupertino_icons: ^1.0.8
##Log
logger: ^2.5.0
## reactive
dartx: ^1.2.0
rxdart: ^0.28.0
## local storage
hive_ce: ^2.10.1
hive_ce_flutter: ^2.2.0
##code generation
freezed_annotation: ^3.0.0
json_annotation: ^4.9.0
#SVG
flutter_svg: ^2.0.17
##state manger
get: ^4.7.2
##Di
get_it: ^8.0.3
permission_handler: ^11.4.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
##code generation
build_runner: ^2.4.15
hive_ce_generator: ^1.8.2
freezed: ^3.0.3
json_serializable: ^6.9.4
##test
mocktail: ^1.0.4
get_test: ^4.0.1
flutter:
uses-material-design: true

View File

@@ -169,6 +169,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.8"
dart_earcut:
dependency: transitive
description:
name: dart_earcut
sha256: e485001bfc05dcbc437d7bfb666316182e3522d4c3f9668048e004d0eb2ce43b
url: "https://pub.dev"
source: hosted
version: "1.2.0"
dart_style:
dependency: transitive
description:
@@ -230,6 +238,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.0"
flutter_map:
dependency: transitive
description:
name: flutter_map
sha256: f7d0379477274f323c3f3bc12d369a2b42eb86d1e7bd2970ae1ea3cff782449a
url: "https://pub.dev"
source: hosted
version: "8.1.1"
flutter_svg:
dependency: "direct main"
description:
@@ -243,6 +259,11 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
freezed:
dependency: "direct dev"
description:
@@ -267,6 +288,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.0.0"
geolocator:
dependency: transitive
description:
name: geolocator
sha256: f62bcd90459e63210bbf9c35deb6a51c521f992a78de19a1fe5c11704f9530e2
url: "https://pub.dev"
source: hosted
version: "13.0.4"
geolocator_android:
dependency: transitive
description:
name: geolocator_android
sha256: fcb1760a50d7500deca37c9a666785c047139b5f9ee15aa5469fae7dbbe3170d
url: "https://pub.dev"
source: hosted
version: "4.6.2"
geolocator_apple:
dependency: transitive
description:
name: geolocator_apple
sha256: dbdd8789d5aaf14cf69f74d4925ad1336b4433a6efdf2fce91e8955dc921bf22
url: "https://pub.dev"
source: hosted
version: "2.3.13"
geolocator_platform_interface:
dependency: transitive
description:
name: geolocator_platform_interface
sha256: "30cb64f0b9adcc0fb36f628b4ebf4f731a2961a0ebd849f4b56200205056fe67"
url: "https://pub.dev"
source: hosted
version: "4.2.6"
geolocator_web:
dependency: transitive
description:
name: geolocator_web
sha256: b1ae9bdfd90f861fde8fd4f209c37b953d65e92823cb73c7dee1fa021b06f172
url: "https://pub.dev"
source: hosted
version: "4.1.3"
geolocator_windows:
dependency: transitive
description:
name: geolocator_windows
sha256: "175435404d20278ffd220de83c2ca293b73db95eafbdc8131fe8609be1421eb6"
url: "https://pub.dev"
source: hosted
version: "0.2.5"
get:
dependency: "direct main"
description:
@@ -355,6 +424,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "4.1.2"
intl:
dependency: transitive
description:
name: intl
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
url: "https://pub.dev"
source: hosted
version: "0.20.2"
io:
dependency: transitive
description:
@@ -387,6 +464,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "6.9.4"
latlong2:
dependency: transitive
description:
name: latlong2
sha256: "98227922caf49e6056f91b6c56945ea1c7b166f28ffcd5fb8e72fc0b453cc8fe"
url: "https://pub.dev"
source: hosted
version: "0.9.1"
leak_tracker:
dependency: transitive
description:
@@ -419,6 +504,38 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.1.1"
lists:
dependency: transitive
description:
name: lists
sha256: "4ca5c19ae4350de036a7e996cdd1ee39c93ac0a2b840f4915459b7d0a7d4ab27"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
location:
dependency: transitive
description:
name: location
sha256: c2c4304071ec860525d5c50d142410072f8620c1d9f74874811af2e804e1a9c8
url: "https://pub.dev"
source: hosted
version: "8.0.0"
location_platform_interface:
dependency: transitive
description:
name: location_platform_interface
sha256: a3404ea6d74e89b121630be62ed8edcc7b39fd108bd19805d0ae55c397135dd7
url: "https://pub.dev"
source: hosted
version: "6.0.0"
location_web:
dependency: transitive
description:
name: location_web
sha256: "744bdff53dc455a2dc9a34474c49cde364d4fbef2aee009f8b0b4b68570c27a1"
url: "https://pub.dev"
source: hosted
version: "6.0.0"
logger:
dependency: "direct main"
description:
@@ -459,6 +576,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.16.0"
mgrs_dart:
dependency: transitive
description:
name: mgrs_dart
sha256: fb89ae62f05fa0bb90f70c31fc870bcbcfd516c843fb554452ab3396f78586f7
url: "https://pub.dev"
source: hosted
version: "2.0.0"
mime:
dependency: transitive
description:
@@ -555,6 +680,54 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.3.0"
permission_handler:
dependency: transitive
description:
name: permission_handler
sha256: "59adad729136f01ea9e35a48f5d1395e25cba6cea552249ddbe9cf950f5d7849"
url: "https://pub.dev"
source: hosted
version: "11.4.0"
permission_handler_android:
dependency: transitive
description:
name: permission_handler_android
sha256: d3971dcdd76182a0c198c096b5db2f0884b0d4196723d21a866fc4cdea057ebc
url: "https://pub.dev"
source: hosted
version: "12.1.0"
permission_handler_apple:
dependency: transitive
description:
name: permission_handler_apple
sha256: f84a188e79a35c687c132a0a0556c254747a08561e99ab933f12f6ca71ef3c98
url: "https://pub.dev"
source: hosted
version: "9.4.6"
permission_handler_html:
dependency: transitive
description:
name: permission_handler_html
sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24"
url: "https://pub.dev"
source: hosted
version: "0.1.3+5"
permission_handler_platform_interface:
dependency: transitive
description:
name: permission_handler_platform_interface
sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878
url: "https://pub.dev"
source: hosted
version: "4.3.0"
permission_handler_windows:
dependency: transitive
description:
name: permission_handler_windows
sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e"
url: "https://pub.dev"
source: hosted
version: "0.2.1"
petitparser:
dependency: transitive
description:
@@ -579,6 +752,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.8"
polylabel:
dependency: transitive
description:
name: polylabel
sha256: "41b9099afb2aa6c1730bdd8a0fab1400d287694ec7615dd8516935fa3144214b"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
pool:
dependency: transitive
description:
@@ -587,6 +768,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.5.1"
proj4dart:
dependency: transitive
description:
name: proj4dart
sha256: c8a659ac9b6864aa47c171e78d41bbe6f5e1d7bd790a5814249e6b68bc44324e
url: "https://pub.dev"
source: hosted
version: "2.1.0"
pub_semver:
dependency: transitive
description:
@@ -603,6 +792,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.5.0"
rasadyar_core:
dependency: transitive
description:
path: "packages/core"
relative: true
source: path
version: "1.0.0+1"
rxdart:
dependency: "direct main"
description:
@@ -656,6 +852,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.10.1"
sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
stack_trace:
dependency: transitive
description:
@@ -688,6 +892,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.1"
supervision:
dependency: "direct main"
description:
path: "features/supervision"
relative: true
source: path
version: "1.0.0"
term_glyph:
dependency: transitive
description:
@@ -728,6 +939,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.4.0"
unicode:
dependency: transitive
description:
name: unicode
sha256: "0f69e46593d65245774d4f17125c6084d2c20b4e473a983f6e21b7d7762218f1"
url: "https://pub.dev"
source: hosted
version: "0.3.1"
uuid:
dependency: transitive
description:
name: uuid
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
url: "https://pub.dev"
source: hosted
version: "4.5.1"
vector_graphics:
dependency: transitive
description:
@@ -800,6 +1027,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.2"
wkt_parser:
dependency: transitive
description:
name: wkt_parser
sha256: "8a555fc60de3116c00aad67891bcab20f81a958e4219cc106e3c037aa3937f13"
url: "https://pub.dev"
source: hosted
version: "2.0.0"
xdg_directories:
dependency: transitive
description:

View File

@@ -1,6 +1,6 @@
name: rasadyar_app
description: "A new Flutter project."
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
publish_to: 'none'
version: 1.0.0+1
environment:
@@ -38,6 +38,10 @@ dependencies:
##Di
get_it: ^8.0.3
supervision:
path: ./features/supervision
dev_dependencies:
flutter_test:
sdk: flutter
@@ -54,6 +58,9 @@ dev_dependencies:
flutter:
uses-material-design: true