feat : auth package
This commit is contained in:
@@ -1,12 +0,0 @@
|
|||||||
import 'package:hive_ce_flutter/hive_flutter.dart';
|
|
||||||
import 'package:rasadyar_app/data/data_provider/local_storage/i_local_storage_provider.dart';
|
|
||||||
|
|
||||||
|
|
||||||
enum HiveBoxNames { user, settings, auth }
|
|
||||||
|
|
||||||
class HiveProvider extends ILocalStorageProvider {
|
|
||||||
@override
|
|
||||||
Future<void> init() async {
|
|
||||||
await Hive.initFlutter();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
const int userTypeId = 0;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
abstract class ILocalStorageProvider {
|
|
||||||
Future<void> init();
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import 'package:hive_ce_flutter/hive_flutter.dart';
|
|
||||||
import 'package:rasadyar_app/data/data_provider/local_storage/hive/hive_provider.dart';
|
|
||||||
|
|
||||||
abstract class IUserLocalStorage {
|
|
||||||
Future<bool> userAuthed();
|
|
||||||
}
|
|
||||||
|
|
||||||
class UserLocalStorage extends IUserLocalStorage {
|
|
||||||
final user = Hive.box(HiveBoxNames.user.name);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> userAuthed() async {
|
|
||||||
if (user.isNotEmpty ) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'package:hive_ce/hive.dart';
|
|
||||||
|
|
||||||
import '../../data_provider/local_storage/hive/hive_types.dart';
|
|
||||||
|
|
||||||
|
|
||||||
part 'user_model.g.dart';
|
|
||||||
|
|
||||||
@HiveType(typeId: userTypeId)
|
|
||||||
class UserModel extends HiveObject{
|
|
||||||
@HiveField(0)
|
|
||||||
String? token;
|
|
||||||
|
|
||||||
@HiveField(1)
|
|
||||||
String? refreshToken;
|
|
||||||
|
|
||||||
UserModel({this.token, this.refreshToken});
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'package:rasadyar_app/data/data_source/local_storage/user/user_local_storage.dart';
|
|
||||||
|
|
||||||
abstract class IUserRepository {
|
|
||||||
Future<bool> userAuthed();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
class UserRepository implements IUserRepository {
|
|
||||||
final IUserLocalStorage _userLocalStorage;
|
|
||||||
|
|
||||||
UserRepository(this._userLocalStorage);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> userAuthed() async {
|
|
||||||
return await _userLocalStorage.userAuthed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:rasadyar_app/domain/repository/user/user_repository.dart';
|
|
||||||
import 'package:rasadyar_app/infrastructure/di/di.dart';
|
|
||||||
|
|
||||||
class UserService extends GetxService {
|
|
||||||
late IUserRepository _userLocalStorage;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onInit() {
|
|
||||||
return super.onInit();
|
|
||||||
// _userLocalStorage = di.get<UserRepository>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> isUserAuthed() async {
|
|
||||||
return await _userLocalStorage.userAuthed();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,10 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:rasadyar_app/domain/service/user/user_service.dart';
|
|
||||||
import 'package:rasadyar_app/presentation/routes/app_pages.dart';
|
import 'package:rasadyar_app/presentation/routes/app_pages.dart';
|
||||||
import 'package:rasadyar_core/core.dart';
|
import 'package:rasadyar_core/core.dart';
|
||||||
import 'package:rasadyar_core/infrastructure/di/di.dart';
|
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
setupInjection();
|
|
||||||
await setupAllProvider();
|
|
||||||
|
|
||||||
runApp(MyApp());
|
runApp(MyApp());
|
||||||
// runApp(DevicePreview(builder: (context) => ForDevicePreview(),));
|
// runApp(DevicePreview(builder: (context) => ForDevicePreview(),));
|
||||||
}
|
}
|
||||||
@@ -46,7 +41,7 @@ class MyApp extends StatelessWidget {
|
|||||||
colorScheme: ColorScheme.fromSeed(seedColor: AppColor.blueNormal),
|
colorScheme: ColorScheme.fromSeed(seedColor: AppColor.blueNormal),
|
||||||
),
|
),
|
||||||
initialRoute: AppPages.initRoutes,
|
initialRoute: AppPages.initRoutes,
|
||||||
initialBinding: BindingsBuilder.put(() => UserService()),
|
// initialBinding: BindingsBuilder.put(() => UserService()),
|
||||||
getPages: AppPages.pages,
|
getPages: AppPages.pages,
|
||||||
locale: const Locale("fa", "IR"),
|
locale: const Locale("fa", "IR"),
|
||||||
supportedLocales: const [
|
supportedLocales: const [
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:auth/src/domain/entity/auth_response_entity.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'auth_response_dto.freezed.dart';
|
||||||
|
part 'auth_response_dto.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class AuthResponseDto with _$AuthResponseDto {
|
||||||
|
const factory AuthResponseDto({
|
||||||
|
String? refresh,
|
||||||
|
String? access,
|
||||||
|
@JsonKey(name: 'otp_status') bool? otpStatus,
|
||||||
|
}) = _AuthResponseDto;
|
||||||
|
|
||||||
|
factory AuthResponseDto.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$AuthResponseDtoFromJson(json);
|
||||||
|
|
||||||
|
AuthResponseEntity toEntity() => AuthResponseEntity(
|
||||||
|
access: access,
|
||||||
|
otpStatus: otpStatus,
|
||||||
|
refresh: refresh,
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
|
part 'login_request_model.freezed.dart';
|
||||||
|
part 'login_request_model.g.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class LoginRequestModel with _$LoginRequestModel {
|
||||||
|
const factory LoginRequestModel({
|
||||||
|
required String username,
|
||||||
|
required String password,
|
||||||
|
required String captchaCode,
|
||||||
|
required String captchaKey,
|
||||||
|
}) = _LoginRequestModel;
|
||||||
|
|
||||||
|
factory LoginRequestModel.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$LoginRequestModelFromJson(json);
|
||||||
|
|
||||||
|
const LoginRequestModel._();
|
||||||
|
|
||||||
|
String get formattedCaptchaKey => 'rest_captcha_$captchaKey.0';
|
||||||
|
}
|
||||||
@@ -0,0 +1,157 @@
|
|||||||
|
// dart format width=80
|
||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'login_request_model.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$LoginRequestModel {
|
||||||
|
|
||||||
|
String get username; String get password; String get captchaCode; String get captchaKey;
|
||||||
|
/// Create a copy of LoginRequestModel
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$LoginRequestModelCopyWith<LoginRequestModel> get copyWith => _$LoginRequestModelCopyWithImpl<LoginRequestModel>(this as LoginRequestModel, _$identity);
|
||||||
|
|
||||||
|
/// Serializes this LoginRequestModel to a JSON map.
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is LoginRequestModel&&(identical(other.username, username) || other.username == username)&&(identical(other.password, password) || other.password == password)&&(identical(other.captchaCode, captchaCode) || other.captchaCode == captchaCode)&&(identical(other.captchaKey, captchaKey) || other.captchaKey == captchaKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,username,password,captchaCode,captchaKey);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LoginRequestModel(username: $username, password: $password, captchaCode: $captchaCode, captchaKey: $captchaKey)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $LoginRequestModelCopyWith<$Res> {
|
||||||
|
factory $LoginRequestModelCopyWith(LoginRequestModel value, $Res Function(LoginRequestModel) _then) = _$LoginRequestModelCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String username, String password, String captchaCode, String captchaKey
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$LoginRequestModelCopyWithImpl<$Res>
|
||||||
|
implements $LoginRequestModelCopyWith<$Res> {
|
||||||
|
_$LoginRequestModelCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final LoginRequestModel _self;
|
||||||
|
final $Res Function(LoginRequestModel) _then;
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequestModel
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? username = null,Object? password = null,Object? captchaCode = null,Object? captchaKey = null,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
username: null == username ? _self.username : username // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,captchaCode: null == captchaCode ? _self.captchaCode : captchaCode // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,captchaKey: null == captchaKey ? _self.captchaKey : captchaKey // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
|
||||||
|
class _LoginRequestModel extends LoginRequestModel {
|
||||||
|
const _LoginRequestModel({required this.username, required this.password, required this.captchaCode, required this.captchaKey}): super._();
|
||||||
|
factory _LoginRequestModel.fromJson(Map<String, dynamic> json) => _$LoginRequestModelFromJson(json);
|
||||||
|
|
||||||
|
@override final String username;
|
||||||
|
@override final String password;
|
||||||
|
@override final String captchaCode;
|
||||||
|
@override final String captchaKey;
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequestModel
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$LoginRequestModelCopyWith<_LoginRequestModel> get copyWith => __$LoginRequestModelCopyWithImpl<_LoginRequestModel>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$LoginRequestModelToJson(this, );
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _LoginRequestModel&&(identical(other.username, username) || other.username == username)&&(identical(other.password, password) || other.password == password)&&(identical(other.captchaCode, captchaCode) || other.captchaCode == captchaCode)&&(identical(other.captchaKey, captchaKey) || other.captchaKey == captchaKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,username,password,captchaCode,captchaKey);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'LoginRequestModel(username: $username, password: $password, captchaCode: $captchaCode, captchaKey: $captchaKey)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$LoginRequestModelCopyWith<$Res> implements $LoginRequestModelCopyWith<$Res> {
|
||||||
|
factory _$LoginRequestModelCopyWith(_LoginRequestModel value, $Res Function(_LoginRequestModel) _then) = __$LoginRequestModelCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String username, String password, String captchaCode, String captchaKey
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$LoginRequestModelCopyWithImpl<$Res>
|
||||||
|
implements _$LoginRequestModelCopyWith<$Res> {
|
||||||
|
__$LoginRequestModelCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _LoginRequestModel _self;
|
||||||
|
final $Res Function(_LoginRequestModel) _then;
|
||||||
|
|
||||||
|
/// Create a copy of LoginRequestModel
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? username = null,Object? password = null,Object? captchaCode = null,Object? captchaKey = null,}) {
|
||||||
|
return _then(_LoginRequestModel(
|
||||||
|
username: null == username ? _self.username : username // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,password: null == password ? _self.password : password // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,captchaCode: null == captchaCode ? _self.captchaCode : captchaCode // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,captchaKey: null == captchaKey ? _self.captchaKey : captchaKey // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'login_request_model.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_LoginRequestModel _$LoginRequestModelFromJson(Map<String, dynamic> json) =>
|
||||||
|
_LoginRequestModel(
|
||||||
|
username: json['username'] as String,
|
||||||
|
password: json['password'] as String,
|
||||||
|
captchaCode: json['captchaCode'] as String,
|
||||||
|
captchaKey: json['captchaKey'] as String,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$LoginRequestModelToJson(_LoginRequestModel instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'username': instance.username,
|
||||||
|
'password': instance.password,
|
||||||
|
'captchaCode': instance.captchaCode,
|
||||||
|
'captchaKey': instance.captchaKey,
|
||||||
|
};
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import 'package:rasadyar_core/core.dart';
|
||||||
|
|
||||||
|
part 'user_local_model.g.dart';
|
||||||
|
|
||||||
|
@HiveType(typeId: 0)
|
||||||
|
class UserLocalModel extends HiveObject {
|
||||||
|
@HiveField(0)
|
||||||
|
String? username;
|
||||||
|
@HiveField(1)
|
||||||
|
String? password;
|
||||||
|
@HiveField(2)
|
||||||
|
String? token;
|
||||||
|
@HiveField(3)
|
||||||
|
String? refreshToken;
|
||||||
|
@HiveField(4)
|
||||||
|
String? name;
|
||||||
|
|
||||||
|
UserLocalModel({
|
||||||
|
this.username,
|
||||||
|
this.password,
|
||||||
|
this.token,
|
||||||
|
this.refreshToken,
|
||||||
|
this.name,
|
||||||
|
});
|
||||||
|
|
||||||
|
UserLocalModel copyWith({
|
||||||
|
String? username,
|
||||||
|
String? password,
|
||||||
|
String? token,
|
||||||
|
String? refreshToken,
|
||||||
|
String? name,
|
||||||
|
}) {
|
||||||
|
return UserLocalModel(
|
||||||
|
username: username ?? this.username,
|
||||||
|
password: password ?? this.password,
|
||||||
|
token: token ?? this.token,
|
||||||
|
refreshToken: refreshToken ?? this.refreshToken,
|
||||||
|
name: name ?? this.name,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
class AuthResponseEntity {
|
||||||
|
final String? access;
|
||||||
|
final String? refresh;
|
||||||
|
final bool? otpStatus;
|
||||||
|
|
||||||
|
AuthResponseEntity({this.access, this.refresh, this.otpStatus});
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'AuthResponseEntity{accessToken: $access, refreshToken: $refresh, expiresIn: $otpStatus}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import 'package:auth/src/domain/entity/auth_response_entity.dart';
|
||||||
|
|
||||||
|
abstract class AuthRepository {
|
||||||
|
Future<AuthResponseEntity> signIn({
|
||||||
|
required Map<String, dynamic> authRequest,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -9,7 +9,7 @@ enum AuthStatus { init }
|
|||||||
|
|
||||||
enum OtpStatus { init, sent, verified, reSend }
|
enum OtpStatus { init, sent, verified, reSend }
|
||||||
|
|
||||||
class AuthWithUseAndPassLogic extends GetxController {
|
class AuthLogic extends GetxController {
|
||||||
Rx<GlobalKey<FormState>> formKey = GlobalKey<FormState>().obs;
|
Rx<GlobalKey<FormState>> formKey = GlobalKey<FormState>().obs;
|
||||||
Rx<GlobalKey<FormState>> formKeyOtp = GlobalKey<FormState>().obs;
|
Rx<GlobalKey<FormState>> formKeyOtp = GlobalKey<FormState>().obs;
|
||||||
Rx<GlobalKey<FormState>> formKeySentOtp = GlobalKey<FormState>().obs;
|
Rx<GlobalKey<FormState>> formKeySentOtp = GlobalKey<FormState>().obs;
|
||||||
@@ -5,8 +5,10 @@ import 'package:rasadyar_core/core.dart';
|
|||||||
|
|
||||||
import 'logic.dart';
|
import 'logic.dart';
|
||||||
|
|
||||||
class AuthWithUseAndPassPage extends GetView<AuthWithUseAndPassLogic> {
|
|
||||||
const AuthWithUseAndPassPage({super.key});
|
|
||||||
|
class AuthPage extends GetView<AuthLogic> {
|
||||||
|
const AuthPage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import 'package:flutter/animation.dart';
|
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:rasadyar_app/presentation/routes/app_pages.dart';
|
|
||||||
import 'package:inspection/inspection.dart';
|
|
||||||
|
|
||||||
class SplashLogic extends GetxController with GetTickerProviderStateMixin {
|
|
||||||
late final AnimationController scaleController;
|
|
||||||
late final AnimationController rotateController;
|
|
||||||
Rxn<Animation<double>> scaleAnimation = Rxn();
|
|
||||||
Rxn<Animation<double>> rotationAnimation = Rxn();
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onInit() {
|
|
||||||
super.onInit();
|
|
||||||
scaleController = AnimationController(
|
|
||||||
vsync: this,
|
|
||||||
duration: const Duration(milliseconds: 1500),
|
|
||||||
);
|
|
||||||
|
|
||||||
rotateController = AnimationController(
|
|
||||||
vsync: this,
|
|
||||||
duration: const Duration(milliseconds: 8000),
|
|
||||||
);
|
|
||||||
|
|
||||||
scaleAnimation.value = Tween<double>(
|
|
||||||
begin: 0.8,
|
|
||||||
end: 1.2,
|
|
||||||
).animate(scaleController);
|
|
||||||
|
|
||||||
rotationAnimation.value = Tween<double>(
|
|
||||||
begin: 0.0,
|
|
||||||
end: 1,
|
|
||||||
).animate(rotateController);
|
|
||||||
|
|
||||||
rotateController.forward();
|
|
||||||
rotateController.addStatusListener((status) {
|
|
||||||
if (status == AnimationStatus.completed) {
|
|
||||||
rotateController.repeat();
|
|
||||||
} else if (status == AnimationStatus.dismissed) {
|
|
||||||
rotateController.forward();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
scaleController.forward();
|
|
||||||
scaleController.addStatusListener((status) {
|
|
||||||
if (status == AnimationStatus.completed) {
|
|
||||||
scaleController.reverse();
|
|
||||||
} else if (status == AnimationStatus.dismissed) {
|
|
||||||
scaleController.forward();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onReady() {
|
|
||||||
super.onReady();
|
|
||||||
Future.delayed(const Duration(seconds: 1), () {
|
|
||||||
Get.offAllNamed(InspectionRoutes.inspection);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void onClose() {
|
|
||||||
rotateController.dispose();
|
|
||||||
scaleController.dispose();
|
|
||||||
super.onClose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:rasadyar_core/core.dart';
|
|
||||||
|
|
||||||
|
|
||||||
import 'logic.dart';
|
|
||||||
|
|
||||||
class SplashPage extends GetView<SplashLogic> {
|
|
||||||
const SplashPage({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
backgroundColor: AppColor.blueDarker,
|
|
||||||
body: Center(
|
|
||||||
child: Stack(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
children: [
|
|
||||||
ObxValue((data) {
|
|
||||||
return ScaleTransition(
|
|
||||||
scale: data.value!,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 1),
|
|
||||||
child: Image.asset(
|
|
||||||
Assets.imagesInnerSplash,
|
|
||||||
width: 190,
|
|
||||||
height: 190,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}, controller.scaleAnimation),
|
|
||||||
|
|
||||||
ObxValue((data) {
|
|
||||||
return RotationTransition(
|
|
||||||
turns: data.value!,
|
|
||||||
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 1),
|
|
||||||
child: Image.asset(Assets.imagesOutterSplash),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}, controller.rotationAnimation),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,255 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:rasadyar_core/core.dart';
|
|
||||||
|
|
||||||
|
|
||||||
class SystemDesignPage extends StatefulWidget {
|
|
||||||
const SystemDesignPage({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<SystemDesignPage> createState() => _SystemDesignPageState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SystemDesignPageState extends State<SystemDesignPage> {
|
|
||||||
List<bool> _isOpen = [false, false, false, false, false, false];
|
|
||||||
|
|
||||||
void _handleAdd() {
|
|
||||||
print("Add FAB pressed");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleEdit() {
|
|
||||||
print("Edit FAB pressed");
|
|
||||||
}
|
|
||||||
|
|
||||||
void _handleDelete() {
|
|
||||||
print("Delete FAB pressed");
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Scaffold(
|
|
||||||
appBar: AppBar(title: Text("System design"), centerTitle: true),
|
|
||||||
body: SingleChildScrollView(
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: ExpansionPanelList(
|
|
||||||
expansionCallback: (panelIndex, isExpanded) {
|
|
||||||
setState(() {
|
|
||||||
_isOpen[panelIndex] = isExpanded;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
children: [
|
|
||||||
buttonWidget(),
|
|
||||||
fabWidget(),
|
|
||||||
outlinedFabWidget(),
|
|
||||||
paginationWidget(),
|
|
||||||
tabWidget(),
|
|
||||||
inputsWidget(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpansionPanel inputsWidget() {
|
|
||||||
return ExpansionPanel(
|
|
||||||
isExpanded: _isOpen[5],
|
|
||||||
headerBuilder: (context, isExpanded) {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(
|
|
||||||
"inputs",
|
|
||||||
style: AppFonts.yekan20.copyWith(color: Colors.red),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
body: Padding(
|
|
||||||
padding: const EdgeInsets.all(8.0),
|
|
||||||
child: Column(
|
|
||||||
spacing: 14,
|
|
||||||
children: [
|
|
||||||
RTextField(
|
|
||||||
hintText: 'حجم کشتار را در روز به قطعه وارد کنید',
|
|
||||||
hintStyle: AppFonts.yekan13,
|
|
||||||
),
|
|
||||||
RTextField(
|
|
||||||
label: 'تلفن مرغداری',
|
|
||||||
labelStyle: AppFonts.yekan10,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpansionPanel tabWidget() {
|
|
||||||
return ExpansionPanel(
|
|
||||||
isExpanded: _isOpen[4],
|
|
||||||
headerBuilder: (context, isExpanded) {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(
|
|
||||||
"tab",
|
|
||||||
style: AppFonts.yekan20.copyWith(color: Colors.red),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
body: Column(
|
|
||||||
spacing: 14,
|
|
||||||
children: [
|
|
||||||
CupertinoSegmentedControlDemo(),
|
|
||||||
CupertinoSegmentedControlDemo2(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpansionPanel paginationWidget() {
|
|
||||||
return ExpansionPanel(
|
|
||||||
isExpanded: _isOpen[3],
|
|
||||||
headerBuilder: (context, isExpanded) {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(
|
|
||||||
"پیجینیشن",
|
|
||||||
style: AppFonts.yekan20.copyWith(color: Colors.red),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
body: Column(spacing: 14, children: [RShowMore(), PaginationFromUntil()]),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpansionPanel outlinedFabWidget() {
|
|
||||||
return ExpansionPanel(
|
|
||||||
isExpanded: _isOpen[2],
|
|
||||||
headerBuilder: (context, isExpanded) {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(
|
|
||||||
"Outlined Fab ",
|
|
||||||
style: AppFonts.yekan20.copyWith(color: Colors.green),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
body: Column(
|
|
||||||
spacing: 14,
|
|
||||||
children: [
|
|
||||||
Row(),
|
|
||||||
/*
|
|
||||||
RFabOutlined.smallAdd(onPressed: () {}),
|
|
||||||
RFabOutlined.smallAdd(onPressed: null),
|
|
||||||
|
|
||||||
RFabOutlined.smallAddNoBorder(onPressed: () {}),
|
|
||||||
RFabOutlined.smallAddNoBorder(onPressed: null),
|
|
||||||
|
|
||||||
RFabOutlined.add(onPressed: () {}),
|
|
||||||
RFabOutlined.add(onPressed: null),
|
|
||||||
|
|
||||||
RFabOutlined.addNoBorder(onPressed: () {}),
|
|
||||||
RFabOutlined.addNoBorder(onPressed: null),*/
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpansionPanel fabWidget() {
|
|
||||||
return ExpansionPanel(
|
|
||||||
isExpanded: _isOpen[1],
|
|
||||||
headerBuilder: (context, isExpanded) {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(
|
|
||||||
"Fab",
|
|
||||||
style: AppFonts.yekan20.copyWith(color: Colors.green),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
body: Column(
|
|
||||||
spacing: 14,
|
|
||||||
children: [
|
|
||||||
Row(),
|
|
||||||
|
|
||||||
/* RFab.smallAdd(onPressed: () {}),
|
|
||||||
RFab.smallAdd(onPressed: null),
|
|
||||||
|
|
||||||
RFab.add(onPressed: () {}),
|
|
||||||
RFab.add(onPressed: null),
|
|
||||||
|
|
||||||
RFab.smallEdit(onPressed: null),
|
|
||||||
RFab.smallEdit(onPressed: () {}),
|
|
||||||
|
|
||||||
RFab.edit(onPressed: () {}),
|
|
||||||
RFab.edit(onPressed: null),
|
|
||||||
|
|
||||||
RFab.smallDelete(onPressed: () {}),
|
|
||||||
RFab.smallDelete(onPressed: null),
|
|
||||||
|
|
||||||
RFab.delete(onPressed: () {}),
|
|
||||||
RFab.delete(onPressed: null),
|
|
||||||
|
|
||||||
RFab.smallAction(onPressed: () {}),
|
|
||||||
RFab.smallAction(onPressed: null),
|
|
||||||
|
|
||||||
RFab.action(onPressed: () {}),
|
|
||||||
RFab.action(onPressed: null),
|
|
||||||
|
|
||||||
RFab.smallFilter(onPressed: () {}),
|
|
||||||
RFab.smallFilter(onPressed: null),
|
|
||||||
|
|
||||||
RFab.filter(onPressed: () {}),
|
|
||||||
RFab.filter(onPressed: null),
|
|
||||||
|
|
||||||
RFab.smallDownload(onPressed: () {}),
|
|
||||||
RFab.smallDownload(onPressed: null),
|
|
||||||
|
|
||||||
RFab.download(onPressed: () {}),
|
|
||||||
RFab.download(onPressed: null),
|
|
||||||
|
|
||||||
RFab.smallExcel(onPressed: () {}),
|
|
||||||
RFab.smallExcel(onPressed: null),
|
|
||||||
|
|
||||||
RFab.excel(onPressed: () {}),
|
|
||||||
RFab.excel(onPressed: null),
|
|
||||||
|
|
||||||
RFab.smallBack(onPressed: () {}),
|
|
||||||
RFab.smallBack(onPressed: null),
|
|
||||||
|
|
||||||
RFab.back(onPressed: () {}),
|
|
||||||
RFab.back(onPressed: null),*/
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExpansionPanel buttonWidget() {
|
|
||||||
return ExpansionPanel(
|
|
||||||
isExpanded: _isOpen[0],
|
|
||||||
headerBuilder: (context, isExpanded) {
|
|
||||||
return ListTile(
|
|
||||||
title: Text(
|
|
||||||
"دکمه ها",
|
|
||||||
style: AppFonts.yekan20.copyWith(color: Colors.green),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
body: Column(
|
|
||||||
spacing: 14,
|
|
||||||
children: [
|
|
||||||
Row(),
|
|
||||||
|
|
||||||
RElevated(text: 'ثبت', onPressed: () {}),
|
|
||||||
|
|
||||||
RElevated(text: 'ثبت', onPressed: null),
|
|
||||||
|
|
||||||
ROutlinedElevated(text: 'ثبت', onPressed: () {}),
|
|
||||||
ROutlinedElevated(
|
|
||||||
text: 'ثبتwwww',
|
|
||||||
onPressed: () {},
|
|
||||||
backgroundColor: AppColor.blueNormal.disabledColor,
|
|
||||||
pressedBackgroundColor: AppColor.blueNormal,
|
|
||||||
),
|
|
||||||
ROutlinedElevated(text: 'ثبت', onPressed: null),
|
|
||||||
|
|
||||||
RTextButton(text: 'ثبت', onPressed: () {}),
|
|
||||||
RTextButton(text: 'ثبت', onPressed: null),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +1,33 @@
|
|||||||
name: auth
|
name: auth
|
||||||
description: A starting point for Dart libraries or applications.
|
description: A starting point for Dart libraries or applications.
|
||||||
|
publish_to: 'none'
|
||||||
version: 1.0.0
|
version: 1.0.0
|
||||||
|
|
||||||
# repository: https://github.com/my_org/my_repo
|
# repository: https://github.com/my_org/my_repo
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.7.2
|
sdk: ^3.7.2
|
||||||
|
|
||||||
# Add regular dependencies here.
|
|
||||||
dependencies:
|
dependencies:
|
||||||
# path: ^1.8.0
|
# path: ^1.8.0
|
||||||
|
rasadyar_core:
|
||||||
|
path: ../core
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
lints: ^5.0.0
|
lints: ^5.0.0
|
||||||
test: ^1.24.0
|
test: ^1.24.0
|
||||||
|
flutter_test:
|
||||||
|
sdk: flutter
|
||||||
|
flutter_lints: ^5.0.0
|
||||||
|
##code generation
|
||||||
|
build_runner: ^2.4.15
|
||||||
|
hive_ce_generator: ^1.9.1
|
||||||
|
freezed: ^3.0.3
|
||||||
|
json_serializable: ^6.9.4
|
||||||
|
|
||||||
|
##test
|
||||||
|
mocktail: ^1.0.4
|
||||||
|
get_test: ^4.0.1
|
||||||
|
|
||||||
|
flutter:
|
||||||
|
uses-material-design: true
|
||||||
@@ -11,6 +11,13 @@ export 'package:flutter_slidable/flutter_slidable.dart';
|
|||||||
export 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
export 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
export 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
export 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||||
export 'package:persian_datetime_picker/persian_datetime_picker.dart';
|
export 'package:persian_datetime_picker/persian_datetime_picker.dart';
|
||||||
|
|
||||||
|
//freezed
|
||||||
|
export 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
//local storage
|
||||||
|
export 'package:hive_ce_flutter/hive_flutter.dart';
|
||||||
|
|
||||||
//Map and location
|
//Map and location
|
||||||
export 'package:latlong2/latlong.dart';
|
export 'package:latlong2/latlong.dart';
|
||||||
export 'package:flutter_map/flutter_map.dart';
|
export 'package:flutter_map/flutter_map.dart';
|
||||||
@@ -19,3 +26,4 @@ export 'package:flutter_map_animations/flutter_map_animations.dart';
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
import 'package:rasadyar_core/infrastructure/di/di.dart';
|
import 'package:rasadyar_core/injection/di.dart';
|
||||||
|
|
||||||
void iLog(dynamic message) {
|
void iLog(dynamic message) {
|
||||||
if(kDebugMode){
|
if(kDebugMode){
|
||||||
di.get<Logger>().i(message.toString());
|
diCore.get<Logger>().i(message.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void eLog(dynamic message) {
|
void eLog(dynamic message) {
|
||||||
if(kDebugMode){
|
if(kDebugMode){
|
||||||
di.get<Logger>().e(message.toString());
|
diCore.get<Logger>().e(message.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void dLog(dynamic message) {
|
void dLog(dynamic message) {
|
||||||
if(kDebugMode){
|
if(kDebugMode){
|
||||||
di.get<Logger>().d(message.toString());
|
diCore.get<Logger>().d(message.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void fLog(dynamic message){
|
void fLog(dynamic message){
|
||||||
if(kDebugMode){
|
if(kDebugMode){
|
||||||
di.get<Logger>().f(message.toString());
|
diCore.get<Logger>().f(message.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void tLog(dynamic message) {
|
void tLog(dynamic message) {
|
||||||
if(kDebugMode){
|
if(kDebugMode){
|
||||||
di.get<Logger>().t(message.toString());
|
diCore.get<Logger>().t(message.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import 'package:hive_ce_flutter/hive_flutter.dart';
|
||||||
|
|
||||||
|
import 'i_local_storage.dart';
|
||||||
|
|
||||||
|
class HiveLocalStorage implements ILocalStorage {
|
||||||
|
HiveLocalStorage() {
|
||||||
|
Hive.initFlutter();
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<String, Box> _boxes = {};
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future init() async => await Hive.initFlutter();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> openBox<T>(String boxName) async {
|
||||||
|
if (!_boxes.containsKey(boxName)) {
|
||||||
|
final box = await Hive.openBox<T>(boxName);
|
||||||
|
_boxes[boxName] = box;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> delete(String boxName, String key) async {
|
||||||
|
Box<dynamic>? box = await getBox(boxName);
|
||||||
|
await box.delete(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<T?> read<T>(String boxName, String key) async {
|
||||||
|
Box? box = await getBox(boxName);
|
||||||
|
return box.get(key) as T?;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> save(String boxName, String key, value) async {
|
||||||
|
Box<dynamic>? box = await getBox(boxName);
|
||||||
|
await box.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> add(String boxName, value) async {
|
||||||
|
Box<dynamic>? box = await getBox(boxName);
|
||||||
|
await box.add(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> addAll(String boxName, Iterable values) async {
|
||||||
|
Box<dynamic>? box = await getBox(boxName);
|
||||||
|
await box.addAll(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Box<T>> getBox<T>(String boxName) async {
|
||||||
|
final box = _boxes[boxName];
|
||||||
|
if (box is Box<T>) {
|
||||||
|
return box;
|
||||||
|
} else {
|
||||||
|
throw Exception('Box $boxName is not of expected type $T');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
packages/core/lib/infrastructure/local/i_local_storage.dart
Normal file
11
packages/core/lib/infrastructure/local/i_local_storage.dart
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
abstract class ILocalStorage<E>{
|
||||||
|
Future<void> init();
|
||||||
|
Future<void> openBox<T>(String boxName);
|
||||||
|
Future<void> save(String boxName, String key, dynamic value);
|
||||||
|
Future<T?> read<T>(String boxName, String key);
|
||||||
|
Future<void> delete(String boxName, String key);
|
||||||
|
|
||||||
|
Future<void> add(String boxName, E value);
|
||||||
|
Future<void> addAll(String boxName, Iterable<E> values);
|
||||||
|
|
||||||
|
}
|
||||||
23
packages/core/lib/infrastructure/remote/dio_form_data.dart
Normal file
23
packages/core/lib/infrastructure/remote/dio_form_data.dart
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
import 'interfaces/i_form_data.dart';
|
||||||
|
|
||||||
|
class DioFormData implements IFormData {
|
||||||
|
final FormData _formData = FormData();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void addFile(String field, Uint8List bytes, String filename) {
|
||||||
|
_formData.files.add(MapEntry(
|
||||||
|
field,
|
||||||
|
MultipartFile.fromBytes(bytes, filename: filename),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void addField(String key, String value) {
|
||||||
|
_formData.fields.add(MapEntry(key, value));
|
||||||
|
}
|
||||||
|
|
||||||
|
FormData get raw => _formData;
|
||||||
|
}
|
||||||
126
packages/core/lib/infrastructure/remote/dio_remote.dart
Normal file
126
packages/core/lib/infrastructure/remote/dio_remote.dart
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:pretty_dio_logger/pretty_dio_logger.dart';
|
||||||
|
import 'package:rasadyar_core/infrastructure/remote/interfaces/i_form_data.dart';
|
||||||
|
import 'package:rasadyar_core/infrastructure/remote/interfaces/i_http_response.dart';
|
||||||
|
import 'package:rasadyar_core/infrastructure/remote/interfaces/i_remote.dart';
|
||||||
|
|
||||||
|
import 'dio_form_data.dart';
|
||||||
|
import 'dio_response.dart';
|
||||||
|
import 'interfaces/i_http_client.dart';
|
||||||
|
|
||||||
|
class DioRemote implements IRemote, IHttpClient {
|
||||||
|
final String baseUrl;
|
||||||
|
late final Dio _dio;
|
||||||
|
|
||||||
|
DioRemote(this.baseUrl);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> init() async {
|
||||||
|
final dio = Dio(BaseOptions(baseUrl: baseUrl));
|
||||||
|
dio.interceptors.add(PrettyDioLogger());
|
||||||
|
_dio = dio;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<IHttpResponse> get(
|
||||||
|
String path, {
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Map<String, String>? headers,
|
||||||
|
ProgressCallback? onReceiveProgress,
|
||||||
|
}) async {
|
||||||
|
final response = await _dio.get(
|
||||||
|
path,
|
||||||
|
queryParameters: queryParameters,
|
||||||
|
options: Options(headers: headers),
|
||||||
|
onReceiveProgress: onReceiveProgress,
|
||||||
|
);
|
||||||
|
return DioHttpResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<IHttpResponse> post(
|
||||||
|
String path, {
|
||||||
|
dynamic data,
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Map<String, String>? headers,
|
||||||
|
ProgressCallback? onSendProgress,
|
||||||
|
ProgressCallback? onReceiveProgress,
|
||||||
|
}) async {
|
||||||
|
final response = await _dio.post(
|
||||||
|
path,
|
||||||
|
data: data,
|
||||||
|
queryParameters: queryParameters,
|
||||||
|
options: Options(headers: headers),
|
||||||
|
onSendProgress: onSendProgress,
|
||||||
|
onReceiveProgress: onReceiveProgress,
|
||||||
|
);
|
||||||
|
return DioHttpResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<IHttpResponse> put(
|
||||||
|
String path, {
|
||||||
|
dynamic data,
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Map<String, String>? headers,
|
||||||
|
ProgressCallback? onSendProgress,
|
||||||
|
ProgressCallback? onReceiveProgress,
|
||||||
|
}) async {
|
||||||
|
final response = await _dio.put(
|
||||||
|
path,
|
||||||
|
data: data,
|
||||||
|
queryParameters: queryParameters,
|
||||||
|
options: Options(headers: headers),
|
||||||
|
onSendProgress: onSendProgress,
|
||||||
|
onReceiveProgress: onReceiveProgress,
|
||||||
|
);
|
||||||
|
return DioHttpResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<IHttpResponse> delete(
|
||||||
|
String path, {
|
||||||
|
dynamic data,
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Map<String, String>? headers,
|
||||||
|
}) async {
|
||||||
|
final response = await _dio.delete(
|
||||||
|
path,
|
||||||
|
data: data,
|
||||||
|
queryParameters: queryParameters,
|
||||||
|
options: Options(headers: headers),
|
||||||
|
);
|
||||||
|
return DioHttpResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<IHttpResponse<Uint8List>> download(
|
||||||
|
String url, {
|
||||||
|
ProgressCallback? onReceiveProgress,
|
||||||
|
}) async {
|
||||||
|
final response = await _dio.get<Uint8List>(
|
||||||
|
url,
|
||||||
|
options: Options(responseType: ResponseType.bytes),
|
||||||
|
onReceiveProgress: onReceiveProgress,
|
||||||
|
);
|
||||||
|
return DioHttpResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<IHttpResponse> upload(
|
||||||
|
String path, {
|
||||||
|
required IFormData formData,
|
||||||
|
Map<String, String>? headers,
|
||||||
|
ProgressCallback? onSendProgress,
|
||||||
|
}) async {
|
||||||
|
final response = await _dio.post(
|
||||||
|
path,
|
||||||
|
data: (formData as DioFormData).raw,
|
||||||
|
options: Options(headers: headers, contentType: 'multipart/form-data'),
|
||||||
|
onSendProgress: onSendProgress,
|
||||||
|
);
|
||||||
|
return DioHttpResponse(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
21
packages/core/lib/infrastructure/remote/dio_response.dart
Normal file
21
packages/core/lib/infrastructure/remote/dio_response.dart
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import 'interfaces/i_http_response.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
|
||||||
|
class DioHttpResponse<T> implements IHttpResponse<T> {
|
||||||
|
final Response<T> _response;
|
||||||
|
|
||||||
|
DioHttpResponse(this._response);
|
||||||
|
|
||||||
|
@override
|
||||||
|
T? get data => _response.data;
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get statusCode => _response.statusCode ?? 0;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, List<String>> get headers =>
|
||||||
|
_response.headers.map.map((k, v) => MapEntry(k, v));
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool get isSuccessful => statusCode >= 200 && statusCode < 300;
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
||||||
|
abstract class IFormData{
|
||||||
|
void addFile(String field, Uint8List bytes, String filename);
|
||||||
|
void addField(String key, String value);
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:rasadyar_core/infrastructure/remote/dio_form_data.dart';
|
||||||
|
import 'i_http_response.dart';
|
||||||
|
import 'i_form_data.dart';
|
||||||
|
|
||||||
|
abstract class IHttpClient {
|
||||||
|
Future<IHttpResponse> get(
|
||||||
|
String path, {
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Map<String, String>? headers,
|
||||||
|
ProgressCallback? onReceiveProgress,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<IHttpResponse> post(
|
||||||
|
String path, {
|
||||||
|
dynamic data,
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Map<String, String>? headers,
|
||||||
|
ProgressCallback? onSendProgress,
|
||||||
|
ProgressCallback? onReceiveProgress,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<IHttpResponse> put(
|
||||||
|
String path, {
|
||||||
|
dynamic data,
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Map<String, String>? headers,
|
||||||
|
ProgressCallback? onSendProgress,
|
||||||
|
ProgressCallback? onReceiveProgress,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<IHttpResponse> delete(
|
||||||
|
String path, {
|
||||||
|
dynamic data,
|
||||||
|
Map<String, dynamic>? queryParameters,
|
||||||
|
Map<String, String>? headers,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<IHttpResponse<Uint8List>> download(
|
||||||
|
String url, {
|
||||||
|
ProgressCallback? onReceiveProgress,
|
||||||
|
});
|
||||||
|
|
||||||
|
Future<IHttpResponse> upload(
|
||||||
|
String path, {
|
||||||
|
required IFormData formData,
|
||||||
|
Map<String, String>? headers,
|
||||||
|
ProgressCallback? onSendProgress,
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
abstract class IHttpResponse<T> {
|
||||||
|
T? get data;
|
||||||
|
int get statusCode;
|
||||||
|
Map<String, List<String>> get headers;
|
||||||
|
bool get isSuccessful;
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
abstract class IRemote<T>{
|
||||||
|
Future<T> init();
|
||||||
|
}
|
||||||
|
|
||||||
@@ -193,6 +193,22 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "1.2.0"
|
||||||
|
dio:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dio
|
||||||
|
sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "5.8.0+1"
|
||||||
|
dio_web_adapter:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: dio_web_adapter
|
||||||
|
sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.1"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -797,6 +813,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.1"
|
version: "1.5.1"
|
||||||
|
pretty_dio_logger:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: pretty_dio_logger
|
||||||
|
sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.0"
|
||||||
proj4dart:
|
proj4dart:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ dependencies:
|
|||||||
rxdart: ^0.28.0
|
rxdart: ^0.28.0
|
||||||
|
|
||||||
## local storage
|
## local storage
|
||||||
hive_ce: ^2.10.1
|
hive_ce: ^2.11.1
|
||||||
hive_ce_flutter: ^2.2.0
|
hive_ce_flutter: ^2.3.0
|
||||||
|
|
||||||
##code generation
|
##code generation
|
||||||
freezed_annotation: ^3.0.0
|
freezed_annotation: ^3.0.0
|
||||||
@@ -58,7 +58,11 @@ dependencies:
|
|||||||
#location
|
#location
|
||||||
latlong2: ^0.9.1
|
latlong2: ^0.9.1
|
||||||
geolocator: ^14.0.0
|
geolocator: ^14.0.0
|
||||||
|
#network
|
||||||
|
dio: ^5.8.0+1
|
||||||
|
|
||||||
|
#networkLogger
|
||||||
|
pretty_dio_logger: ^1.4.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
@@ -66,7 +70,7 @@ dev_dependencies:
|
|||||||
flutter_lints: ^5.0.0
|
flutter_lints: ^5.0.0
|
||||||
##code generation
|
##code generation
|
||||||
build_runner: ^2.4.15
|
build_runner: ^2.4.15
|
||||||
hive_ce_generator: ^1.8.2
|
hive_ce_generator: ^1.9.1
|
||||||
freezed: ^3.0.3
|
freezed: ^3.0.3
|
||||||
json_serializable: ^6.9.4
|
json_serializable: ^6.9.4
|
||||||
|
|
||||||
@@ -75,5 +79,7 @@ dev_dependencies:
|
|||||||
get_test: ^4.0.1
|
get_test: ^4.0.1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
flutter:
|
flutter:
|
||||||
uses-material-design: true
|
uses-material-design: true
|
||||||
|
|||||||
Reference in New Issue
Block a user