mirror of
https://github.com/SyncrowIOT/syncrow-app.git
synced 2025-11-27 11:14:55 +00:00
Merge branch 'dev' into doorlock_interface
This commit is contained in:
@ -20,8 +20,9 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
|
||||
static AuthCubit get(context) => BlocProvider.of(context);
|
||||
|
||||
TextEditingController emailController = TextEditingController();
|
||||
TextEditingController passwordController = TextEditingController();
|
||||
final TextEditingController emailController = TextEditingController();
|
||||
final TextEditingController passwordController = TextEditingController();
|
||||
final loginFormKey = GlobalKey<FormState>();
|
||||
bool isPasswordVisible = false;
|
||||
|
||||
static GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
@ -41,6 +42,56 @@ class AuthCubit extends Cubit<AuthState> {
|
||||
static UserModel? user;
|
||||
|
||||
static Token token = Token.emptyConstructor();
|
||||
|
||||
/////////////////////////////////////VALIDATORS/////////////////////////////////////
|
||||
String? passwordValidator(String? value) {
|
||||
if (value != null) {
|
||||
if (value.isNotEmpty) {
|
||||
if (value.length >= 6) {
|
||||
return null;
|
||||
//TODO uncomment this code when the password validation is needed
|
||||
// if (RegExp(
|
||||
// r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$')
|
||||
// .hasMatch(value)) {
|
||||
// return null;
|
||||
// } else {
|
||||
// return 'Password must contain at least one uppercase letter, one lowercase letter, one number and one special character';
|
||||
// }
|
||||
} else {
|
||||
return 'Password must be at least 6 characters';
|
||||
}
|
||||
} else {
|
||||
return 'Please enter your password';
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String? emailAddressValidator(String? value) {
|
||||
if (value != null && value.isNotEmpty && value != "") {
|
||||
if (checkValidityOfEmail(value)) {
|
||||
if (loginFormKey.currentState != null) {
|
||||
loginFormKey.currentState!.save();
|
||||
}
|
||||
return null;
|
||||
} else {
|
||||
return 'Please enter a valid email';
|
||||
}
|
||||
} else {
|
||||
return 'Email address is required';
|
||||
}
|
||||
}
|
||||
|
||||
bool checkValidityOfEmail(String? email) {
|
||||
if (email != null) {
|
||||
return RegExp(
|
||||
r"^[a-zA-Z0-9]+([.!#$%&'*+/=?^_`{|}~-]?[a-zA-Z0-9]+)*@[a-zA-Z0-9]+([.-]?[a-zA-Z0-9]+)*\.[a-zA-Z0-9]{2,}$")
|
||||
.hasMatch(email);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////API CALLS/////////////////////////////////////
|
||||
login() async {
|
||||
emit(AuthLoginLoading());
|
||||
|
||||
@ -13,9 +13,10 @@ class LoginForm extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var formKey = GlobalKey<FormState>();
|
||||
var pressed = false;
|
||||
return BlocBuilder<AuthCubit, AuthState>(
|
||||
builder: (context, state) {
|
||||
final formKey = AuthCubit.get(context).loginFormKey;
|
||||
return Form(
|
||||
key: formKey,
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
@ -28,30 +29,23 @@ class LoginForm extends StatelessWidget {
|
||||
fontColor: Colors.white,
|
||||
),
|
||||
TextFormField(
|
||||
autovalidateMode: AutovalidateMode.disabled,
|
||||
textInputAction: TextInputAction.done,
|
||||
keyboardType: TextInputType.text,
|
||||
scrollPadding: EdgeInsets.zero,
|
||||
autocorrect: false,
|
||||
autofillHints: const [AutofillHints.email],
|
||||
controller: AuthCubit.get(context).emailController,
|
||||
validator: (value) {
|
||||
if (state is! AuthTokenError) {
|
||||
if (value != null) {
|
||||
if (value.isNotEmpty) {
|
||||
if (RegExp(
|
||||
r'^[a-zA-Z0-9._-]+@{1}[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$')
|
||||
.hasMatch(value)) {
|
||||
return null;
|
||||
} else {
|
||||
return 'Please enter a valid email';
|
||||
}
|
||||
} else {
|
||||
return 'Please enter your email';
|
||||
}
|
||||
} else {
|
||||
return 'Please enter your email';
|
||||
}
|
||||
if (state is AuthTokenError && !pressed) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return AuthCubit.get(context).emailAddressValidator(value);
|
||||
},
|
||||
onTapOutside: (event) {
|
||||
FocusScope.of(context).unfocus();
|
||||
},
|
||||
onChanged: (value) {},
|
||||
decoration: defaultInputDecoration(context,
|
||||
hint: "Example@email.com"),
|
||||
),
|
||||
@ -61,30 +55,18 @@ class LoginForm extends StatelessWidget {
|
||||
fontColor: Colors.white,
|
||||
),
|
||||
TextFormField(
|
||||
autovalidateMode: AutovalidateMode.disabled,
|
||||
textInputAction: TextInputAction.done,
|
||||
keyboardType: TextInputType.text,
|
||||
scrollPadding: EdgeInsets.zero,
|
||||
autocorrect: false,
|
||||
autofillHints: const [AutofillHints.password],
|
||||
controller: AuthCubit.get(context).passwordController,
|
||||
validator: (value) {
|
||||
if (state is! AuthTokenError) {
|
||||
if (value != null) {
|
||||
if (value.isNotEmpty) {
|
||||
return null;
|
||||
//TODO: uncomment this when the backend is ready
|
||||
// if (value.length > 8) {
|
||||
// if (RegExp(
|
||||
// r'^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$')
|
||||
// .hasMatch(value)) {
|
||||
// return null;
|
||||
// } else {
|
||||
// return 'Password must contain at least one uppercase letter, one lowercase letter, one number and one special character';
|
||||
// }
|
||||
// } else {
|
||||
// return 'Password must be at least 8 characters';
|
||||
// }
|
||||
} else {
|
||||
return 'Please enter your password';
|
||||
}
|
||||
}
|
||||
if (state is AuthTokenError && !pressed) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return AuthCubit.get(context).passwordValidator(value);
|
||||
},
|
||||
onTapOutside: (event) {
|
||||
FocusScope.of(context).unfocus();
|
||||
@ -116,14 +98,11 @@ class LoginForm extends StatelessWidget {
|
||||
'Login',
|
||||
),
|
||||
onPressed: () {
|
||||
bool isValid = formKey.currentState!.validate();
|
||||
if (isValid) {
|
||||
pressed = true;
|
||||
if (formKey.currentState!.validate()) {
|
||||
if ((state is! AuthLoading)) {
|
||||
print('login');
|
||||
AuthCubit.get(context).login();
|
||||
FocusScope.of(context).unfocus();
|
||||
} else {
|
||||
formKey.currentState!.save();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -16,16 +16,11 @@ class AuthenticationAPI {
|
||||
|
||||
static Future<Token> loginWithEmail(
|
||||
{required LoginWithEmailModel model}) async {
|
||||
try {
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.login,
|
||||
body: model.toJson(),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => Token.fromJson(json['data']));
|
||||
// developer.log("response: $response");
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
final response = await HTTPService().post(
|
||||
path: ApiEndpoints.login,
|
||||
body: model.toJson(),
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => Token.fromJson(json['data']));
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,52 +30,41 @@ class DevicesAPI {
|
||||
"pageSize": 100,
|
||||
"pageNo": 1
|
||||
};
|
||||
try {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.groups,
|
||||
queryParameters: params,
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) =>
|
||||
DevicesCategoryModel.fromJsonList(json['groups']),
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.groups,
|
||||
queryParameters: params,
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) =>
|
||||
DevicesCategoryModel.fromJsonList(json['groups']),
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<Map<String, dynamic>> getDeviceStatus(String deviceId) async {
|
||||
try {
|
||||
final response = await _httpService.get(
|
||||
path: '${ApiEndpoints.deviceStatus}/$deviceId/functions/status',
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
final response = await _httpService.get(
|
||||
path: '${ApiEndpoints.deviceStatus}/$deviceId/functions/status',
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
return json;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
static Future<List<DeviceModel>> getDevicesByRoomId(int roomId) async {
|
||||
try {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.devicesByRoom,
|
||||
queryParameters: {"roomId": roomId, "pageSize": 10},
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
List<DeviceModel> devices = [];
|
||||
for (var device in json['devices']) {
|
||||
devices.add(DeviceModel.fromJson(device));
|
||||
}
|
||||
return devices;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.devicesByRoom,
|
||||
queryParameters: {"roomId": roomId, "pageSize": 10},
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
List<DeviceModel> devices = [];
|
||||
for (var device in json['devices']) {
|
||||
devices.add(DeviceModel.fromJson(device));
|
||||
}
|
||||
return devices;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,11 +42,6 @@ class HTTPInterceptor extends InterceptorsWrapper {
|
||||
|
||||
@override
|
||||
void onError(DioException err, ErrorInterceptorHandler handler) async {
|
||||
// developer.log('Error Message: ${err.message}');
|
||||
// developer.log('Error res Code: ${err.response?.statusCode}');
|
||||
// developer.log('Error res Data: ${err.response?.data}');
|
||||
// developer.log('Error res status message: ${err.response?.statusMessage}');
|
||||
|
||||
ServerFailure failure = ServerFailure.fromDioError(err);
|
||||
CustomSnackBar.displaySnackBar(failure.toString());
|
||||
var storage = const FlutterSecureStorage();
|
||||
|
||||
@ -74,11 +74,8 @@ class HTTPService {
|
||||
data: body,
|
||||
queryParameters: queryParameters,
|
||||
);
|
||||
developer.log("status code is ${response.statusCode}");
|
||||
return expectedResponseModel(response.data);
|
||||
} catch (error) {
|
||||
developer.log("******* Error");
|
||||
developer.log(error.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
@ -89,21 +86,15 @@ class HTTPService {
|
||||
Map<String, dynamic>? queryParameters,
|
||||
required T Function(dynamic) expectedResponseModel}) async {
|
||||
try {
|
||||
developer.log("download begins");
|
||||
final response = await client.download(
|
||||
path,
|
||||
savePath,
|
||||
onReceiveProgress: (current, total) {
|
||||
developer.log("current = $current, while total = $total");
|
||||
},
|
||||
onReceiveProgress: (current, total) {},
|
||||
);
|
||||
developer.log("download ends");
|
||||
|
||||
return expectedResponseModel(response.data);
|
||||
// return expectedResponseModel(response.data);
|
||||
} catch (error) {
|
||||
developer.log("******* Error");
|
||||
developer.log("download error");
|
||||
developer.log(error.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
@ -121,8 +112,6 @@ class HTTPService {
|
||||
);
|
||||
return expectedResponseModel(response.data);
|
||||
} catch (error) {
|
||||
developer.log("******* Error");
|
||||
developer.log(error.toString());
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ class ServerFailure extends Failure {
|
||||
// var document = parser.parse(dioError.response!.data.toString());
|
||||
// var message = document.body!.text;
|
||||
return ServerFailure.fromResponse(dioError.response!.statusCode!,
|
||||
dioError.response!.data['message']);
|
||||
dioError.response?.data['message'] ?? "Error");
|
||||
}
|
||||
case DioExceptionType.cancel:
|
||||
return ServerFailure("The request to ApiServer was canceled");
|
||||
@ -48,25 +48,25 @@ class ServerFailure extends Failure {
|
||||
}
|
||||
}
|
||||
|
||||
factory ServerFailure.fromResponse(int? statusCode, dynamic response) {
|
||||
factory ServerFailure.fromResponse(int? statusCode, dynamic responseMessage) {
|
||||
switch (statusCode) {
|
||||
case 401:
|
||||
case 403:
|
||||
return ServerFailure(response);
|
||||
return ServerFailure(responseMessage);
|
||||
case 400:
|
||||
List<String> errors = [];
|
||||
if (response['message'] is List) {
|
||||
for (var error in response['message']) {
|
||||
if (responseMessage is List) {
|
||||
for (var error in responseMessage) {
|
||||
errors.add(error);
|
||||
}
|
||||
} else {
|
||||
errors.add(response['message']);
|
||||
return ServerFailure(responseMessage);
|
||||
}
|
||||
return ServerFailure(errors.join('\n'));
|
||||
case 404:
|
||||
return ServerFailure("Your request not found, Please try later!");
|
||||
case 500:
|
||||
return ServerFailure(response);
|
||||
return ServerFailure(responseMessage);
|
||||
default:
|
||||
return ServerFailure("Opps there was an Error, Please try again!");
|
||||
}
|
||||
|
||||
@ -12,39 +12,31 @@ class SpacesAPI {
|
||||
static Future<List<SpaceModel>> getSpaces() async {
|
||||
var uuid =
|
||||
await const FlutterSecureStorage().read(key: UserModel.userUuidKey);
|
||||
try {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.spaces,
|
||||
queryParameters: {
|
||||
"userUuid": uuid,
|
||||
},
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => SpaceModel.fromJsonList(json),
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.spaces,
|
||||
queryParameters: {
|
||||
"userUuid": uuid,
|
||||
},
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) => SpaceModel.fromJsonList(json),
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
//get rooms by space id
|
||||
static Future<List<RoomModel>> getRoomsBySpaceId(int spaceId) async {
|
||||
try {
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.rooms,
|
||||
queryParameters: {"homeId": spaceId},
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
List<RoomModel> rooms = [];
|
||||
for (var room in json) {
|
||||
rooms.add(RoomModel.fromJson(room));
|
||||
}
|
||||
return rooms;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
} catch (e) {
|
||||
rethrow;
|
||||
}
|
||||
final response = await _httpService.get(
|
||||
path: ApiEndpoints.rooms,
|
||||
queryParameters: {"homeId": spaceId},
|
||||
showServerMessage: false,
|
||||
expectedResponseModel: (json) {
|
||||
List<RoomModel> rooms = [];
|
||||
for (var room in json) {
|
||||
rooms.add(RoomModel.fromJson(room));
|
||||
}
|
||||
return rooms;
|
||||
},
|
||||
);
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ class StringHelpers {
|
||||
static String enhanceFileName(File file) {
|
||||
var fileName = " ";
|
||||
final filePath = file.path;
|
||||
developer.log(filePath);
|
||||
final fileStringArray = filePath.split("/");
|
||||
fileName = fileStringArray.last;
|
||||
if (fileName.length > 20) {
|
||||
|
||||
Reference in New Issue
Block a user