Improved error handling, added multithreading for fromJson calls, made receive sharing intent more robust

This commit is contained in:
Anton Stubenbord
2022-11-13 14:41:42 +01:00
parent afbd4bddb4
commit 1cafd5d246
43 changed files with 644 additions and 746 deletions

View File

@@ -198,10 +198,8 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
child: Text(S
.of(context)
.documentDetailsPageAssignAsnButtonLabel),
onPressed: widget.allowEdit
? () => BlocProvider.of<DocumentsCubit>(context)
.assignAsn(document)
: null,
onPressed:
widget.allowEdit ? () => _assignAsn(document) : null,
),
),
_separator(),
@@ -233,6 +231,14 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
);
}
Future<void> _assignAsn(DocumentModel document) async {
try {
await BlocProvider.of<DocumentsCubit>(context).assignAsn(document);
} on ErrorMessage catch (error) {
showError(context, error);
}
}
Widget _buildDocumentContentView(DocumentModel document, String? match) {
return SingleChildScrollView(
child: _DetailsItem(
@@ -392,21 +398,23 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
);
}
Future<void> _onDelete(DocumentModel document) async {
showDialog(
context: context,
builder: (context) =>
DeleteDocumentConfirmationDialog(document: document))
.then((delete) {
if (delete ?? false) {
BlocProvider.of<DocumentsCubit>(context)
.removeDocument(document)
.then((value) {
Navigator.pop(context);
showSnackBar(context, S.of(context).documentDeleteSuccessMessage);
});
void _onDelete(DocumentModel document) async {
final delete = await showDialog(
context: context,
builder: (context) =>
DeleteDocumentConfirmationDialog(document: document),
) ??
false;
if (delete) {
try {
await BlocProvider.of<DocumentsCubit>(context).removeDocument(document);
showSnackBar(context, S.of(context).documentDeleteSuccessMessage);
} on ErrorMessage catch (error) {
showError(context, error);
} finally {
Navigator.pop(context);
}
});
}
}
Future<void> _onOpen(DocumentModel document) async {

View File

@@ -3,6 +3,7 @@ import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
@@ -76,10 +77,14 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
setState(() {
_isSubmitLoading = true;
});
await getIt<DocumentsCubit>().updateDocument(updatedDocument);
Navigator.pop(context);
showSnackBar(
context, "Document successfully updated."); //TODO: INTL
try {
await getIt<DocumentsCubit>().updateDocument(updatedDocument);
showSnackBar(context, S.of(context).documentUpdateErrorMessage);
} on ErrorMessage catch (error) {
showError(context, error);
} finally {
Navigator.pop(context);
}
}
},
icon: const Icon(Icons.save),

View File

@@ -44,13 +44,20 @@ class _DocumentsPageState extends State<DocumentsPage> {
@override
void initState() {
super.initState();
final documentsCubit = BlocProvider.of<DocumentsCubit>(context);
if (!documentsCubit.state.isLoaded) {
documentsCubit.loadDocuments();
if (!BlocProvider.of<DocumentsCubit>(context).state.isLoaded) {
_initDocuments();
}
_pagingController.addPageRequestListener(_loadNewPage);
}
Future<void> _initDocuments() async {
try {
BlocProvider.of<DocumentsCubit>(context).loadDocuments();
} on ErrorMessage catch (error) {
showError(context, error);
}
}
@override
void dispose() {
_pagingController.dispose();
@@ -64,17 +71,25 @@ class _DocumentsPageState extends State<DocumentsPage> {
if (pageCount <= pageKey + 1) {
_pagingController.nextPageKey = null;
}
documentsCubit.loadMore();
try {
await documentsCubit.loadMore();
} on ErrorMessage catch (error) {
showError(context, error);
}
}
void _onSelected(DocumentModel model) {
BlocProvider.of<DocumentsCubit>(context).toggleDocumentSelection(model);
}
Future<void> _onRefresh() {
final documentsCubit = BlocProvider.of<DocumentsCubit>(context);
return documentsCubit.updateFilter(
filter: documentsCubit.state.filter.copyWith(page: 1));
Future<void> _onRefresh() async {
try {
await BlocProvider.of<DocumentsCubit>(context).updateCurrentFilter(
(filter) => filter.copyWith(page: 1),
);
} on ErrorMessage catch (error) {
showError(context, error);
}
}
@override
@@ -86,9 +101,9 @@ class _DocumentsPageState extends State<DocumentsPage> {
_panelController.close();
return false;
}
final docBloc = BlocProvider.of<DocumentsCubit>(context);
if (docBloc.state.selection.isNotEmpty) {
docBloc.resetSelection();
final documentsCubit = BlocProvider.of<DocumentsCubit>(context);
if (documentsCubit.state.selection.isNotEmpty) {
documentsCubit.resetSelection();
return false;
}
return true;

View File

@@ -513,7 +513,7 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
);
}
void _onApplyFilter() {
void _onApplyFilter() async {
if (_formKey.currentState?.saveAndValidate() ?? false) {
final v = _formKey.currentState!.value;
final docCubit = BlocProvider.of<DocumentsCubit>(context);
@@ -530,13 +530,15 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
addedDateAfter: (v[fkAddedAt] as DateTimeRange?)?.start,
queryType: v[QueryTypeFormField.fkQueryType] as QueryType,
);
BlocProvider.of<DocumentsCubit>(context)
.updateFilter(filter: newFilter)
.then((value) {
try {
await BlocProvider.of<DocumentsCubit>(context)
.updateFilter(filter: newFilter);
BlocProvider.of<SavedViewCubit>(context).resetSelection();
FocusScope.of(context).unfocus();
widget.panelController.close();
});
} on ErrorMessage catch (error) {
showError(context, error);
}
}
}

View File

@@ -74,14 +74,22 @@ class _DocumentsPageAppBarState extends State<DocumentsPageAppBar> {
void _onDelete(BuildContext context, DocumentsState documentsState) async {
final shouldDelete = await showDialog<bool>(
context: context,
builder: (context) => BulkDeleteConfirmationDialog(state: documentsState),
);
if (shouldDelete ?? false) {
BlocProvider.of<DocumentsCubit>(context)
.bulkRemoveDocuments(documentsState.selection)
.then((_) => showSnackBar(
context, S.of(context).documentsPageBulkDeleteSuccessfulText));
context: context,
builder: (context) =>
BulkDeleteConfirmationDialog(state: documentsState),
) ??
false;
if (shouldDelete) {
try {
await BlocProvider.of<DocumentsCubit>(context)
.bulkRemoveDocuments(documentsState.selection);
showSnackBar(
context,
S.of(context).documentsPageBulkDeleteSuccessfulText,
);
} on ErrorMessage catch (error) {
showError(context, error);
}
}
}

View File

@@ -78,22 +78,32 @@ class SavedViewSelectionWidget extends StatelessWidget {
final newView = await Navigator.of(context).push<SavedView?>(
MaterialPageRoute(
builder: (context) => AddSavedViewPage(
currentFilter: getIt<DocumentsCubit>().state.filter),
currentFilter: getIt<DocumentsCubit>().state.filter,
),
),
);
if (newView != null) {
BlocProvider.of<SavedViewCubit>(context).add(newView);
try {
await BlocProvider.of<SavedViewCubit>(context).add(newView);
} on ErrorMessage catch (error) {
showError(context, error);
}
}
}
void _onSelected(bool isSelected, BuildContext context, SavedView view) {
if (isSelected) {
BlocProvider.of<DocumentsCubit>(context)
.updateFilter(filter: view.toDocumentFilter());
BlocProvider.of<SavedViewCubit>(context).selectView(view);
} else {
BlocProvider.of<DocumentsCubit>(context).updateFilter();
BlocProvider.of<SavedViewCubit>(context).selectView(null);
void _onSelected(
bool isSelected, BuildContext context, SavedView view) async {
try {
if (isSelected) {
BlocProvider.of<DocumentsCubit>(context)
.updateFilter(filter: view.toDocumentFilter());
BlocProvider.of<SavedViewCubit>(context).selectView(view);
} else {
BlocProvider.of<DocumentsCubit>(context).updateFilter();
BlocProvider.of<SavedViewCubit>(context).selectView(null);
}
} on ErrorMessage catch (error) {
showError(context, error);
}
}
@@ -105,7 +115,11 @@ class SavedViewSelectionWidget extends StatelessWidget {
) ??
false;
if (delete) {
BlocProvider.of<SavedViewCubit>(context).remove(view);
try {
BlocProvider.of<SavedViewCubit>(context).remove(view);
} on ErrorMessage catch (error) {
showError(context, error);
}
}
}
}

View File

@@ -43,11 +43,18 @@ class _SortDocumentsButtonState extends State<SortDocumentsButton> {
),
onPressed: () async {
setState(() => _isLoading = true);
BlocProvider.of<DocumentsCubit>(context)
.updateFilter(
filter: state.filter
.copyWith(sortOrder: state.filter.sortOrder.toggle()))
.whenComplete(() => setState(() => _isLoading = false));
try {
await BlocProvider.of<DocumentsCubit>(context)
.updateCurrentFilter(
(filter) => filter.copyWith(
sortOrder: state.filter.sortOrder.toggle(),
),
);
} on ErrorMessage catch (error) {
showError(context, error);
} finally {
setState(() => _isLoading = false);
}
},
);
}