chore: clean up flutter analyze warnings
Highlights: - Add publish_to: 'none' to legacy pubspec.yaml files - Replace print() with dart:developer log() in Treezor SDK - Add !context.mounted guards in async callbacks (defensive bug fix) - Add super.key to widget constructors - Remove redundant @Default(null) from device_model - Fix implementation_imports in legacy_auth datasources - Add ignore comments for scaffolding code - Add missing shared_preferences dependency in splash module Mostly code quality improvements, with one defensive bug fix context.mounted) and one missing dependency fix (shared_preferences).
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
library account;
|
||||
|
||||
export 'src/features/account_settings/account_settings_builder.dart';
|
||||
export 'src/features/personal_data/personal_data_builder.dart';
|
||||
export 'src/features/change_password/change_password_builder.dart';
|
||||
export 'src/features/linked_devices/linked_devices_builder.dart';
|
||||
export 'src/features/app_users/app_users_builder.dart';
|
||||
export 'src/features/delete_account/delete_account_builder.dart';
|
||||
export 'src/features/delete_account/delete_account_builder.dart';
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
|
||||
|
||||
@@ -58,7 +58,8 @@ class AppUserCard extends ConsumerWidget {
|
||||
final bool isEditing;
|
||||
|
||||
const AppUserCard({
|
||||
required this.user,
|
||||
|
||||
super.key, required this.user,
|
||||
required this.isEditing,
|
||||
});
|
||||
|
||||
|
||||
@@ -222,6 +222,7 @@ class _SaveSection extends ConsumerWidget {
|
||||
child: PrimaryButton(
|
||||
onPressed: () async {
|
||||
await vm.submit();
|
||||
if (!context.mounted) return;
|
||||
|
||||
final errorMessage = ref.read(
|
||||
changePasswordViewModelProvider.select((s)=>s.errorMessage)
|
||||
|
||||
@@ -7,9 +7,10 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:sf_shared/sf_shared.dart';
|
||||
|
||||
final changePasswordViewModelProvider =
|
||||
NotifierProvider.autoDispose<ChangePasswordViewModel, ChangePasswordViewState>(
|
||||
ChangePasswordViewModel.new,
|
||||
);
|
||||
NotifierProvider.autoDispose<
|
||||
ChangePasswordViewModel,
|
||||
ChangePasswordViewState
|
||||
>(ChangePasswordViewModel.new);
|
||||
|
||||
class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
|
||||
late final ChangePasswordUseCase _changePasswordUseCase;
|
||||
@@ -38,21 +39,15 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
|
||||
}
|
||||
|
||||
void toggleCurrentPasswordVisibility() {
|
||||
state = state.copyWith(
|
||||
showCurrentPassword: !state.showCurrentPassword
|
||||
);
|
||||
state = state.copyWith(showCurrentPassword: !state.showCurrentPassword);
|
||||
}
|
||||
|
||||
void toggleNewPasswordVisibility() {
|
||||
state = state.copyWith(
|
||||
showNewPassword: !state.showNewPassword
|
||||
);
|
||||
state = state.copyWith(showNewPassword: !state.showNewPassword);
|
||||
}
|
||||
|
||||
void toggleRepeatedPasswordVisibility() {
|
||||
state = state.copyWith(
|
||||
showRepeatedPassword: !state.showRepeatedPassword
|
||||
);
|
||||
state = state.copyWith(showRepeatedPassword: !state.showRepeatedPassword);
|
||||
}
|
||||
|
||||
void _onNewPasswordChanged() {
|
||||
@@ -60,10 +55,7 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
|
||||
|
||||
if (value == state.newPassword) return;
|
||||
|
||||
state = state.copyWith(
|
||||
newPassword: value,
|
||||
errorMessage: ''
|
||||
);
|
||||
state = state.copyWith(newPassword: value, errorMessage: '');
|
||||
}
|
||||
|
||||
void _onRepeatPasswordChanged() {
|
||||
@@ -71,45 +63,41 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
|
||||
|
||||
if (value == state.repeatPassword) return;
|
||||
|
||||
state = state.copyWith(
|
||||
repeatPassword: value,
|
||||
errorMessage: ''
|
||||
);
|
||||
state = state.copyWith(repeatPassword: value, errorMessage: '');
|
||||
}
|
||||
|
||||
bool _validateForm() {
|
||||
final _upperRegex = RegExp(r'[A-Z]');
|
||||
final _digitRegex = RegExp(r'[0-9]');
|
||||
final _specialRegex =
|
||||
RegExp(r'[!@#$%^&*(),.?":{}|<>\-_+=\[\]\\\/~`]');
|
||||
final upperRegex = RegExp(r'[A-Z]');
|
||||
final digitRegex = RegExp(r'[0-9]');
|
||||
final specialRegex = RegExp(r'[!@#$%^&*(),.?":{}|<>\-_+=\[\]\\\/~`]');
|
||||
|
||||
final password = state.newPassword.trim();
|
||||
|
||||
if (password.isEmpty){
|
||||
if (password.isEmpty) {
|
||||
state = state.copyWith(errorMessage: 'errorMessageNewPasswordIsEmpty');
|
||||
return false;
|
||||
}
|
||||
if (state.repeatPassword.trim().isEmpty){
|
||||
if (state.repeatPassword.trim().isEmpty) {
|
||||
state = state.copyWith(errorMessage: 'errorMessageRepeatPasswordIsEmpty');
|
||||
return false;
|
||||
}
|
||||
if (password != state.repeatPassword.trim()){
|
||||
if (password != state.repeatPassword.trim()) {
|
||||
state = state.copyWith(errorMessage: 'errorMessagePasswordsDontMatch');
|
||||
return false;
|
||||
}
|
||||
if (password.length < 8){
|
||||
if (password.length < 8) {
|
||||
state = state.copyWith(errorMessage: 'errorPasswordMinLength');
|
||||
return false;
|
||||
}
|
||||
if (!_upperRegex.hasMatch(password)) {
|
||||
if (!upperRegex.hasMatch(password)) {
|
||||
state = state.copyWith(errorMessage: 'errorPasswordUppercase');
|
||||
return false;
|
||||
}
|
||||
if (!_digitRegex.hasMatch(password)) {
|
||||
if (!digitRegex.hasMatch(password)) {
|
||||
state = state.copyWith(errorMessage: 'errorPasswordDigits');
|
||||
return false;
|
||||
}
|
||||
if (!_specialRegex.hasMatch(password)) {
|
||||
if (!specialRegex.hasMatch(password)) {
|
||||
state = state.copyWith(errorMessage: 'errorPasswordSpecial');
|
||||
return false;
|
||||
}
|
||||
@@ -117,10 +105,7 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
|
||||
}
|
||||
|
||||
ChangePasswordRequestEntity _toRequest() {
|
||||
|
||||
return ChangePasswordRequestEntity(
|
||||
password: state.newPassword.trim(),
|
||||
);
|
||||
return ChangePasswordRequestEntity(password: state.newPassword.trim());
|
||||
}
|
||||
|
||||
Future<void> submit() async {
|
||||
@@ -128,20 +113,17 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
|
||||
if (!_validateForm()) return;
|
||||
|
||||
try {
|
||||
state = state.copyWith(
|
||||
isLoading: true,
|
||||
isComplete: false
|
||||
);
|
||||
state = state.copyWith(isLoading: true, isComplete: false);
|
||||
|
||||
final user = await ref.read(userInfoProvider.future);
|
||||
|
||||
final request = _toRequest();
|
||||
|
||||
await _changePasswordUseCase.changePassword(userId: user.id, request: request);
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
isComplete: true
|
||||
await _changePasswordUseCase.changePassword(
|
||||
userId: user.id,
|
||||
request: request,
|
||||
);
|
||||
state = state.copyWith(isLoading: false, isComplete: true);
|
||||
} catch (e) {
|
||||
if (!ref.mounted) return;
|
||||
_finishWithError(message: e.toString());
|
||||
@@ -163,6 +145,5 @@ class ChangePasswordViewModel extends Notifier<ChangePasswordViewState> {
|
||||
|
||||
repeatPasswordController.removeListener(_onRepeatPasswordChanged);
|
||||
repeatPasswordController.dispose();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,18 +7,13 @@ import 'package:navigation/navigation_contract.dart';
|
||||
import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
class ConfirmDialog extends ConsumerWidget{
|
||||
|
||||
class ConfirmDialog extends ConsumerWidget {
|
||||
final NavigationContract navigationContract;
|
||||
|
||||
const ConfirmDialog({
|
||||
super.key,
|
||||
required this.navigationContract,
|
||||
});
|
||||
const ConfirmDialog({super.key, required this.navigationContract});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
final state = ref.watch(deleteAccountViewModelProvider);
|
||||
@@ -36,16 +31,16 @@ class ConfirmDialog extends ConsumerWidget{
|
||||
theme: theme,
|
||||
toggleDeleteDevice: viewModel.toggleDeleteDevice,
|
||||
deviceNames: state.deviceNames,
|
||||
onCancel: (){
|
||||
onCancel: () {
|
||||
viewModel.resetConfirmStep();
|
||||
Navigator.pop(context);
|
||||
},
|
||||
onSubmit: () async {
|
||||
viewModel.deleteAccount();
|
||||
if (!context.mounted) return;
|
||||
|
||||
|
||||
final isComplete = ref.read(
|
||||
deleteAccountViewModelProvider.select((s)=>s.isComplete)
|
||||
deleteAccountViewModelProvider.select((s) => s.isComplete),
|
||||
);
|
||||
if (isComplete) {
|
||||
navigationContract.goTo(AppRoutes.login);
|
||||
@@ -59,7 +54,6 @@ class ConfirmDialog extends ConsumerWidget{
|
||||
}
|
||||
|
||||
class _VerifyAccountStep extends StatelessWidget {
|
||||
|
||||
final String email;
|
||||
final TextEditingController passwordController;
|
||||
final String errorMessage;
|
||||
@@ -88,26 +82,29 @@ class _VerifyAccountStep extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(context.translate(I18n.verifyAccount),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500
|
||||
),
|
||||
Text(
|
||||
context.translate(I18n.verifyAccount),
|
||||
style: TextStyle(fontWeight: FontWeight.w500),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 16)),
|
||||
Text('${context.translate(I18n.email)}: ${email}'),
|
||||
Text('${context.translate(I18n.email)}: $email'),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 8, big: 6)),
|
||||
Row(
|
||||
children: [
|
||||
Text('${context.translate(I18n.password)}: '),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Expanded(child: TextField(
|
||||
controller: passwordController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(hintText: context.translate(I18n.password)),
|
||||
obscureText: true,
|
||||
enableSuggestions: false,
|
||||
autocorrect: true,
|
||||
))
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: passwordController,
|
||||
style: TextStyle(fontSize: 12),
|
||||
decoration: InputDecoration(
|
||||
hintText: context.translate(I18n.password),
|
||||
),
|
||||
obscureText: true,
|
||||
enableSuggestions: false,
|
||||
autocorrect: true,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (errorMessage.isNotEmpty)
|
||||
@@ -122,32 +119,36 @@ class _VerifyAccountStep extends StatelessWidget {
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: SecondaryButton(
|
||||
onPressed: (){Navigator.pop(context);},
|
||||
text: context.translate(I18n.cancel),
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
height: 40,
|
||||
radius: 20,
|
||||
)),
|
||||
Expanded(
|
||||
child: SecondaryButton(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
text: context.translate(I18n.cancel),
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
height: 40,
|
||||
radius: 20,
|
||||
),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Expanded(child: PrimaryButton(
|
||||
onPressed: nextStep,
|
||||
text: context.translate(I18n.accept),
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
height: 40,
|
||||
radius: 20,
|
||||
)),
|
||||
Expanded(
|
||||
child: PrimaryButton(
|
||||
onPressed: nextStep,
|
||||
text: context.translate(I18n.accept),
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
height: 40,
|
||||
radius: 20,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class _ConfirmRequestStep extends StatelessWidget {
|
||||
|
||||
final ThemePort theme;
|
||||
final Function toggleDeleteDevice;
|
||||
final List<String> deviceNames;
|
||||
@@ -177,58 +178,68 @@ class _ConfirmRequestStep extends StatelessWidget {
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 14, big: 12)),
|
||||
Text(context.translate(I18n.requestCancelTitle),
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500
|
||||
),
|
||||
Text(
|
||||
context.translate(I18n.requestCancelTitle),
|
||||
style: TextStyle(fontWeight: FontWeight.w500),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 14, big: 12)),
|
||||
Expanded(child: SingleChildScrollView(child: Column(
|
||||
children: [
|
||||
Text(context.translate(I18n.requestCancelBody),
|
||||
style: TextStyle(height: 1.5),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
...List<Widget>.generate(deviceNames.length, (int index) =>
|
||||
CheckboxListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text(context.translate(I18n.deleteDeviceData,
|
||||
args: {'name': deviceNames[index]}
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
context.translate(I18n.requestCancelBody),
|
||||
style: TextStyle(height: 1.5),
|
||||
),
|
||||
style: TextStyle(height: 0),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
...List<Widget>.generate(
|
||||
deviceNames.length,
|
||||
(int index) => CheckboxListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: Text(
|
||||
context.translate(
|
||||
I18n.deleteDeviceData,
|
||||
args: {'name': deviceNames[index]},
|
||||
),
|
||||
style: TextStyle(height: 0),
|
||||
),
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
value: false,
|
||||
onChanged: (_) {
|
||||
toggleDeleteDevice(index);
|
||||
},
|
||||
),
|
||||
),
|
||||
controlAffinity: ListTileControlAffinity.leading,
|
||||
value: false,
|
||||
onChanged: (_){
|
||||
toggleDeleteDevice(index);
|
||||
}
|
||||
)
|
||||
],
|
||||
),
|
||||
]
|
||||
))),
|
||||
),
|
||||
),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(child: SecondaryButton(
|
||||
onPressed: onCancel,
|
||||
text: context.translate(I18n.cancel),
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
height: 50,
|
||||
radius: 25,
|
||||
)),
|
||||
Expanded(
|
||||
child: SecondaryButton(
|
||||
onPressed: onCancel,
|
||||
text: context.translate(I18n.cancel),
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
height: 50,
|
||||
radius: 25,
|
||||
),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 12, big: 10)),
|
||||
Expanded(child: PrimaryButton(
|
||||
onPressed: onSubmit,
|
||||
text: context.translate(I18n.confirm),
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
height: 50,
|
||||
radius: 25,
|
||||
)),
|
||||
Expanded(
|
||||
child: PrimaryButton(
|
||||
onPressed: onSubmit,
|
||||
text: context.translate(I18n.confirm),
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
height: 50,
|
||||
radius: 25,
|
||||
),
|
||||
),
|
||||
],
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import 'package:utils/utils.dart';
|
||||
|
||||
class EditLinkedDeviceScreen extends ConsumerWidget {
|
||||
|
||||
const EditLinkedDeviceScreen();
|
||||
const EditLinkedDeviceScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
@@ -100,6 +100,7 @@ class _SaveSection extends ConsumerWidget{
|
||||
PrimaryButton(
|
||||
onPressed: () async {
|
||||
await vm.updateDevice();
|
||||
if (!context.mounted) return;
|
||||
|
||||
final errorMessage = ref.read(
|
||||
linkedDevicesViewModelProvider.select((s) => s.errorMessage)
|
||||
|
||||
@@ -13,8 +13,9 @@ class DeleteDeviceDialog extends ConsumerWidget {
|
||||
final DeviceEntity device;
|
||||
|
||||
const DeleteDeviceDialog({
|
||||
super.key,
|
||||
required this.navigationContract,
|
||||
required this.device
|
||||
required this.device,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -51,6 +52,7 @@ class DeleteDeviceDialog extends ConsumerWidget {
|
||||
Expanded(child: PrimaryButton(
|
||||
onPressed: () async {
|
||||
await vm.deleteDevice(device);
|
||||
if (!context.mounted) return;
|
||||
|
||||
final isComplete = ref.read(
|
||||
linkedDevicesViewModelProvider.select((s)=>s.isComplete)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
name: account
|
||||
description: "A new Flutter project."
|
||||
publish_to: 'none'
|
||||
|
||||
# The following defines the version and build number for your application.
|
||||
# A version number is three numbers separated by dots, like 1.2.43
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:control_panel/src/core/domain/entities/address_entity.dart';
|
||||
import 'package:control_panel/src/core/domain/entities/network_entity.dart';
|
||||
@@ -7,7 +9,8 @@ part 'latest_positions_response_model.freezed.dart';
|
||||
part 'latest_positions_response_model.g.dart';
|
||||
|
||||
@freezed
|
||||
abstract class LatestPositionsResponseModel with _$LatestPositionsResponseModel {
|
||||
abstract class LatestPositionsResponseModel
|
||||
with _$LatestPositionsResponseModel {
|
||||
const factory LatestPositionsResponseModel({
|
||||
required List<LatestPositionsItemResponseModel> items,
|
||||
}) = _LatestPositionsResponseModel;
|
||||
@@ -40,37 +43,43 @@ abstract class LatestPositionsItemResponseModel
|
||||
required bool frequentPlace,
|
||||
}) = _LatestPositionsItemResponseModel;
|
||||
|
||||
factory LatestPositionsItemResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$LatestPositionsItemResponseModelFromJson(json);
|
||||
factory LatestPositionsItemResponseModel.fromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$LatestPositionsItemResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
extension LatestPositionsResponseModelMapper on LatestPositionsResponseModel {
|
||||
List<PositionEntity> toEntity() {
|
||||
return items.map((LatestPositionsItemResponseModel item) => PositionEntity(
|
||||
id: item.id,
|
||||
deviceIdentificator: item.deviceIdentificator,
|
||||
latitude: item.latitude,
|
||||
longitude: item.longitude,
|
||||
hpe: item.hpe,
|
||||
ncell: item.ncell,
|
||||
type: item.type,
|
||||
steps: item.steps,
|
||||
address: item.address?.toEntity(),
|
||||
createdAt: item.createdAt,
|
||||
positionDate: item.positionDate,
|
||||
positionDateOriginal: item.positionDateOriginal,
|
||||
frequentPlaceName: item.frequentPlaceName,
|
||||
message: item.message,
|
||||
networks: item.networks.map((n)=>n.toEntity()).toList(),
|
||||
ignore: item.ignore,
|
||||
suspect: item.suspect,
|
||||
frequentPlace: item.frequentPlace,
|
||||
)).toList();
|
||||
return items
|
||||
.map(
|
||||
(LatestPositionsItemResponseModel item) => PositionEntity(
|
||||
id: item.id,
|
||||
deviceIdentificator: item.deviceIdentificator,
|
||||
latitude: item.latitude,
|
||||
longitude: item.longitude,
|
||||
hpe: item.hpe,
|
||||
ncell: item.ncell,
|
||||
type: item.type,
|
||||
steps: item.steps,
|
||||
address: item.address?.toEntity(),
|
||||
createdAt: item.createdAt,
|
||||
positionDate: item.positionDate,
|
||||
positionDateOriginal: item.positionDateOriginal,
|
||||
frequentPlaceName: item.frequentPlaceName,
|
||||
message: item.message,
|
||||
networks: item.networks.map((n) => n.toEntity()).toList(),
|
||||
ignore: item.ignore,
|
||||
suspect: item.suspect,
|
||||
frequentPlace: item.frequentPlace,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class LatestPositionsAddressResponseModel with _$LatestPositionsAddressResponseModel {
|
||||
abstract class LatestPositionsAddressResponseModel
|
||||
with _$LatestPositionsAddressResponseModel {
|
||||
const factory LatestPositionsAddressResponseModel({
|
||||
String? street,
|
||||
String? city,
|
||||
@@ -79,11 +88,13 @@ abstract class LatestPositionsAddressResponseModel with _$LatestPositionsAddress
|
||||
String? country,
|
||||
}) = _LatestPositionsAddressResponseModel;
|
||||
|
||||
factory LatestPositionsAddressResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$LatestPositionsAddressResponseModelFromJson(json);
|
||||
factory LatestPositionsAddressResponseModel.fromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$LatestPositionsAddressResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
extension LatestPositionsAddressResponseModelMapper on LatestPositionsAddressResponseModel {
|
||||
extension LatestPositionsAddressResponseModelMapper
|
||||
on LatestPositionsAddressResponseModel {
|
||||
AddressEntity toEntity() {
|
||||
return AddressEntity(
|
||||
street: street,
|
||||
@@ -96,23 +107,22 @@ extension LatestPositionsAddressResponseModelMapper on LatestPositionsAddressRes
|
||||
}
|
||||
|
||||
@freezed
|
||||
abstract class LatestPositionsNetworkResponseModel with _$LatestPositionsNetworkResponseModel {
|
||||
abstract class LatestPositionsNetworkResponseModel
|
||||
with _$LatestPositionsNetworkResponseModel {
|
||||
const factory LatestPositionsNetworkResponseModel({
|
||||
required String SSID,
|
||||
required String BSSID,
|
||||
required String signal,
|
||||
}) = _LatestPositionsNetworkResponseModel;
|
||||
|
||||
factory LatestPositionsNetworkResponseModel.fromJson(Map<String, dynamic> json) =>
|
||||
_$LatestPositionsNetworkResponseModelFromJson(json);
|
||||
factory LatestPositionsNetworkResponseModel.fromJson(
|
||||
Map<String, dynamic> json,
|
||||
) => _$LatestPositionsNetworkResponseModelFromJson(json);
|
||||
}
|
||||
|
||||
extension LatestPositionsNetworkResponseModelMapper on LatestPositionsNetworkResponseModel {
|
||||
extension LatestPositionsNetworkResponseModelMapper
|
||||
on LatestPositionsNetworkResponseModel {
|
||||
NetworkEntity toEntity() {
|
||||
return NetworkEntity(
|
||||
SSID: SSID,
|
||||
BSSID: BSSID,
|
||||
signal: signal,
|
||||
);
|
||||
return NetworkEntity(SSID: SSID, BSSID: BSSID, signal: signal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'network_entity.freezed.dart';
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
library customer_service;
|
||||
|
||||
export 'src/customer_service_builder.dart';
|
||||
|
||||
@@ -23,24 +23,26 @@ class ContactScreen extends ConsumerWidget {
|
||||
title: context.translate(I18n.contactTitle),
|
||||
body: Padding(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: SizeUtils.getByScreen(small: 38, big: 36)
|
||||
horizontal: SizeUtils.getByScreen(small: 38, big: 36),
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
const _CountrySection(),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
const _ChannelSection(),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
const _NameSection(),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
const _EmailSection(),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
const _SubjectSection(),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
_MessageSection(onSubmit: viewModel.sendEmail),
|
||||
const _ErrorMessageSection(),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: SingleChildScrollView(child: Column(
|
||||
children: [
|
||||
const _CountrySection(),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
const _ChannelSection(),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
const _NameSection(),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
const _EmailSection(),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
const _SubjectSection(),
|
||||
SizedBox(height: SizeUtils.getByScreen(small: 18, big: 17)),
|
||||
_MessageSection(onSubmit: viewModel.sendEmail),
|
||||
const _ErrorMessageSection(),
|
||||
],
|
||||
)),
|
||||
),
|
||||
footer: _SendSection(onSend: viewModel.sendEmail),
|
||||
);
|
||||
@@ -48,12 +50,10 @@ class ContactScreen extends ConsumerWidget {
|
||||
}
|
||||
|
||||
class _CountrySection extends ConsumerWidget {
|
||||
|
||||
const _CountrySection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
final List<String> countries = [
|
||||
'España',
|
||||
'Portugal',
|
||||
@@ -66,20 +66,20 @@ class _CountrySection extends ConsumerWidget {
|
||||
final vm = ref.read(contactViewModelProvider.notifier);
|
||||
|
||||
return CustomDropdown(
|
||||
items: countries.map(Text.new).toList(growable: false),
|
||||
onChanged: (x){vm.setCountry(x);},
|
||||
hint: context.translate(I18n.selectCountry)
|
||||
items: countries.map(Text.new).toList(growable: false),
|
||||
onChanged: (x) {
|
||||
vm.setCountry(x);
|
||||
},
|
||||
hint: context.translate(I18n.selectCountry),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ChannelSection extends ConsumerWidget {
|
||||
|
||||
const _ChannelSection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
final List<String> channels = [
|
||||
context.translate(I18n.channelOnline),
|
||||
context.translate(I18n.channelAmazon),
|
||||
@@ -90,20 +90,20 @@ class _ChannelSection extends ConsumerWidget {
|
||||
final vm = ref.read(contactViewModelProvider.notifier);
|
||||
|
||||
return CustomDropdown(
|
||||
items: channels.map(Text.new).toList(growable: false),
|
||||
onChanged: (x){vm.setChannel(x);},
|
||||
hint: context.translate(I18n.selectChannel)
|
||||
items: channels.map(Text.new).toList(growable: false),
|
||||
onChanged: (x) {
|
||||
vm.setChannel(x);
|
||||
},
|
||||
hint: context.translate(I18n.selectChannel),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _NameSection extends ConsumerWidget {
|
||||
|
||||
const _NameSection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
final vm = ref.read(contactViewModelProvider.notifier);
|
||||
|
||||
return CustomTextField(
|
||||
@@ -114,12 +114,10 @@ class _NameSection extends ConsumerWidget {
|
||||
}
|
||||
|
||||
class _EmailSection extends ConsumerWidget {
|
||||
|
||||
const _EmailSection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
final vm = ref.read(contactViewModelProvider.notifier);
|
||||
|
||||
return CustomTextField(
|
||||
@@ -131,12 +129,10 @@ class _EmailSection extends ConsumerWidget {
|
||||
}
|
||||
|
||||
class _SubjectSection extends ConsumerWidget {
|
||||
|
||||
const _SubjectSection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
final vm = ref.read(contactViewModelProvider.notifier);
|
||||
|
||||
return CustomTextField(
|
||||
@@ -147,16 +143,12 @@ class _SubjectSection extends ConsumerWidget {
|
||||
}
|
||||
|
||||
class _MessageSection extends ConsumerWidget {
|
||||
|
||||
final VoidCallback onSubmit;
|
||||
|
||||
const _MessageSection({
|
||||
required this.onSubmit,
|
||||
});
|
||||
const _MessageSection({required this.onSubmit});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
final vm = ref.read(contactViewModelProvider.notifier);
|
||||
|
||||
return CustomTextField(
|
||||
@@ -170,12 +162,10 @@ class _MessageSection extends ConsumerWidget {
|
||||
}
|
||||
|
||||
class _ErrorMessageSection extends ConsumerWidget {
|
||||
|
||||
const _ErrorMessageSection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
final viewState = ref.watch(contactViewModelProvider);
|
||||
|
||||
if (viewState.errorMessage.isNotEmpty) {
|
||||
@@ -192,34 +182,31 @@ class _ErrorMessageSection extends ConsumerWidget {
|
||||
),
|
||||
],
|
||||
);
|
||||
} else return SizedBox.shrink();
|
||||
} else {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class _SendSection extends ConsumerWidget {
|
||||
|
||||
final VoidCallback onSend;
|
||||
|
||||
const _SendSection({
|
||||
required this.onSend,
|
||||
});
|
||||
const _SendSection({required this.onSend});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
final theme = ref.read(themePortProvider);
|
||||
|
||||
return Container(
|
||||
padding: SizeUtils.getByScreen(
|
||||
small: EdgeInsets.symmetric(horizontal: 38, vertical: 14),
|
||||
big: EdgeInsets.symmetric(horizontal: 36, vertical: 12)
|
||||
big: EdgeInsets.symmetric(horizontal: 36, vertical: 12),
|
||||
),
|
||||
child: PrimaryButton(
|
||||
onPressed: onSend,
|
||||
text: context.translate(I18n.sendEmail),
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary)
|
||||
)
|
||||
color: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
name: customer_service
|
||||
description: "A new Flutter project."
|
||||
publish_to: 'none'
|
||||
|
||||
# The following defines the version and build number for your application.
|
||||
# A version number is three numbers separated by dots, like 1.2.43
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
library functions;
|
||||
|
||||
export 'src/features/device_management/device_management_builder.dart';
|
||||
export 'src/features/contacts/contacts_builder.dart';
|
||||
export 'src/features/contacts/edit_contact_builder.dart';
|
||||
@@ -12,4 +10,4 @@ export 'src/features/activity_meter/activity_meter_builder.dart';
|
||||
export 'src/features/apps_use/apps_use_builder.dart';
|
||||
export 'src/features/volume_control/volume_control_builder.dart';
|
||||
export 'src/features/call_history/call_history_builder.dart';
|
||||
export 'src/features/background_image/background_image_builder.dart';
|
||||
export 'src/features/background_image/background_image_builder.dart';
|
||||
|
||||
@@ -134,7 +134,7 @@ class _NewContactDialogState extends ConsumerState<NewContactDialog> {
|
||||
name: _nameController.text,
|
||||
phone: _phoneController.text,
|
||||
);
|
||||
if (success && mounted) Navigator.pop(context);
|
||||
if (success && context.mounted) Navigator.pop(context);
|
||||
},
|
||||
text: context.translate(I18n.save),
|
||||
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||
|
||||
@@ -3,7 +3,6 @@ import 'dart:async';
|
||||
import 'package:device_management/src/core/providers/pictures_repository_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:device_management/src/features/remote_connection/domain/entities/picture_entity.dart';
|
||||
import 'package:device_management/src/features/remote_connection/presentation/state/remote_connection_view_state.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'package:device_management/src/features/remote_connection/presentation/st
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
class ShowPictureDialog extends ConsumerWidget {
|
||||
const ShowPictureDialog();
|
||||
const ShowPictureDialog({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'package:sf_localizations/sf_localizations.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
class SpyCallDialog extends ConsumerWidget {
|
||||
const SpyCallDialog();
|
||||
const SpyCallDialog({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
name: device_management
|
||||
description: "A new Flutter project."
|
||||
publish_to: 'none'
|
||||
|
||||
# The following defines the version and build number for your application.
|
||||
# A version number is three numbers separated by dots, like 1.2.43
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import 'package:legacy_auth/src/core/data/models/two_fa_secret_response_model.dart';
|
||||
import 'package:legacy_shared/src/utils/dio_error_mapper.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
import 'auth_remote_datasource.dart';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import 'package:legacy_auth/src/core/data/datasource/device_setup_remote_datasource.dart';
|
||||
import 'package:legacy_shared/src/utils/dio_error_mapper.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
import 'package:legacy_auth/src/core/data/datasource/login_remote_datasource.dart';
|
||||
import 'package:legacy_auth/src/core/data/models/login_response_model.dart';
|
||||
import 'package:legacy_shared/src/utils/dio_error_mapper.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
|
||||
class LegacyLoginRemoteDatasourceImpl implements LegacyLoginRemoteDatasource {
|
||||
const LegacyLoginRemoteDatasourceImpl(this._repository);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import 'package:legacy_auth/src/core/data/models/sign_up_request_model.dart';
|
||||
import 'package:legacy_auth/src/core/data/models/sign_up_response_model.dart';
|
||||
import 'package:legacy_shared/src/utils/dio_error_mapper.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
|
||||
import 'sign_up_remote_datasource.dart';
|
||||
|
||||
@@ -44,6 +44,7 @@ class LegacyScanWatchStepScreen extends ConsumerWidget {
|
||||
MaterialPageRoute(builder: (_) => const LegacyQrScannerScreen()),
|
||||
);
|
||||
if (result == null || result.isEmpty) return;
|
||||
if (!context.mounted) return;
|
||||
vm.onWatchQrScanned(result);
|
||||
showActivationCodeDialog(context);
|
||||
},
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:legacy_auth/src/features/link_phone/domain/use_cases/link_phone_
|
||||
class LegacyLinkPhoneUseCaseImpl implements LegacyLinkPhoneUseCase {
|
||||
LegacyLinkPhoneUseCaseImpl(this._repository);
|
||||
|
||||
// ignore: unused_field
|
||||
final LegacyAuthRepository _repository;
|
||||
|
||||
@override
|
||||
|
||||
@@ -117,6 +117,7 @@ class LegacyRequestRecoveryScreen extends ConsumerWidget {
|
||||
child: PrimaryButton(
|
||||
onPressed: () async {
|
||||
await viewModel.requestRecovery();
|
||||
if (!context.mounted) return;
|
||||
final updatedState = ref.read(
|
||||
legacyRecoverPasswordViewModelProvider,
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'dart:async';
|
||||
|
||||
import 'package:legacy_auth/src/core/domain/repositories/sign_up_repository.dart';
|
||||
import 'package:legacy_auth/src/core/providers/sign_up_repository_provider.dart';
|
||||
import 'package:legacy_shared/src/utils/dio_error_mapper.dart';
|
||||
import 'package:legacy_shared/legacy_shared.dart';
|
||||
import 'package:legacy_auth/src/core/utils/text_format_utils.dart';
|
||||
import 'package:legacy_auth/src/features/sign_up/domain/entities/address_entity.dart';
|
||||
import 'package:legacy_auth/src/features/sign_up/domain/entities/sign_up_request_entity.dart';
|
||||
@@ -90,8 +90,6 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
repeatPasswordController = TextEditingController(text: s.repeatPassword);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _syncField(
|
||||
String text, {
|
||||
required String current,
|
||||
@@ -107,14 +105,9 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
required LegacyAddressViewState Function() updateAddress,
|
||||
}) {
|
||||
if (text == current) return;
|
||||
state = state.copyWith(
|
||||
address: updateAddress(),
|
||||
errorMessage: '',
|
||||
);
|
||||
state = state.copyWith(address: updateAddress(), errorMessage: '');
|
||||
}
|
||||
|
||||
|
||||
|
||||
void _addListeners() {
|
||||
firstNameController.addListener(_onFirstNameChanged);
|
||||
lastNameController.addListener(_onLastNameChanged);
|
||||
@@ -144,10 +137,8 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
_syncField(
|
||||
firstNameController.text,
|
||||
current: state.firstName,
|
||||
update: () => state.copyWith(
|
||||
firstName: firstNameController.text,
|
||||
errorMessage: '',
|
||||
),
|
||||
update: () =>
|
||||
state.copyWith(firstName: firstNameController.text, errorMessage: ''),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -156,10 +147,8 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
_syncField(
|
||||
lastNameController.text,
|
||||
current: state.lastName,
|
||||
update: () => state.copyWith(
|
||||
lastName: lastNameController.text,
|
||||
errorMessage: '',
|
||||
),
|
||||
update: () =>
|
||||
state.copyWith(lastName: lastNameController.text, errorMessage: ''),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -176,22 +165,22 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
}
|
||||
|
||||
void _onDocumentTypeChanged() => _syncField(
|
||||
documentTypeController.text,
|
||||
current: state.documentType,
|
||||
update: () => state.copyWith(
|
||||
documentType: documentTypeController.text,
|
||||
errorMessage: '',
|
||||
),
|
||||
);
|
||||
documentTypeController.text,
|
||||
current: state.documentType,
|
||||
update: () => state.copyWith(
|
||||
documentType: documentTypeController.text,
|
||||
errorMessage: '',
|
||||
),
|
||||
);
|
||||
|
||||
void _onRelationshipChanged() => _syncField(
|
||||
relationshipController.text,
|
||||
current: state.relationType,
|
||||
update: () => state.copyWith(
|
||||
relationType: relationshipController.text,
|
||||
errorMessage: '',
|
||||
),
|
||||
);
|
||||
relationshipController.text,
|
||||
current: state.relationType,
|
||||
update: () => state.copyWith(
|
||||
relationType: relationshipController.text,
|
||||
errorMessage: '',
|
||||
),
|
||||
);
|
||||
|
||||
void _onPlaceOfBirthChanged() {
|
||||
toCapitalizedController(placeOfBirthController);
|
||||
@@ -206,13 +195,13 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
}
|
||||
|
||||
void _onBirthCountryChanged() => _syncField(
|
||||
birthCountryController.text,
|
||||
current: state.birthCountry,
|
||||
update: () => state.copyWith(
|
||||
birthCountry: birthCountryController.text,
|
||||
errorMessage: '',
|
||||
),
|
||||
);
|
||||
birthCountryController.text,
|
||||
current: state.birthCountry,
|
||||
update: () => state.copyWith(
|
||||
birthCountry: birthCountryController.text,
|
||||
errorMessage: '',
|
||||
),
|
||||
);
|
||||
|
||||
void _onPhoneChanged() {
|
||||
final text = phoneController.text;
|
||||
@@ -325,11 +314,11 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
}
|
||||
|
||||
void _onAddressCountryChanged() => _syncAddressField(
|
||||
addressCountryController.text,
|
||||
current: state.address.country,
|
||||
updateAddress: () =>
|
||||
state.address.copyWith(country: addressCountryController.text),
|
||||
);
|
||||
addressCountryController.text,
|
||||
current: state.address.country,
|
||||
updateAddress: () =>
|
||||
state.address.copyWith(country: addressCountryController.text),
|
||||
);
|
||||
|
||||
void _onAddressPostCodeChanged() {
|
||||
final text = addressPostCodeController.text.trim();
|
||||
@@ -353,8 +342,6 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void next() {
|
||||
if (state.isLoading) return;
|
||||
|
||||
@@ -386,8 +373,6 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void updateDialCode(String dialCode) {
|
||||
state = state.copyWith(dialCode: dialCode);
|
||||
}
|
||||
@@ -449,8 +434,6 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
state = state.copyWith(isShowPassword: !state.isShowPassword);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool _validateStep0() {
|
||||
final emailErr = emailErrorFor(state.email);
|
||||
final phoneErr = phoneErrorFor(state.phone);
|
||||
@@ -544,8 +527,6 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
bool _validateForm() =>
|
||||
_validateStep0() && _validateStep1() && _validateStep2();
|
||||
|
||||
|
||||
|
||||
Future<bool> signUp() async {
|
||||
if (state.isLoading) return false;
|
||||
if (!_validateForm()) return false;
|
||||
@@ -573,13 +554,11 @@ class LegacySignUpViewModel extends Notifier<LegacySignUpViewState>
|
||||
if (!ref.mounted) return false;
|
||||
|
||||
final msg = formatErrorMessage(e);
|
||||
final errorMsg =
|
||||
msg == 'BadRequest' ? I18n.errorEmailAlreadyRegistered : msg;
|
||||
final errorMsg = msg == 'BadRequest'
|
||||
? I18n.errorEmailAlreadyRegistered
|
||||
: msg;
|
||||
|
||||
state = state.copyWith(
|
||||
isLoading: false,
|
||||
errorMessage: errorMsg,
|
||||
);
|
||||
state = state.copyWith(isLoading: false, errorMessage: errorMsg);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// ignore_for_file: non_constant_identifier_names
|
||||
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
import 'package:location/src/core/domain/entities/frequent_place_entity.dart';
|
||||
|
||||
|
||||
@@ -4,5 +4,6 @@ import 'package:sf_infrastructure/sf_infrastructure.dart';
|
||||
class SettingsRemoteDatasourceImpl implements SettingsRemoteDatasource {
|
||||
SettingsRemoteDatasourceImpl(this._repository);
|
||||
|
||||
// ignore: unused_field
|
||||
final QuestiaRepository _repository;
|
||||
}
|
||||
|
||||
@@ -4,5 +4,6 @@ import 'package:settings/src/core/domain/repositories/settings_repository.dart';
|
||||
class SettingsRepositoryImpl implements SettingsRepository {
|
||||
const SettingsRepositoryImpl(this._remote);
|
||||
|
||||
// ignore: unused_field
|
||||
final SettingsRemoteDatasource _remote;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ import 'shutdown_use_case.dart';
|
||||
class ShutdownUseCaseImpl implements ShutdownUseCase {
|
||||
ShutdownUseCaseImpl(this._repository);
|
||||
|
||||
// ignore: unused_field
|
||||
final SettingsRepository _repository;
|
||||
|
||||
@override
|
||||
|
||||
@@ -47,7 +47,6 @@ class _OptionsSection extends ConsumerWidget {
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
|
||||
final state = ref.watch(remoteManagementViewModelProvider);
|
||||
final vm = ref.read(remoteManagementViewModelProvider.notifier);
|
||||
|
||||
return SingleChildScrollView(
|
||||
@@ -63,6 +62,7 @@ class _OptionsSection extends ConsumerWidget {
|
||||
message: context.translate(I18n.remoteTurnOffConfirm),
|
||||
onConfirm: () async {
|
||||
await vm.shutdown();
|
||||
if (!context.mounted) return;
|
||||
|
||||
final errorMessage = ref.read(
|
||||
remoteManagementViewModelProvider.select((s)=>s.errorMessage)
|
||||
|
||||
@@ -10,7 +10,8 @@ class ConfirmDialog extends ConsumerWidget {
|
||||
final VoidCallback onConfirm;
|
||||
|
||||
const ConfirmDialog({
|
||||
required this.title,
|
||||
|
||||
super.key, required this.title,
|
||||
required this.message,
|
||||
required this.onConfirm,
|
||||
});
|
||||
|
||||
@@ -6,6 +6,7 @@ class SyncClockUseCaseImpl implements SyncClockUseCase {
|
||||
|
||||
SyncClockUseCaseImpl(this._repository);
|
||||
|
||||
// ignore: unused_field
|
||||
final SettingsRepository _repository;
|
||||
|
||||
@override
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'sync_clock_view_state.freezed.dart';
|
||||
|
||||
@@ -37,6 +37,7 @@ class SyncClockScreen extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
class _OptionsSection extends ConsumerWidget {
|
||||
|
||||
const _OptionsSection();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
name: settings
|
||||
description: "A new Flutter project."
|
||||
publish_to: 'none'
|
||||
|
||||
# The following defines the version and build number for your application.
|
||||
# A version number is three numbers separated by dots, like 1.2.43
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
library legacy_shared;
|
||||
|
||||
export 'src/providers/map_style_provider.dart';
|
||||
export 'src/providers/selected_device_provider.dart';
|
||||
export 'src/widgets/layouts/page_layout.dart';
|
||||
@@ -17,4 +15,4 @@ export 'src/providers/commands_repository_provider.dart';
|
||||
export 'src/domain/repositories/devices_repository.dart';
|
||||
export 'src/providers/devices_repository_provider.dart';
|
||||
export 'src/data/datasources/device_settings_update_datasource.dart';
|
||||
export 'src/providers/device_settings_update_provider.dart';
|
||||
export 'src/providers/device_settings_update_provider.dart';
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:utils/utils.dart';
|
||||
|
||||
class AppMenuButton extends StatelessWidget {
|
||||
|
||||
final GestureTapCallback onPressed;
|
||||
final IconData icon;
|
||||
final bool negativeIcon;
|
||||
@@ -12,6 +10,7 @@ class AppMenuButton extends StatelessWidget {
|
||||
final Color color;
|
||||
|
||||
const AppMenuButton({
|
||||
super.key,
|
||||
required this.onPressed,
|
||||
required this.icon,
|
||||
this.negativeIcon = false,
|
||||
@@ -22,43 +21,40 @@ class AppMenuButton extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return TextButton(
|
||||
onPressed: onPressed,
|
||||
style: ButtonStyle(
|
||||
overlayColor: WidgetStatePropertyAll(Color(0xFFF7F7F7))
|
||||
overlayColor: WidgetStatePropertyAll(Color(0xFFF7F7F7)),
|
||||
),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: negativeIcon
|
||||
? Colors.white
|
||||
: color,
|
||||
color: negativeIcon ? Colors.white : color,
|
||||
),
|
||||
height: SizeUtils.getByScreen(small: 52, big: 48),
|
||||
width: SizeUtils.getByScreen(small: 52, big: 48),
|
||||
child: Icon(icon,
|
||||
child: Icon(
|
||||
icon,
|
||||
size: iconSize ?? SizeUtils.getByScreen(small: 52, big: 48),
|
||||
color: negativeIcon
|
||||
? color
|
||||
: Colors.white,
|
||||
color: negativeIcon ? color : Colors.white,
|
||||
weight: 30,
|
||||
),
|
||||
),
|
||||
SizedBox(width: SizeUtils.getByScreen(small: 16, big: 15)),
|
||||
Expanded(
|
||||
child: Text(text,
|
||||
child: Text(
|
||||
text,
|
||||
style: TextStyle(
|
||||
fontSize: SizeUtils.getByScreen(small: 18, big: 19),
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Color(0xFF4B4B4B)
|
||||
)
|
||||
)
|
||||
)
|
||||
color: Color(0xFF4B4B4B),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ class SectionButton extends StatelessWidget {
|
||||
final Widget body;
|
||||
|
||||
const SectionButton({
|
||||
required this.onPressed,
|
||||
|
||||
super.key, required this.onPressed,
|
||||
required this.icon,
|
||||
this.iconPadding,
|
||||
required this.body,
|
||||
|
||||
@@ -723,7 +723,7 @@ packages:
|
||||
source: path
|
||||
version: "0.0.1"
|
||||
sf_localizations:
|
||||
dependency: "direct overridden"
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "../../../../packages/sf_localizations"
|
||||
relative: true
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
name: legacy_shared
|
||||
description: "A new Flutter project."
|
||||
publish_to: 'none'
|
||||
version: 0.0.1
|
||||
homepage:
|
||||
|
||||
@@ -30,6 +31,7 @@ dependencies:
|
||||
freezed: ^3.2.3
|
||||
json_annotation: ^4.9.0
|
||||
json_serializable: ^6.11.2
|
||||
sf_localizations: ^0.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
||||
@@ -24,7 +24,6 @@ class ScanStrapAndWatchStepScreen extends ConsumerWidget {
|
||||
final textPrimary = theme.getColorFor(ThemeCode.textPrimary);
|
||||
|
||||
final vm = ref.read(deviceSetupViewModelProvider.notifier);
|
||||
final state = ref.watch(deviceSetupViewModelProvider);
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
|
||||
@@ -11,7 +11,6 @@ class SuccessStepScreen extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final state = ref.watch(deviceSetupViewModelProvider);
|
||||
final vm = ref.read(deviceSetupViewModelProvider.notifier);
|
||||
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:auth/src/features/link_phone/domain/use_cases/link_phone_use_cas
|
||||
class LinkPhoneUseCaseImpl implements LinkPhoneUseCase {
|
||||
LinkPhoneUseCaseImpl(this._repository);
|
||||
|
||||
// ignore: unused_field
|
||||
final AuthRepository _repository;
|
||||
|
||||
@override
|
||||
|
||||
@@ -312,6 +312,7 @@ class _SignInSection extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
class _OrContinueWith extends StatelessWidget {
|
||||
const _OrContinueWith({required this.theme});
|
||||
final ThemePort theme;
|
||||
@@ -334,6 +335,7 @@ class _OrContinueWith extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
// ignore: unused_element
|
||||
class _SocialButtons extends ConsumerWidget {
|
||||
const _SocialButtons({required this.theme});
|
||||
final ThemePort theme;
|
||||
|
||||
@@ -117,6 +117,7 @@ class RequestRecoveryScreen extends ConsumerWidget {
|
||||
child: PrimaryButton(
|
||||
onPressed: () async {
|
||||
await viewModel.requestRecovery();
|
||||
if (!context.mounted) return;
|
||||
final updatedState = ref.read(
|
||||
recoverPasswordViewModelProvider,
|
||||
);
|
||||
|
||||
@@ -28,11 +28,20 @@ class ExtractScreen extends ConsumerWidget {
|
||||
|
||||
ref.listen(extractViewModelProvider(childId), (prev, next) {
|
||||
if (next.success && !(prev?.success ?? false)) {
|
||||
showTopSnackbar(context, message: context.translate(I18n.walletMoveSuccess), type: MessageType.success);
|
||||
showTopSnackbar(
|
||||
context,
|
||||
message: context.translate(I18n.walletMoveSuccess),
|
||||
type: MessageType.success,
|
||||
);
|
||||
navigation.goBack();
|
||||
}
|
||||
if (next.errorMessage.isNotEmpty && next.errorMessage != (prev?.errorMessage ?? '')) {
|
||||
showTopSnackbar(context, message: context.translate(I18n.walletMoveError), type: MessageType.error);
|
||||
if (next.errorMessage.isNotEmpty &&
|
||||
next.errorMessage != (prev?.errorMessage ?? '')) {
|
||||
showTopSnackbar(
|
||||
context,
|
||||
message: context.translate(I18n.walletMoveError),
|
||||
type: MessageType.error,
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -53,8 +62,37 @@ class ExtractScreen extends ConsumerWidget {
|
||||
return WalletManagementLayout(
|
||||
childName: childName,
|
||||
balance: availableBalance,
|
||||
cardColors: cardColorsFor(theme: theme, carrierGenre: viewState.device?.carrierGenre, cardStatus: cardStatus),
|
||||
cardColors: cardColorsFor(
|
||||
theme: theme,
|
||||
carrierGenre: viewState.device?.carrierGenre,
|
||||
cardStatus: cardStatus,
|
||||
),
|
||||
navigation: navigation,
|
||||
footer: FooterContainer(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
primaryColor: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
primaryText: viewState.isSubmitting
|
||||
? context.translate(I18n.walletMoveProcessing)
|
||||
: context.translate(I18n.sendMessageAndBlock),
|
||||
onPrimaryPressed: viewState.isSubmitting
|
||||
? null
|
||||
: () {
|
||||
final amount = double.tryParse(
|
||||
viewModel.amountController.text.trim(),
|
||||
);
|
||||
if (amount == null || amount <= 0) {
|
||||
showTopSnackbar(
|
||||
context,
|
||||
message: context.translate(I18n.walletMoveAmountRequired),
|
||||
type: MessageType.warning,
|
||||
);
|
||||
return;
|
||||
}
|
||||
viewModel.submit();
|
||||
},
|
||||
cancelText: context.translate(I18n.cancel),
|
||||
onCancelPressed: () => navigation.goBack(),
|
||||
),
|
||||
children: [
|
||||
SectionContainer(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
@@ -95,9 +133,10 @@ class ExtractScreen extends ConsumerWidget {
|
||||
context.translate(
|
||||
I18n.allowanceBalanceAfter,
|
||||
args: {
|
||||
'amount': (availableBalance -
|
||||
(double.tryParse(viewState.amount) ?? 0))
|
||||
.toStringAsFixed(2),
|
||||
'amount':
|
||||
(availableBalance -
|
||||
(double.tryParse(viewState.amount) ?? 0))
|
||||
.toStringAsFixed(2),
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -131,7 +170,10 @@ class ExtractScreen extends ConsumerWidget {
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(
|
||||
context.translate(I18n.extractMessageLabel, args: {'name': childName}),
|
||||
context.translate(
|
||||
I18n.extractMessageLabel,
|
||||
args: {'name': childName},
|
||||
),
|
||||
style: TextStyle(fontSize: 14, letterSpacing: 0),
|
||||
),
|
||||
),
|
||||
@@ -146,7 +188,10 @@ class ExtractScreen extends ConsumerWidget {
|
||||
children: [
|
||||
Icon(Icons.info_outline, size: 16),
|
||||
Text(
|
||||
context.translate(I18n.allowanceMaxChars, args: {'count': '150'}),
|
||||
context.translate(
|
||||
I18n.allowanceMaxChars,
|
||||
args: {'count': '150'},
|
||||
),
|
||||
style: TextStyle(fontSize: 14, letterSpacing: 0),
|
||||
),
|
||||
],
|
||||
@@ -156,25 +201,6 @@ class ExtractScreen extends ConsumerWidget {
|
||||
],
|
||||
),
|
||||
],
|
||||
footer: FooterContainer(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
primaryColor: theme.getColorFor(ThemeCode.buttonPrimary),
|
||||
primaryText: viewState.isSubmitting
|
||||
? context.translate(I18n.walletMoveProcessing)
|
||||
: context.translate(I18n.sendMessageAndBlock),
|
||||
onPrimaryPressed: viewState.isSubmitting
|
||||
? null
|
||||
: () {
|
||||
final amount = double.tryParse(viewModel.amountController.text.trim());
|
||||
if (amount == null || amount <= 0) {
|
||||
showTopSnackbar(context, message: context.translate(I18n.walletMoveAmountRequired), type: MessageType.warning);
|
||||
return;
|
||||
}
|
||||
viewModel.submit();
|
||||
},
|
||||
cancelText: context.translate(I18n.cancel),
|
||||
onCancelPressed: () => navigation.goBack(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,8 +44,13 @@ class GoalsScreen extends ConsumerWidget {
|
||||
return WalletManagementLayout(
|
||||
childName: childName,
|
||||
balance: availableBalance,
|
||||
cardColors: cardColorsFor(theme: theme, carrierGenre: viewState.device?.carrierGenre, cardStatus: cardStatus),
|
||||
cardColors: cardColorsFor(
|
||||
theme: theme,
|
||||
carrierGenre: viewState.device?.carrierGenre,
|
||||
cardStatus: cardStatus,
|
||||
),
|
||||
navigation: navigation,
|
||||
footer: Container(),
|
||||
children: [
|
||||
SectionContainer(
|
||||
backgroundColor: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
@@ -86,7 +91,6 @@ class GoalsScreen extends ConsumerWidget {
|
||||
childId: childId,
|
||||
),
|
||||
],
|
||||
footer: Container(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -123,7 +127,7 @@ class SavingsBlockState extends ConsumerState<SavingsBlock> {
|
||||
Widget build(BuildContext context) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
var emptyBlock = ({fullPlan}) => Container(
|
||||
Container emptyBlock({fullPlan}) => Container(
|
||||
padding: EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
@@ -213,7 +217,7 @@ class SavingsBlockState extends ConsumerState<SavingsBlock> {
|
||||
),
|
||||
);
|
||||
|
||||
var editBlock = ({create, index}) => Column(
|
||||
Column editBlock({create, index}) => Column(
|
||||
spacing: 24,
|
||||
children: [
|
||||
CustomTextField(
|
||||
@@ -292,7 +296,10 @@ class SavingsBlockState extends ConsumerState<SavingsBlock> {
|
||||
children: [
|
||||
Icon(Icons.info_outline, size: 16),
|
||||
Text(
|
||||
context.translate(I18n.allowanceMaxChars, args: {'count': '150'}),
|
||||
context.translate(
|
||||
I18n.allowanceMaxChars,
|
||||
args: {'count': '150'},
|
||||
),
|
||||
style: TextStyle(fontSize: 14, letterSpacing: 0),
|
||||
),
|
||||
],
|
||||
@@ -492,7 +499,9 @@ class SavingsBlockState extends ConsumerState<SavingsBlock> {
|
||||
ThemeCode.textSecondary,
|
||||
),
|
||||
),
|
||||
Center(child: Text(context.translate(I18n.goalsSaved))),
|
||||
Center(
|
||||
child: Text(context.translate(I18n.goalsSaved)),
|
||||
),
|
||||
if (!showAdd[index])
|
||||
TextButton(
|
||||
style: ButtonStyle(
|
||||
@@ -637,7 +646,7 @@ class TasksBlockState extends ConsumerState<TasksBlock> {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
final viewModel = ref.read(goalsViewModelProvider(widget.childId).notifier);
|
||||
|
||||
final emptyBlock = ({fullPlan}) => Container(
|
||||
Container emptyBlock({fullPlan}) => Container(
|
||||
padding: EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.getColorFor(ThemeCode.backgroundPrimary),
|
||||
@@ -818,7 +827,9 @@ class TasksBlockState extends ConsumerState<TasksBlock> {
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
context.translate(I18n.goalsRewardForCompletion),
|
||||
context.translate(
|
||||
I18n.goalsRewardForCompletion,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 16,
|
||||
letterSpacing: 0,
|
||||
@@ -854,14 +865,18 @@ class TasksBlockState extends ConsumerState<TasksBlock> {
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(
|
||||
context.translate(I18n.goalsTasksCompletedMessagePrefix),
|
||||
context.translate(
|
||||
I18n.goalsTasksCompletedMessagePrefix,
|
||||
),
|
||||
style: TextStyle(fontSize: 14, letterSpacing: 0),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: Alignment.topLeft,
|
||||
child: Text(
|
||||
context.translate(I18n.goalsTasksCompletedMessage),
|
||||
context.translate(
|
||||
I18n.goalsTasksCompletedMessage,
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w500,
|
||||
|
||||
@@ -188,17 +188,13 @@ class WalletItem extends ConsumerWidget {
|
||||
|
||||
Widget _buildGenderAvatar(String? carrierGenre, double size) {
|
||||
final IconData icon;
|
||||
final Color color;
|
||||
switch (carrierGenre) {
|
||||
case 'M':
|
||||
icon = Icons.face;
|
||||
color = const Color(0xFF64B5F6);
|
||||
case 'F':
|
||||
icon = Icons.face_3;
|
||||
color = const Color(0xFFF48FB1);
|
||||
default:
|
||||
icon = Icons.face_2;
|
||||
color = const Color(0xFF90A4AE);
|
||||
}
|
||||
return CircleAvatar(
|
||||
radius: size / 2,
|
||||
@@ -209,6 +205,8 @@ class WalletItem extends ConsumerWidget {
|
||||
}
|
||||
|
||||
class PhotoDialog extends ConsumerWidget {
|
||||
const PhotoDialog({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final theme = ref.watch(themePortProvider);
|
||||
|
||||
@@ -20,6 +20,7 @@ dependencies:
|
||||
path: ../../packages/sf_infrastructure
|
||||
sf_shared:
|
||||
path: ../../packages/sf_shared
|
||||
shared_preferences: ^2.5.5
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
Reference in New Issue
Block a user