mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-09 08:08:14 -06:00
Fixed login and error handling
This commit is contained in:
@@ -1,14 +1,11 @@
|
||||
import 'dart:developer' as dev;
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||
import 'package:paperless_mobile/core/widgets/highlighted_text.dart';
|
||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||
import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart';
|
||||
@@ -25,7 +22,6 @@ import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_widget.d
|
||||
import 'package:paperless_mobile/generated/l10n.dart';
|
||||
import 'package:paperless_mobile/util.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:share_plus/share_plus.dart';
|
||||
|
||||
class DocumentDetailsPage extends StatefulWidget {
|
||||
|
||||
@@ -58,10 +58,6 @@ class DocumentUploadCubit extends Cubit<DocumentUploadState> {
|
||||
Iterable<int> tags = const [],
|
||||
DateTime? createdAt,
|
||||
}) async {
|
||||
final auth = await _localVault.loadAuthenticationInformation();
|
||||
if (auth == null || !auth.isValid) {
|
||||
throw const PaperlessServerException(ErrorCode.notAuthenticated);
|
||||
}
|
||||
await _documentApi.create(
|
||||
bytes,
|
||||
filename: filename,
|
||||
|
||||
@@ -245,8 +245,8 @@ class _DocumentUploadPreparationPageState
|
||||
Navigator.pop(context, true);
|
||||
} on PaperlessServerException catch (error, stackTrace) {
|
||||
showErrorMessage(context, error, stackTrace);
|
||||
} on PaperlessValidationErrors catch (PaperlessServerExceptions) {
|
||||
setState(() => _errors = PaperlessServerExceptions);
|
||||
} on PaperlessValidationErrors catch (errors) {
|
||||
setState(() => _errors = errors);
|
||||
} catch (unknownError, stackTrace) {
|
||||
showErrorMessage(
|
||||
context, const PaperlessServerException.unknown(), stackTrace);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
|
||||
part 'documents_state.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
|
||||
|
||||
class DocumentsCubit extends Cubit<DocumentsState> {
|
||||
final PaperlessDocumentsApi _api;
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
part of 'documents_cubit.dart';
|
||||
import 'package:equatable/equatable.dart';
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
|
||||
@JsonSerializable()
|
||||
class DocumentsState extends Equatable {
|
||||
final bool isLoaded;
|
||||
final DocumentFilter filter;
|
||||
final List<PagedSearchResult> value;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
final List<DocumentModel> selection;
|
||||
|
||||
const DocumentsState({
|
||||
|
||||
@@ -7,6 +7,7 @@ import 'package:paperless_mobile/core/repository/provider/label_repositories_pro
|
||||
import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart';
|
||||
import 'package:paperless_mobile/features/document_details/view/pages/document_details_page.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/documents_empty_state.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/grid/document_grid.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/list/document_list.dart';
|
||||
@@ -82,6 +83,8 @@ class _DocumentsPageState extends State<DocumentsPage> {
|
||||
-4), //TODO: Wait for stable version of m3, then use AlignmentDirectional.topEnd
|
||||
isLabelVisible: appliedFiltersCount > 0,
|
||||
count: state.filter.appliedFiltersCount,
|
||||
backgroundColor: Theme.of(context).colorScheme.errorContainer,
|
||||
textColor: Theme.of(context).colorScheme.onErrorContainer,
|
||||
child: FloatingActionButton(
|
||||
child: const Icon(Icons.filter_alt_outlined),
|
||||
onPressed: _openDocumentFilter,
|
||||
|
||||
@@ -10,21 +10,30 @@ class DocumentPreview extends StatelessWidget {
|
||||
final BoxFit fit;
|
||||
final Alignment alignment;
|
||||
final double borderRadius;
|
||||
final bool enableHero;
|
||||
|
||||
const DocumentPreview({
|
||||
Key? key,
|
||||
super.key,
|
||||
required this.id,
|
||||
this.fit = BoxFit.cover,
|
||||
this.alignment = Alignment.center,
|
||||
this.borderRadius = 8.0,
|
||||
}) : super(key: key);
|
||||
this.enableHero = true,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return
|
||||
// Hero(
|
||||
// tag: "document_$id",child:
|
||||
ClipRRect(
|
||||
if (!enableHero) {
|
||||
return _buildPreview(context);
|
||||
}
|
||||
return Hero(
|
||||
tag: "thumb_$id",
|
||||
child: _buildPreview(context),
|
||||
);
|
||||
}
|
||||
|
||||
ClipRRect _buildPreview(BuildContext context) {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(borderRadius),
|
||||
child: CachedNetworkImage(
|
||||
fit: fit,
|
||||
@@ -39,7 +48,6 @@ class DocumentPreview extends StatelessWidget {
|
||||
),
|
||||
cacheManager: context.watch<CacheManager>(),
|
||||
),
|
||||
// ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/core/widgets/empty_state.dart';
|
||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
|
||||
import 'package:paperless_mobile/generated/l10n.dart';
|
||||
|
||||
class DocumentsEmptyState extends StatelessWidget {
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/grid/document_grid_item.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:paperless_mobile/core/repository/provider/label_repositories_pro
|
||||
import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart';
|
||||
import 'package:paperless_mobile/core/widgets/offline_widget.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/list/document_list_item.dart';
|
||||
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
|
||||
import 'package:paperless_mobile/generated/l10n.dart';
|
||||
|
||||
class BulkDeleteConfirmationDialog extends StatelessWidget {
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/core/widgets/offline_banner.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/selection/bulk_delete_confirmation_dialog.dart';
|
||||
import 'package:paperless_mobile/features/saved_view/view/saved_view_selection_widget.dart';
|
||||
import 'package:paperless_mobile/generated/l10n.dart';
|
||||
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/search/sort_field_selection_bottom_sheet.dart';
|
||||
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||
@@ -120,10 +121,10 @@ class _LabelFormState<T extends Label> extends State<LabelForm<T>> {
|
||||
final createdLabel = await widget.submitButtonConfig
|
||||
.onSubmit(widget.fromJsonT(mergedJson));
|
||||
Navigator.pop(context, createdLabel);
|
||||
} on PaperlessValidationErrors catch (errorMessages) {
|
||||
setState(() => _errors = errorMessages);
|
||||
} on PaperlessServerException catch (error, stackTrace) {
|
||||
showErrorMessage(context, error, stackTrace);
|
||||
} on DioError catch (error) {
|
||||
setState(() => _errors = error.error as PaperlessValidationErrors);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ class InboxItem extends StatelessWidget {
|
||||
id: document.id,
|
||||
fit: BoxFit.cover,
|
||||
alignment: Alignment.topCenter,
|
||||
enableHero: false,
|
||||
),
|
||||
),
|
||||
subtitle: Column(
|
||||
|
||||
@@ -3,22 +3,19 @@ import 'dart:io';
|
||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/core/security/authentication_aware_dio_manager.dart';
|
||||
import 'package:paperless_mobile/core/store/local_vault.dart';
|
||||
import 'package:paperless_mobile/features/login/bloc/authentication_state.dart';
|
||||
import 'package:paperless_mobile/features/login/model/authentication_information.dart';
|
||||
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
||||
import 'package:paperless_mobile/features/login/model/user_credentials.model.dart';
|
||||
import 'package:paperless_mobile/features/login/services/authentication_service.dart';
|
||||
import 'package:paperless_mobile/features/settings/model/application_settings_state.dart';
|
||||
|
||||
class AuthenticationCubit extends HydratedCubit<AuthenticationState> {
|
||||
class AuthenticationCubit extends Cubit<AuthenticationState>
|
||||
with HydratedMixin<AuthenticationState> {
|
||||
final LocalAuthenticationService _localAuthService;
|
||||
final PaperlessAuthenticationApi _authApi;
|
||||
final LocalVault _localVault;
|
||||
final AuthenticationAwareDioManager _dioWrapper;
|
||||
|
||||
AuthenticationCubit(
|
||||
this._localVault,
|
||||
this._localAuthService,
|
||||
this._authApi,
|
||||
this._dioWrapper,
|
||||
@@ -31,6 +28,7 @@ class AuthenticationCubit extends HydratedCubit<AuthenticationState> {
|
||||
}) async {
|
||||
assert(credentials.username != null && credentials.password != null);
|
||||
try {
|
||||
print(_dioWrapper.client.hashCode);
|
||||
_dioWrapper.updateSettings(
|
||||
baseUrl: serverUrl,
|
||||
clientCertificate: clientCertificate,
|
||||
@@ -41,19 +39,22 @@ class AuthenticationCubit extends HydratedCubit<AuthenticationState> {
|
||||
password: credentials.password!,
|
||||
);
|
||||
|
||||
final auth = AuthenticationInformation(
|
||||
serverUrl: serverUrl,
|
||||
_dioWrapper.updateSettings(
|
||||
baseUrl: serverUrl,
|
||||
clientCertificate: clientCertificate,
|
||||
token: token,
|
||||
authToken: token,
|
||||
);
|
||||
|
||||
await _localVault.storeAuthenticationInformation(auth);
|
||||
|
||||
emit(AuthenticationState(
|
||||
isAuthenticated: true,
|
||||
wasLoginStored: false,
|
||||
authentication: auth,
|
||||
));
|
||||
emit(
|
||||
AuthenticationState(
|
||||
wasLoginStored: false,
|
||||
authentication: AuthenticationInformation(
|
||||
serverUrl: serverUrl,
|
||||
clientCertificate: clientCertificate,
|
||||
token: token,
|
||||
),
|
||||
),
|
||||
);
|
||||
} on TlsException catch (_) {
|
||||
const error = PaperlessServerException(
|
||||
ErrorCode.invalidClientCertificateConfiguration);
|
||||
@@ -67,59 +68,68 @@ class AuthenticationCubit extends HydratedCubit<AuthenticationState> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> restoreSessionState() async {
|
||||
final storedAuth = await _localVault.loadAuthenticationInformation();
|
||||
late ApplicationSettingsState? appSettings;
|
||||
try {
|
||||
appSettings = await _localVault.loadApplicationSettings() ??
|
||||
ApplicationSettingsState.defaultSettings;
|
||||
} catch (err) {
|
||||
appSettings = ApplicationSettingsState.defaultSettings;
|
||||
///
|
||||
/// Performs a conditional hydration based on the local authentication success.
|
||||
///
|
||||
Future<void> restoreSessionState(bool promptForLocalAuthentication) async {
|
||||
final json = HydratedBloc.storage.read(storageToken);
|
||||
|
||||
if (json == null) {
|
||||
// If there is nothing to restore, we can quit here.
|
||||
return;
|
||||
}
|
||||
if (storedAuth == null || !storedAuth.isValid) {
|
||||
return emit(
|
||||
AuthenticationState(isAuthenticated: false, wasLoginStored: false),
|
||||
);
|
||||
} else {
|
||||
if (appSettings.isLocalAuthenticationEnabled) {
|
||||
final localAuthSuccess = await _localAuthService
|
||||
.authenticateLocalUser("Authenticate to log back in");
|
||||
if (localAuthSuccess) {
|
||||
|
||||
if (promptForLocalAuthentication) {
|
||||
final localAuthSuccess = await _localAuthService
|
||||
.authenticateLocalUser("Authenticate to log back in");
|
||||
if (localAuthSuccess) {
|
||||
hydrate();
|
||||
if (state.isAuthenticated) {
|
||||
_dioWrapper.updateSettings(
|
||||
clientCertificate: storedAuth.clientCertificate,
|
||||
clientCertificate: state.authentication!.clientCertificate,
|
||||
authToken: state.authentication!.token,
|
||||
baseUrl: state.authentication!.serverUrl,
|
||||
);
|
||||
return emit(
|
||||
AuthenticationState(
|
||||
isAuthenticated: true,
|
||||
wasLoginStored: true,
|
||||
authentication: storedAuth,
|
||||
authentication: state.authentication,
|
||||
wasLocalAuthenticationSuccessful: true,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return emit(AuthenticationState(
|
||||
isAuthenticated: false,
|
||||
wasLoginStored: true,
|
||||
wasLocalAuthenticationSuccessful: false,
|
||||
));
|
||||
}
|
||||
} else {
|
||||
hydrate();
|
||||
return emit(
|
||||
AuthenticationState(
|
||||
wasLoginStored: true,
|
||||
wasLocalAuthenticationSuccessful: false,
|
||||
authentication: state.authentication,
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
hydrate();
|
||||
if (state.isAuthenticated) {
|
||||
_dioWrapper.updateSettings(
|
||||
clientCertificate: storedAuth.clientCertificate,
|
||||
clientCertificate: state.authentication!.clientCertificate,
|
||||
authToken: state.authentication!.token,
|
||||
baseUrl: state.authentication!.serverUrl,
|
||||
);
|
||||
final authState = AuthenticationState(
|
||||
isAuthenticated: true,
|
||||
authentication: storedAuth,
|
||||
authentication: state.authentication!,
|
||||
wasLoginStored: true,
|
||||
);
|
||||
return emit(authState);
|
||||
} else {
|
||||
return emit(AuthenticationState.initial);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> logout() async {
|
||||
await _localVault.clear();
|
||||
await super.clear();
|
||||
await clear();
|
||||
_dioWrapper.resetSettings();
|
||||
emit(AuthenticationState.initial);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,21 +6,20 @@ part 'authentication_state.g.dart';
|
||||
@JsonSerializable()
|
||||
class AuthenticationState {
|
||||
final bool wasLoginStored;
|
||||
@JsonKey(ignore: true)
|
||||
final bool? wasLocalAuthenticationSuccessful;
|
||||
final bool isAuthenticated;
|
||||
final AuthenticationInformation? authentication;
|
||||
|
||||
static final AuthenticationState initial = AuthenticationState(
|
||||
wasLoginStored: false,
|
||||
isAuthenticated: false,
|
||||
);
|
||||
|
||||
bool get isAuthenticated => authentication != null;
|
||||
AuthenticationState({
|
||||
required this.isAuthenticated,
|
||||
required this.wasLoginStored,
|
||||
this.wasLocalAuthenticationSuccessful,
|
||||
this.authentication,
|
||||
}) : assert(!isAuthenticated || authentication != null);
|
||||
});
|
||||
|
||||
AuthenticationState copyWith({
|
||||
bool? wasLoginStored,
|
||||
@@ -29,7 +28,6 @@ class AuthenticationState {
|
||||
bool? wasLocalAuthenticationSuccessful,
|
||||
}) {
|
||||
return AuthenticationState(
|
||||
isAuthenticated: isAuthenticated ?? this.isAuthenticated,
|
||||
wasLoginStored: wasLoginStored ?? this.wasLoginStored,
|
||||
authentication: authentication ?? this.authentication,
|
||||
wasLocalAuthenticationSuccessful: wasLocalAuthenticationSuccessful ??
|
||||
|
||||
@@ -8,10 +8,7 @@ part of 'authentication_state.dart';
|
||||
|
||||
AuthenticationState _$AuthenticationStateFromJson(Map<String, dynamic> json) =>
|
||||
AuthenticationState(
|
||||
isAuthenticated: json['isAuthenticated'] as bool,
|
||||
wasLoginStored: json['wasLoginStored'] as bool,
|
||||
wasLocalAuthenticationSuccessful:
|
||||
json['wasLocalAuthenticationSuccessful'] as bool?,
|
||||
authentication: json['authentication'] == null
|
||||
? null
|
||||
: AuthenticationInformation.fromJson(
|
||||
@@ -22,8 +19,5 @@ Map<String, dynamic> _$AuthenticationStateToJson(
|
||||
AuthenticationState instance) =>
|
||||
<String, dynamic>{
|
||||
'wasLoginStored': instance.wasLoginStored,
|
||||
'wasLocalAuthenticationSuccessful':
|
||||
instance.wasLocalAuthenticationSuccessful,
|
||||
'isAuthenticated': instance.isAuthenticated,
|
||||
'authentication': instance.authentication,
|
||||
};
|
||||
|
||||
@@ -49,7 +49,7 @@ class _LoginPageState extends State<LoginPage> {
|
||||
padding: const EdgeInsets.only(top: 16.0),
|
||||
child: Text(
|
||||
S.of(context).loginPageAdvancedLabel,
|
||||
style: Theme.of(context).textTheme.bodyText1,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
).padded(),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||
import 'package:paperless_mobile/core/service/connectivity_status.service.dart';
|
||||
import 'package:paperless_mobile/generated/l10n.dart';
|
||||
@@ -26,6 +27,10 @@ class _ServerAddressFormFieldState extends State<ServerAddressFormField> {
|
||||
validator: FormBuilderValidators.required(
|
||||
errorText: S.of(context).loginPageServerUrlValidatorMessageText,
|
||||
),
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.deny(r".*/$"),
|
||||
FilteringTextInputFormatter.deny(r"\s"),
|
||||
],
|
||||
decoration: InputDecoration(
|
||||
suffixIcon: _buildIsReachableIcon(),
|
||||
hintText: "http://192.168.1.50:8000",
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:paperless_api/paperless_api.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
|
||||
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
|
||||
import 'package:paperless_mobile/features/documents/view/widgets/selection/confirm_delete_saved_view_dialog.dart';
|
||||
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart';
|
||||
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_state.dart';
|
||||
|
||||
@@ -1,20 +1,30 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||
import 'package:paperless_mobile/features/login/services/authentication_service.dart';
|
||||
import 'package:paperless_mobile/features/settings/model/application_settings_state.dart';
|
||||
import 'package:paperless_mobile/features/settings/model/view_type.dart';
|
||||
|
||||
class ApplicationSettingsCubit extends HydratedCubit<ApplicationSettingsState> {
|
||||
ApplicationSettingsCubit() : super(ApplicationSettingsState.defaultSettings);
|
||||
final LocalAuthenticationService _localAuthenticationService;
|
||||
ApplicationSettingsCubit(this._localAuthenticationService)
|
||||
: super(ApplicationSettingsState.defaultSettings);
|
||||
|
||||
Future<void> setLocale(String? localeSubtag) async {
|
||||
final updatedSettings = state.copyWith(preferredLocaleSubtag: localeSubtag);
|
||||
_updateSettings(updatedSettings);
|
||||
}
|
||||
|
||||
Future<void> setIsBiometricAuthenticationEnabled(bool isEnabled) async {
|
||||
final updatedSettings =
|
||||
state.copyWith(isLocalAuthenticationEnabled: isEnabled);
|
||||
_updateSettings(updatedSettings);
|
||||
Future<void> setIsBiometricAuthenticationEnabled(
|
||||
bool isEnabled, {
|
||||
required String localizedReason,
|
||||
}) async {
|
||||
final isActionAuthorized = await _localAuthenticationService
|
||||
.authenticateLocalUser(localizedReason);
|
||||
if (isActionAuthorized) {
|
||||
final updatedSettings =
|
||||
state.copyWith(isLocalAuthenticationEnabled: isEnabled);
|
||||
_updateSettings(updatedSettings);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> setThemeMode(ThemeMode? selectedMode) async {
|
||||
|
||||
@@ -19,7 +19,6 @@ class BiometricAuthenticationSetting extends StatelessWidget {
|
||||
subtitle: Text(
|
||||
S.of(context).appSettingsBiometricAuthenticationDescriptionText),
|
||||
onChanged: (val) async {
|
||||
final settingsBloc = context.read<ApplicationSettingsCubit>();
|
||||
final String localizedReason = val
|
||||
? S
|
||||
.of(context)
|
||||
@@ -27,12 +26,10 @@ class BiometricAuthenticationSetting extends StatelessWidget {
|
||||
: S
|
||||
.of(context)
|
||||
.appSettingsDisableBiometricAuthenticationReasonText;
|
||||
final changeValue = await context
|
||||
.read<LocalAuthenticationService>()
|
||||
.authenticateLocalUser(localizedReason);
|
||||
if (changeValue) {
|
||||
settingsBloc.setIsBiometricAuthenticationEnabled(val);
|
||||
}
|
||||
await context
|
||||
.read<ApplicationSettingsCubit>()
|
||||
.setIsBiometricAuthenticationEnabled(val,
|
||||
localizedReason: localizedReason);
|
||||
},
|
||||
);
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user