feat: view type stored in view/cubit, itself, cleanup coe

This commit is contained in:
Anton Stubenbord
2023-02-10 12:41:30 +01:00
parent e65e152d44
commit f04edece16
72 changed files with 307 additions and 568 deletions

View File

@@ -1,6 +1,6 @@
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:paperless_mobile/features/login/bloc/authentication_state.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_state.dart';
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
extension AddressableHydratedStorage on Storage {
ApplicationSettingsState get settings {

View File

@@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/constants.dart';
import 'package:paperless_mobile/core/widgets/paperless_logo.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/view/settings_page.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:url_launcher/link.dart';

View File

@@ -12,13 +12,13 @@ import 'package:paperless_mobile/core/translation/error_code_localization_mapper
import 'package:paperless_mobile/core/widgets/highlighted_text.dart';
import 'package:paperless_mobile/core/widgets/offline_widget.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart';
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
import 'package:paperless_mobile/features/document_details/view/widgets/document_download_button.dart';
import 'package:paperless_mobile/features/documents/view/pages/document_edit_page.dart';
import 'package:paperless_mobile/features/document_edit/cubit/document_edit_cubit.dart';
import 'package:paperless_mobile/features/document_edit/view/document_edit_page.dart';
import 'package:paperless_mobile/features/documents/view/pages/document_view.dart';
import 'package:paperless_mobile/features/documents/view/widgets/delete_document_confirmation_dialog.dart';
import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart';
import 'package:paperless_mobile/features/edit_document/cubit/edit_document_cubit.dart';
import 'package:paperless_mobile/features/labels/storage_path/view/widgets/storage_path_widget.dart';
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_widget.dart';
import 'package:paperless_mobile/features/labels/view/widgets/label_text.dart';
@@ -265,7 +265,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
builder: (_) => MultiBlocProvider(
providers: [
BlocProvider.value(
value: EditDocumentCubit(
value: DocumentEditCubit(
document,
documentsApi: context.read(),
correspondentRepository: context.read(),
@@ -279,7 +279,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
value: cubit,
),
],
child: BlocListener<EditDocumentCubit, EditDocumentState>(
child: BlocListener<DocumentEditCubit, DocumentEditState>(
listenWhen: (previous, current) =>
previous.document != current.document,
listener: (context, state) {

View File

@@ -11,9 +11,9 @@ import 'package:paperless_mobile/core/repository/state/impl/document_type_reposi
import 'package:paperless_mobile/core/repository/state/impl/storage_path_repository_state.dart';
import 'package:paperless_mobile/core/repository/state/impl/tag_repository_state.dart';
part 'edit_document_state.dart';
part 'document_edit_state.dart';
class EditDocumentCubit extends Cubit<EditDocumentState> {
class DocumentEditCubit extends Cubit<DocumentEditState> {
final DocumentModel _initialDocument;
final PaperlessDocumentsApi _docsApi;
@@ -24,7 +24,7 @@ class EditDocumentCubit extends Cubit<EditDocumentState> {
final LabelRepository<Tag> _tagRepository;
final List<StreamSubscription> _subscriptions = [];
EditDocumentCubit(
DocumentEditCubit(
DocumentModel document, {
required PaperlessDocumentsApi documentsApi,
required LabelRepository<Correspondent> correspondentRepository,
@@ -40,7 +40,7 @@ class EditDocumentCubit extends Cubit<EditDocumentState> {
_tagRepository = tagRepository,
_notifier = notifier,
super(
EditDocumentState(
DocumentEditState(
document: document,
correspondents: correspondentRepository.current?.values ?? {},
documentTypes: documentTypeRepository.current?.values ?? {},

View File

@@ -1,6 +1,6 @@
part of 'edit_document_cubit.dart';
part of 'document_edit_cubit.dart';
class EditDocumentState extends Equatable {
class DocumentEditState extends Equatable {
final DocumentModel document;
final Map<int, Correspondent> correspondents;
@@ -8,7 +8,7 @@ class EditDocumentState extends Equatable {
final Map<int, StoragePath> storagePaths;
final Map<int, Tag> tags;
const EditDocumentState({
const DocumentEditState({
required this.correspondents,
required this.documentTypes,
required this.storagePaths,
@@ -25,14 +25,14 @@ class EditDocumentState extends Equatable {
document,
];
EditDocumentState copyWith({
DocumentEditState copyWith({
Map<int, Correspondent>? correspondents,
Map<int, DocumentType>? documentTypes,
Map<int, StoragePath>? storagePaths,
Map<int, Tag>? tags,
DocumentModel? document,
}) {
return EditDocumentState(
return DocumentEditState(
document: document ?? this.document,
correspondents: correspondents ?? this.correspondents,
documentTypes: documentTypes ?? this.documentTypes,

View File

@@ -13,7 +13,7 @@ import 'package:paperless_mobile/core/repository/state/impl/document_type_reposi
import 'package:paperless_mobile/core/repository/state/impl/storage_path_repository_state.dart';
import 'package:paperless_mobile/core/workarounds/colored_chip.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/edit_document/cubit/edit_document_cubit.dart';
import 'package:paperless_mobile/features/document_edit/cubit/document_edit_cubit.dart';
import 'package:paperless_mobile/features/edit_label/view/impl/add_correspondent_page.dart';
import 'package:paperless_mobile/features/edit_label/view/impl/add_document_type_page.dart';
import 'package:paperless_mobile/features/edit_label/view/impl/add_storage_path_page.dart';
@@ -51,12 +51,12 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
void initState() {
super.initState();
_filteredSuggestions = widget.suggestions
.documentDifference(context.read<EditDocumentCubit>().state.document);
.documentDifference(context.read<DocumentEditCubit>().state.document);
}
@override
Widget build(BuildContext context) {
return BlocBuilder<EditDocumentCubit, EditDocumentState>(
return BlocBuilder<DocumentEditCubit, DocumentEditState>(
builder: (context, state) {
return Scaffold(
resizeToAvoidBottomInset: false,
@@ -252,7 +252,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
_isSubmitLoading = true;
});
try {
await context.read<EditDocumentCubit>().updateDocument(mergedDocument);
await context.read<DocumentEditCubit>().updateDocument(mergedDocument);
showSnackBar(context, S.of(context).documentUpdateSuccessMessage);
} on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace);

View File

@@ -19,8 +19,8 @@ import 'package:paperless_mobile/features/document_search/view/document_search_p
import 'package:paperless_mobile/features/document_upload/cubit/document_upload_cubit.dart';
import 'package:paperless_mobile/features/document_upload/view/document_upload_preparation_page.dart';
import 'package:paperless_mobile/features/documents/view/pages/document_view.dart';
import 'package:paperless_mobile/features/scan/bloc/document_scanner_cubit.dart';
import 'package:paperless_mobile/features/scan/view/widgets/scanned_image_item.dart';
import 'package:paperless_mobile/features/document_scan/cubit/document_scanner_cubit.dart';
import 'package:paperless_mobile/features/document_scan/view/widgets/scanned_image_item.dart';
import 'package:paperless_mobile/features/search_app_bar/view/search_app_bar.dart';
import 'package:paperless_mobile/features/tasks/cubit/task_status_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -5,8 +5,9 @@ import 'package:flutter/foundation.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/cubit/documents_state.dart';
import 'package:paperless_mobile/features/paged_document_view/paged_documents_mixin.dart';
import 'package:paperless_mobile/features/settings/model/view_type.dart';
class DocumentsCubit extends HydratedCubit<DocumentsState>
with PagedDocumentsMixin {
@@ -94,4 +95,8 @@ class DocumentsCubit extends HydratedCubit<DocumentsState>
notifier.unsubscribe(this);
return super.close();
}
void setViewType(ViewType viewType) {
emit(state.copyWith(viewType: viewType));
}
}

View File

@@ -1,13 +1,20 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/paged_document_view/model/paged_documents_state.dart';
import 'package:paperless_mobile/features/settings/model/view_type.dart';
part 'documents_state.g.dart';
@JsonSerializable()
class DocumentsState extends PagedDocumentsState {
@JsonKey(includeFromJson: true, includeToJson: false)
@JsonKey(includeFromJson: false, includeToJson: false)
final List<DocumentModel> selection;
final ViewType viewType;
const DocumentsState({
this.selection = const [],
this.viewType = ViewType.list,
super.value = const [],
super.filter = const DocumentFilter(),
super.hasLoaded = false,
@@ -22,6 +29,7 @@ class DocumentsState extends PagedDocumentsState {
List<PagedSearchResult<DocumentModel>>? value,
DocumentFilter? filter,
List<DocumentModel>? selection,
ViewType? viewType,
}) {
return DocumentsState(
hasLoaded: hasLoaded ?? this.hasLoaded,
@@ -29,38 +37,22 @@ class DocumentsState extends PagedDocumentsState {
value: value ?? this.value,
filter: filter ?? this.filter,
selection: selection ?? this.selection,
viewType: viewType ?? this.viewType,
);
}
factory DocumentsState.fromJson(Map<String, dynamic> json) =>
_$DocumentsStateFromJson(json);
Map<String, dynamic> toJson() => _$DocumentsStateToJson(this);
@override
List<Object?> get props => [
selection,
viewType,
...super.props,
];
Map<String, dynamic> toJson() {
final json = {
'hasLoaded': hasLoaded,
'isLoading': isLoading,
'filter': filter.toJson(),
'value':
value.map((e) => e.toJson(DocumentModelJsonConverter())).toList(),
};
return json;
}
factory DocumentsState.fromJson(Map<String, dynamic> json) {
return DocumentsState(
hasLoaded: json['hasLoaded'],
isLoading: json['isLoading'],
value: (json['value'] as List<dynamic>)
.map((e) =>
PagedSearchResult.fromJsonT(e, DocumentModelJsonConverter()))
.toList(),
filter: DocumentFilter.fromJson(json['filter']),
);
}
@override
DocumentsState copyWithPaged({
bool? hasLoaded,

View File

@@ -1,7 +1,4 @@
import 'dart:developer';
import 'package:badges/badges.dart' as b;
import 'package:collection/collection.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
@@ -9,20 +6,19 @@ import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart';
import 'package:paperless_mobile/features/document_search/view/document_search_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/cubit/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/cubit/documents_state.dart';
import 'package:paperless_mobile/features/documents/view/widgets/adaptive_documents_view.dart';
import 'package:paperless_mobile/features/documents/view/widgets/documents_empty_state.dart';
import 'package:paperless_mobile/features/documents/view/widgets/search/document_filter_panel.dart';
import 'package:paperless_mobile/features/documents/view/widgets/selection/bulk_delete_confirmation_dialog.dart';
import 'package:paperless_mobile/features/documents/view/widgets/selection/view_type_selection_widget.dart';
import 'package:paperless_mobile/features/documents/view/widgets/sort_documents_button.dart';
import 'package:paperless_mobile/features/labels/bloc/providers/labels_bloc_provider.dart';
import 'package:paperless_mobile/features/labels/cubit/providers/labels_bloc_provider.dart';
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart';
import 'package:paperless_mobile/features/saved_view/view/add_saved_view_page.dart';
import 'package:paperless_mobile/features/saved_view/view/saved_view_list.dart';
import 'package:paperless_mobile/features/search_app_bar/view/search_app_bar.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_state.dart';
import 'package:paperless_mobile/features/settings/model/view_type.dart';
import 'package:paperless_mobile/features/tasks/cubit/task_status_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';
@@ -263,14 +259,6 @@ class _DocumentsPageState extends State<DocumentsPage>
),
_buildViewActions(),
BlocBuilder<DocumentsCubit, DocumentsState>(
// Not required anymore since saved views are now handled separately
// buildWhen: (previous, current) =>
// !const ListEquality().equals(
// previous.documents,
// current.documents,
// ) ||
// previous.selectedIds !=
// current.selectedIds,
builder: (context, state) {
if (state.hasLoaded &&
state.documents.isEmpty) {
@@ -285,13 +273,9 @@ class _DocumentsPageState extends State<DocumentsPage>
),
);
}
return BlocBuilder<
ApplicationSettingsCubit,
ApplicationSettingsState>(
builder: (context, settings) {
return SliverAdaptiveDocumentsView(
viewType:
settings.preferredViewType,
viewType: state.viewType,
onTap: _openDetails,
onSelected: context
.read<DocumentsCubit>()
@@ -309,10 +293,7 @@ class _DocumentsPageState extends State<DocumentsPage>
hasLoaded: state.hasLoaded,
isLabelClickable: true,
isLoading: state.isLoading,
selectedDocumentIds:
state.selectedIds,
);
},
selectedDocumentIds: state.selectedIds,
);
},
),
@@ -360,18 +341,11 @@ class _DocumentsPageState extends State<DocumentsPage>
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SortDocumentsButton(),
BlocBuilder<ApplicationSettingsCubit, ApplicationSettingsState>(
BlocBuilder<DocumentsCubit, DocumentsState>(
builder: (context, state) {
return IconButton(
icon: Icon(
state.preferredViewType == ViewType.list
? Icons.grid_view_rounded
: Icons.list,
),
onPressed: () =>
context.read<ApplicationSettingsCubit>().setViewType(
state.preferredViewType.toggle(),
),
return ViewTypeSelectionWidget(
viewType: state.viewType,
onChanged: context.read<DocumentsCubit>().setViewType,
);
},
)

View File

@@ -4,9 +4,9 @@ import 'package:intl/intl.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart';
import 'package:paperless_mobile/features/documents/view/widgets/items/document_item.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/bloc/providers/document_type_bloc_provider.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/providers/document_type_bloc_provider.dart';
import 'package:paperless_mobile/features/labels/correspondent/view/widgets/correspondent_widget.dart';
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_widget.dart';

View File

@@ -4,8 +4,8 @@ import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_extended_date_range_picker.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_form_field.dart';
import 'package:paperless_mobile/features/labels/view/widgets/label_form_field.dart';
import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -9,8 +9,8 @@ import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/documents/view/pages/documents_page.dart';
import 'package:paperless_mobile/features/documents/view/widgets/search/document_filter_form.dart';
import 'package:paperless_mobile/features/documents/view/widgets/search/text_query_form_field.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_form_field.dart';
import 'package:paperless_mobile/features/labels/view/widgets/label_form_field.dart';
import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -4,8 +4,8 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/translation/sort_field_localization_mapper.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
import 'package:paperless_mobile/generated/l10n.dart';
class SortFieldSelectionBottomSheet extends StatefulWidget {

View File

@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/widgets/form_builder_fields/form_builder_type_ahead.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:provider/provider.dart';

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/cubit/documents_state.dart';
import 'package:paperless_mobile/generated/l10n.dart';
class BulkDeleteConfirmationDialog extends StatelessWidget {

View File

@@ -0,0 +1,26 @@
import 'package:flutter/material.dart';
import 'package:paperless_mobile/features/settings/model/view_type.dart';
/// Meant to be used with blocbuilder.
class ViewTypeSelectionWidget extends StatelessWidget {
final ViewType viewType;
final void Function(ViewType type) onChanged;
const ViewTypeSelectionWidget({
super.key,
required this.viewType,
required this.onChanged,
});
@override
Widget build(BuildContext context) {
final next = viewType.toggle();
final icon = next == ViewType.grid ? Icons.grid_view_rounded : Icons.list;
return IconButton(
icon: Icon(icon),
onPressed: () {
onChanged(next);
},
);
}
}

View File

@@ -5,10 +5,10 @@ import 'package:paperless_mobile/core/repository/label_repository.dart';
import 'package:paperless_mobile/core/repository/state/impl/correspondent_repository_state.dart';
import 'package:paperless_mobile/core/repository/state/impl/document_type_repository_state.dart';
import 'package:paperless_mobile/core/translation/sort_field_localization_mapper.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/cubit/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/cubit/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';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
class SortDocumentsButton extends StatelessWidget {
const SortDocumentsButton({

View File

@@ -1,39 +0,0 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/features/documents/view/widgets/sort_documents_button.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_state.dart';
import 'package:paperless_mobile/features/settings/model/view_type.dart';
class ViewActions extends StatelessWidget {
const ViewActions({super.key});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const SortDocumentsButton(),
BlocBuilder<ApplicationSettingsCubit, ApplicationSettingsState>(
builder: (context, settings) {
final cubit = context.read<ApplicationSettingsCubit>();
switch (settings.preferredViewType) {
case ViewType.grid:
return IconButton(
icon: const Icon(Icons.list),
onPressed: () =>
cubit.setViewType(settings.preferredViewType.toggle()),
);
case ViewType.list:
return IconButton(
icon: const Icon(Icons.grid_view_rounded),
onPressed: () =>
cubit.setViewType(settings.preferredViewType.toggle()),
);
}
},
)
],
);
}
}

View File

@@ -17,18 +17,18 @@ import 'package:paperless_mobile/core/repository/state/impl/tag_repository_state
import 'package:paperless_mobile/core/translation/error_code_localization_mapper.dart';
import 'package:paperless_mobile/features/document_upload/cubit/document_upload_cubit.dart';
import 'package:paperless_mobile/features/document_upload/view/document_upload_preparation_page.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/view/pages/documents_page.dart';
import 'package:paperless_mobile/features/home/view/route_description.dart';
import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart';
import 'package:paperless_mobile/features/inbox/bloc/state/inbox_state.dart';
import 'package:paperless_mobile/features/inbox/cubit/inbox_cubit.dart';
import 'package:paperless_mobile/features/inbox/cubit/state/inbox_state.dart';
import 'package:paperless_mobile/features/inbox/view/pages/inbox_page.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/view/pages/labels_page.dart';
import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart';
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart';
import 'package:paperless_mobile/features/scan/bloc/document_scanner_cubit.dart';
import 'package:paperless_mobile/features/scan/view/scanner_page.dart';
import 'package:paperless_mobile/features/document_scan/cubit/document_scanner_cubit.dart';
import 'package:paperless_mobile/features/document_scan/view/scanner_page.dart';
import 'package:paperless_mobile/features/sharing/share_intent_queue.dart';
import 'package:paperless_mobile/features/tasks/cubit/task_status_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -13,7 +13,7 @@
// import 'package:paperless_mobile/core/repository/state/impl/storage_path_repository_state.dart';
// import 'package:paperless_mobile/core/repository/state/impl/tag_repository_state.dart';
// import 'package:paperless_mobile/extensions/flutter_extensions.dart';
// import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart';
// import 'package:paperless_mobile/features/inbox/cubit/inbox_cubit.dart';
// import 'package:paperless_mobile/features/inbox/view/pages/inbox_page.dart';
// import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart';
// import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';

View File

@@ -3,13 +3,9 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/repository/label_repository.dart';
import 'package:paperless_mobile/core/repository/saved_view_repository.dart';
import 'package:paperless_mobile/core/repository/state/impl/correspondent_repository_state.dart';
import 'package:paperless_mobile/core/repository/state/impl/document_type_repository_state.dart';
import 'package:paperless_mobile/core/repository/state/impl/storage_path_repository_state.dart';
import 'package:paperless_mobile/core/repository/state/impl/tag_repository_state.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:provider/provider.dart';

View File

@@ -5,7 +5,7 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
import 'package:paperless_mobile/core/repository/label_repository.dart';
import 'package:paperless_mobile/features/inbox/bloc/state/inbox_state.dart';
import 'package:paperless_mobile/features/inbox/cubit/state/inbox_state.dart';
import 'package:paperless_mobile/features/paged_document_view/paged_documents_mixin.dart';
class InboxCubit extends HydratedCubit<InboxState> with PagedDocumentsMixin {

View File

@@ -9,8 +9,8 @@ import 'package:paperless_mobile/features/documents/view/widgets/documents_list_
import 'package:paperless_mobile/core/widgets/hint_card.dart';
import 'package:paperless_mobile/extensions/dart_extensions.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart';
import 'package:paperless_mobile/features/inbox/bloc/state/inbox_state.dart';
import 'package:paperless_mobile/features/inbox/cubit/inbox_cubit.dart';
import 'package:paperless_mobile/features/inbox/cubit/state/inbox_state.dart';
import 'package:paperless_mobile/features/inbox/view/widgets/inbox_empty_widget.dart';
import 'package:paperless_mobile/features/inbox/view/widgets/inbox_item.dart';
import 'package:paperless_mobile/features/search_app_bar/view/search_app_bar.dart';

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart';
import 'package:paperless_mobile/features/inbox/cubit/inbox_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';
class InboxEmptyWidget extends StatelessWidget {

View File

@@ -5,7 +5,7 @@ import 'package:paperless_mobile/core/workarounds/colored_chip.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/documents/view/widgets/delete_document_confirmation_dialog.dart';
import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart';
import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart';
import 'package:paperless_mobile/features/inbox/cubit/inbox_cubit.dart';
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_widget.dart';
import 'package:paperless_mobile/features/labels/view/widgets/label_text.dart';
import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -2,9 +2,9 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/repository/state/impl/correspondent_repository_state.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/bloc/providers/correspondent_bloc_provider.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/providers/correspondent_bloc_provider.dart';
class CorrespondentWidget extends StatelessWidget {
final int? correspondentId;

View File

@@ -3,7 +3,7 @@ import 'dart:async';
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/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
class LabelCubit<T extends Label> extends Cubit<LabelState<T>> {
final LabelRepository<T> _repository;

View File

@@ -3,7 +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/core/repository/state/impl/correspondent_repository_state.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
class CorrespondentBlocProvider extends StatelessWidget {
final Widget child;

View File

@@ -3,7 +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/core/repository/state/impl/document_type_repository_state.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
class DocumentTypeBlocProvider extends StatelessWidget {
final Widget child;

View File

@@ -6,7 +6,7 @@ import 'package:paperless_mobile/core/repository/state/impl/correspondent_reposi
import 'package:paperless_mobile/core/repository/state/impl/document_type_repository_state.dart';
import 'package:paperless_mobile/core/repository/state/impl/storage_path_repository_state.dart';
import 'package:paperless_mobile/core/repository/state/impl/tag_repository_state.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
class LabelsBlocProvider extends StatelessWidget {
final Widget child;

View File

@@ -3,7 +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/core/repository/state/impl/storage_path_repository_state.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
class StoragePathBlocProvider extends StatelessWidget {
final Widget child;

View File

@@ -3,7 +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/core/repository/state/impl/tag_repository_state.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
class TagBlocProvider extends StatelessWidget {
final Widget child;

View File

@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/bloc/providers/document_type_bloc_provider.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/providers/document_type_bloc_provider.dart';
class DocumentTypeWidget extends StatelessWidget {
final int? documentTypeId;

View File

@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/bloc/providers/storage_path_bloc_provider.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/providers/storage_path_bloc_provider.dart';
class StoragePathWidget extends StatelessWidget {
final int? pathId;

View File

@@ -1,9 +1,9 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/bloc/providers/tag_bloc_provider.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/providers/tag_bloc_provider.dart';
import 'package:paperless_mobile/features/labels/tags/view/widgets/tag_widget.dart';
class TagsWidget extends StatelessWidget {

View File

@@ -15,7 +15,7 @@ import 'package:paperless_mobile/features/edit_label/view/impl/edit_corresponden
import 'package:paperless_mobile/features/edit_label/view/impl/edit_document_type_page.dart';
import 'package:paperless_mobile/features/edit_label/view/impl/edit_storage_path_page.dart';
import 'package:paperless_mobile/features/edit_label/view/impl/edit_tag_page.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/view/widgets/label_tab_view.dart';
import 'package:paperless_mobile/features/search_app_bar/view/search_app_bar.dart';
import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -1,8 +1,8 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/linked_documents/bloc/linked_documents_cubit.dart';
import 'package:paperless_mobile/features/linked_documents/view/pages/linked_documents_page.dart';
import 'package:paperless_mobile/features/linked_documents/cubit/linked_documents_cubit.dart';
import 'package:paperless_mobile/features/linked_documents/view/linked_documents_page.dart';
import 'package:paperless_mobile/helpers/format_helpers.dart';
class LabelItem<T extends Label> extends StatelessWidget {

View File

@@ -3,9 +3,9 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
import 'package:paperless_mobile/core/translation/matching_algorithm_localization_mapper.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/core/widgets/offline_widget.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
import 'package:paperless_mobile/features/labels/view/widgets/label_item.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';

View File

@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
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/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/cubit/label_cubit.dart';
import 'package:paperless_mobile/features/labels/cubit/label_state.dart';
class LabelText<T extends Label> extends StatelessWidget {
final int? id;

View File

@@ -1,8 +1,9 @@
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
import 'package:paperless_mobile/features/linked_documents/bloc/state/linked_documents_state.dart';
import 'package:paperless_mobile/features/paged_document_view/model/paged_documents_state.dart';
import 'package:paperless_mobile/features/paged_document_view/paged_documents_mixin.dart';
part 'linked_documents_state.dart';
class LinkedDocumentsCubit extends Cubit<LinkedDocumentsState>
with PagedDocumentsMixin {

View File

@@ -1,5 +1,5 @@
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/paged_document_view/model/paged_documents_state.dart';
part of 'linked_documents_cubit.dart';
class LinkedDocumentsState extends PagedDocumentsState {
const LinkedDocumentsState({

View File

@@ -3,8 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
import 'package:paperless_mobile/features/documents/view/widgets/adaptive_documents_view.dart';
import 'package:paperless_mobile/features/linked_documents/bloc/linked_documents_cubit.dart';
import 'package:paperless_mobile/features/linked_documents/bloc/state/linked_documents_state.dart';
import 'package:paperless_mobile/features/linked_documents/cubit/linked_documents_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/routes/document_details_route.dart';

View File

@@ -1,12 +1,14 @@
import 'package:dio/dio.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/security/session_manager.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';
part 'authentication_state.dart';
part 'authentication_cubit.g.dart';
class AuthenticationCubit extends Cubit<AuthenticationState>
with HydratedMixin<AuthenticationState> {

View File

@@ -1,12 +1,9 @@
import 'package:json_annotation/json_annotation.dart';
import 'package:paperless_mobile/features/login/model/authentication_information.dart';
part 'authentication_state.g.dart';
part of 'authentication_cubit.dart';
@JsonSerializable()
class AuthenticationState {
final bool wasLoginStored;
@JsonKey(ignore: true)
@JsonKey(includeFromJson: false, includeToJson: false)
final bool? wasLocalAuthenticationSuccessful;
final AuthenticationInformation? authentication;

View File

@@ -3,17 +3,15 @@ import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/type/types.dart';
import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart';
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
import 'package:paperless_mobile/features/login/view/widgets/form_fields/client_certificate_form_field.dart';
import 'package:paperless_mobile/features/login/view/widgets/form_fields/server_address_form_field.dart';
import 'package:paperless_mobile/features/login/view/widgets/form_fields/user_credentials_form_field.dart';
import 'package:paperless_mobile/features/login/view/widgets/login_pages/server_connection_page.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/constants.dart';
import 'widgets/never_scrollable_scroll_behavior.dart';
import 'widgets/login_pages/server_login_page.dart';
import 'widgets/never_scrollable_scroll_behavior.dart';
class LoginPage extends StatefulWidget {
const LoginPage({Key? key}) : super(key: key);

View File

@@ -63,25 +63,48 @@ class _ClientCertificateFormFieldState
),
child: Column(
children: [
ListTile(
leading: ElevatedButton(
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
ElevatedButton(
onPressed: () => _onSelectFile(field),
child: Text(S.of(context).genericActionSelectText),
child:
Text(S.of(context).genericActionSelectText),
),
title: _buildSelectedFileText(field),
trailing: AbsorbPointer(
absorbing: field.value == null,
child: _selectedFile != null
? IconButton(
_buildSelectedFileText(field).paddedOnly(left: 8),
],
),
if (_selectedFile != null)
IconButton(
icon: const Icon(Icons.close),
onPressed: () => setState(() {
_selectedFile = null;
field.didChange(null);
}),
)
: null,
),
),
],
).padded(8),
// ListTile(
// leading: ElevatedButton(
// onPressed: () => _onSelectFile(field),
// child: Text(S.of(context).genericActionSelectText),
// ),
// title: _buildSelectedFileText(field),
// trailing: AbsorbPointer(
// absorbing: field.value == null,
// child: _selectedFile != null
// ? IconButton(
// icon: const Icon(Icons.close),
// onPressed: () => setState(() {
// _selectedFile = null;
// field.didChange(null);
// }),
// )
// : null,
// ),
// ),
if (_selectedFile != null) ...[
ObscuredInputTextFormField(
key: const ValueKey('login-client-cert-passphrase'),
@@ -127,7 +150,9 @@ class _ClientCertificateFormFieldState
assert(_selectedFile == null);
return Text(
S.of(context).loginPageClientCertificateSettingSelectFileText,
style: TextStyle(color: Theme.of(context).hintColor),
style: Theme.of(context).textTheme.labelMedium?.apply(
color: Theme.of(context).hintColor,
),
);
} else {
assert(_selectedFile != null);

View File

@@ -1,11 +1,10 @@
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/documents/view/widgets/search/document_filter_form.dart';
import 'package:paperless_mobile/features/labels/bloc/providers/labels_bloc_provider.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
class AddSavedViewPage extends StatefulWidget {
final DocumentFilter currentFilter;

View File

@@ -2,11 +2,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/core/widgets/hint_card.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/cubit/documents_cubit.dart';
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart';
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_details_cubit.dart';
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_state.dart';
import 'package:paperless_mobile/features/saved_view/view/saved_view_page.dart';
import 'package:paperless_mobile/features/saved_view_details/cubit/saved_view_details_cubit.dart';
import 'package:paperless_mobile/features/saved_view_details/view/saved_view_details_page.dart';
import 'package:paperless_mobile/generated/l10n.dart';
class SavedViewList extends StatelessWidget {
@@ -48,7 +48,7 @@ class SavedViewList extends StatelessWidget {
),
),
],
child: SavedViewPage(
child: SavedViewDetailsPage(
onDelete: savedViewCubit.remove,
),
),

View File

@@ -1,218 +0,0 @@
// import 'dart:math';
// import 'package:flutter/material.dart';
// import 'package:flutter_bloc/flutter_bloc.dart';
// import 'package:paperless_api/paperless_api.dart';
// import 'package:paperless_mobile/core/bloc/connectivity_cubit.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/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';
// import 'package:paperless_mobile/features/saved_view/view/add_saved_view_page.dart';
// import 'package:paperless_mobile/generated/l10n.dart';
// import 'package:paperless_mobile/helpers/message_helpers.dart';
// import 'package:paperless_mobile/constants.dart';
// import 'package:shimmer/shimmer.dart';
// class SavedViewSelectionWidget extends StatelessWidget {
// final DocumentFilter currentFilter;
// const SavedViewSelectionWidget({
// Key? key,
// required this.height,
// required this.enabled,
// required this.currentFilter,
// }) : super(key: key);
// final double height;
// final bool enabled;
// @override
// Widget build(BuildContext context) {
// return BlocBuilder<ConnectivityCubit, ConnectivityState>(
// builder: (context, connectivityState) {
// final hasInternetConnection = connectivityState.isConnected;
// return SizedBox(
// height: height,
// child: Column(
// mainAxisAlignment: MainAxisAlignment.start,
// crossAxisAlignment: CrossAxisAlignment.start,
// mainAxisSize: MainAxisSize.min,
// children: [
// BlocBuilder<SavedViewCubit, SavedViewState>(
// builder: (context, state) {
// if (!state.hasLoaded) {
// return _buildLoadingWidget(context);
// }
// if (state.value.isEmpty) {
// return Text(S.of(context).savedViewsEmptyStateText);
// }
// return SizedBox(
// height: 38,
// child: ListView.separated(
// itemCount: state.value.length,
// scrollDirection: Axis.horizontal,
// itemBuilder: (context, index) {
// final view = state.value.values.elementAt(index);
// return GestureDetector(
// onLongPress: hasInternetConnection
// ? () => _onDelete(context, view)
// : null,
// child: BlocBuilder<DocumentsCubit, DocumentsState>(
// builder: (context, docState) {
// final view = state.value.values.toList()[index];
// return FilterChip(
// label: Text(
// view.name,
// ),
// selected:
// view.id == docState.selectedSavedViewId,
// onSelected: enabled && hasInternetConnection
// ? (isSelected) =>
// _onSelected(isSelected, context, view)
// : null,
// );
// },
// ),
// );
// },
// separatorBuilder: (context, index) => const SizedBox(
// width: 4.0,
// ),
// ),
// );
// },
// ),
// BlocBuilder<SavedViewCubit, SavedViewState>(
// builder: (context, state) {
// return Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text(
// S.of(context).savedViewsLabel,
// style: Theme.of(context).textTheme.titleSmall,
// ),
// BlocBuilder<DocumentsCubit, DocumentsState>(
// buildWhen: (previous, current) =>
// previous.filter != current.filter,
// builder: (context, docState) {
// return TextButton.icon(
// icon: const Icon(Icons.add),
// onPressed: (enabled &&
// state.hasLoaded &&
// hasInternetConnection)
// ? () =>
// _onCreatePressed(context, docState.filter)
// : null,
// label: Text(S.of(context).savedViewCreateNewLabel),
// );
// },
// ),
// ],
// );
// },
// ),
// ],
// ).padded(),
// );
// },
// );
// }
// Widget _buildLoadingWidget(BuildContext context) {
// return SizedBox(
// height: 38,
// width: MediaQuery.of(context).size.width,
// child: Shimmer.fromColors(
// baseColor: Theme.of(context).brightness == Brightness.light
// ? Colors.grey[300]!
// : Colors.grey[900]!,
// highlightColor: Theme.of(context).brightness == Brightness.light
// ? Colors.grey[100]!
// : Colors.grey[600]!,
// child: ListView(
// scrollDirection: Axis.horizontal,
// physics: const NeverScrollableScrollPhysics(),
// children: [
// FilterChip(
// label: const SizedBox(width: 32),
// onSelected: (_) {},
// ),
// const SizedBox(width: 4.0),
// FilterChip(
// label: const SizedBox(width: 64),
// onSelected: (_) {},
// ),
// const SizedBox(width: 4.0),
// FilterChip(
// label: const SizedBox(width: 100),
// onSelected: (_) {},
// ),
// const SizedBox(width: 4.0),
// FilterChip(
// label: const SizedBox(width: 32),
// onSelected: (_) {},
// ),
// const SizedBox(width: 4.0),
// FilterChip(
// label: const SizedBox(width: 48),
// onSelected: (_) {},
// ),
// ],
// ),
// ),
// );
// }
// void _onCreatePressed(BuildContext context, DocumentFilter filter) async {
// final newView = await Navigator.of(context).push<SavedView?>(
// MaterialPageRoute(
// builder: (context) => AddSavedViewPage(
// currentFilter: filter,
// ),
// ),
// );
// if (newView != null) {
// try {
// await context.read<SavedViewCubit>().add(newView);
// } on PaperlessServerException catch (error, stackTrace) {
// showErrorMessage(context, error, stackTrace);
// }
// }
// }
// void _onSelected(
// bool selectionIntent,
// BuildContext context,
// SavedView view,
// ) async {
// if (selectionIntent) {
// context.read<DocumentsCubit>().selectView(view.id!);
// } else {
// context.read<DocumentsCubit>().unselectView();
// context.read<DocumentsCubit>().resetFilter();
// }
// }
// void _onDelete(BuildContext context, SavedView view) async {
// {
// final delete = await showDialog<bool>(
// context: context,
// builder: (context) => ConfirmDeleteSavedViewDialog(view: view),
// ) ??
// false;
// if (delete) {
// try {
// context.read<SavedViewCubit>().remove(view);
// if (context.read<DocumentsCubit>().state.selectedSavedViewId ==
// view.id) {
// await context.read<DocumentsCubit>().resetFilter();
// }
// } on PaperlessServerException catch (error, stackTrace) {
// showErrorMessage(context, error, stackTrace);
// }
// }
// }
// }
// }

View File

@@ -1,12 +1,15 @@
import 'package:bloc/bloc.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
import 'package:paperless_mobile/features/paged_document_view/model/paged_documents_state.dart';
import 'package:paperless_mobile/features/paged_document_view/paged_documents_mixin.dart';
import 'package:paperless_mobile/features/settings/model/view_type.dart';
part 'saved_view_details_cubit.g.dart';
part 'saved_view_details_state.dart';
class SavedViewDetailsCubit extends Cubit<SavedViewDetailsState>
class SavedViewDetailsCubit extends HydratedCubit<SavedViewDetailsState>
with PagedDocumentsMixin {
@override
final PaperlessDocumentsApi api;
@@ -27,4 +30,18 @@ class SavedViewDetailsCubit extends Cubit<SavedViewDetailsState>
);
updateFilter(filter: savedView.toDocumentFilter());
}
void setViewType(ViewType viewType) {
emit(state.copyWith(viewType: viewType));
}
@override
SavedViewDetailsState? fromJson(Map<String, dynamic> json) {
return SavedViewDetailsState.fromJson(json);
}
@override
Map<String, dynamic>? toJson(SavedViewDetailsState state) {
return state.toJson();
}
}

View File

@@ -1,7 +1,12 @@
part of 'saved_view_details_cubit.dart';
@JsonSerializable(ignoreUnannotated: true)
class SavedViewDetailsState extends PagedDocumentsState {
@JsonKey()
final ViewType viewType;
const SavedViewDetailsState({
this.viewType = ViewType.list,
super.filter,
super.hasLoaded,
super.isLoading,
@@ -10,10 +15,8 @@ class SavedViewDetailsState extends PagedDocumentsState {
@override
List<Object?> get props => [
filter,
hasLoaded,
isLoading,
value,
viewType,
...super.props,
];
@override
@@ -36,12 +39,19 @@ class SavedViewDetailsState extends PagedDocumentsState {
bool? isLoading,
List<PagedSearchResult<DocumentModel>>? value,
DocumentFilter? filter,
ViewType? viewType,
}) {
return SavedViewDetailsState(
hasLoaded: hasLoaded ?? this.hasLoaded,
isLoading: isLoading ?? this.isLoading,
value: value ?? this.value,
filter: filter ?? this.filter,
viewType: viewType ?? this.viewType,
);
}
factory SavedViewDetailsState.fromJson(Map<String, dynamic> json) =>
_$SavedViewDetailsStateFromJson(json);
Map<String, dynamic> toJson() => _$SavedViewDetailsStateToJson(this);
}

View File

@@ -2,33 +2,27 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
import 'package:paperless_mobile/core/repository/provider/label_repositories_provider.dart';
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/view/widgets/adaptive_documents_view.dart';
import 'package:paperless_mobile/features/documents/view/widgets/documents_empty_state.dart';
import 'package:paperless_mobile/features/documents/view/widgets/selection/confirm_delete_saved_view_dialog.dart';
import 'package:paperless_mobile/features/documents/view/widgets/view_actions.dart';
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_details_cubit.dart';
import 'package:paperless_mobile/features/settings/model/view_type.dart';
import 'package:paperless_mobile/features/documents/view/widgets/selection/view_type_selection_widget.dart';
import 'package:paperless_mobile/features/saved_view_details/cubit/saved_view_details_cubit.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
import 'package:paperless_mobile/routes/document_details_route.dart';
class SavedViewPage extends StatefulWidget {
class SavedViewDetailsPage extends StatefulWidget {
final Future<void> Function(SavedView savedView) onDelete;
const SavedViewPage({
const SavedViewDetailsPage({
super.key,
required this.onDelete,
});
@override
State<SavedViewPage> createState() => _SavedViewPageState();
State<SavedViewDetailsPage> createState() => _SavedViewDetailsPageState();
}
class _SavedViewPageState extends State<SavedViewPage> {
class _SavedViewDetailsPageState extends State<SavedViewDetailsPage> {
final _scrollController = ScrollController();
ViewType _viewType = ViewType.list;
SavedView get _savedView => context.read<SavedViewDetailsCubit>().savedView;
@override
void initState() {
@@ -52,13 +46,11 @@ class _SavedViewPageState extends State<SavedViewPage> {
@override
Widget build(BuildContext context) {
final cubit = context.read<SavedViewDetailsCubit>();
return Scaffold(
appBar: AppBar(
title: BlocBuilder<SavedViewDetailsCubit, SavedViewDetailsState>(
builder: (context, state) {
return Text(_savedView.name);
},
),
title: Text(cubit.savedView.name),
actions: [
IconButton(
icon: const Icon(Icons.delete),
@@ -66,21 +58,23 @@ class _SavedViewPageState extends State<SavedViewPage> {
final shouldDelete = await showDialog<bool>(
context: context,
builder: (context) =>
ConfirmDeleteSavedViewDialog(view: _savedView),
ConfirmDeleteSavedViewDialog(view: cubit.savedView),
) ??
false;
if (shouldDelete) {
await widget.onDelete(_savedView);
await widget.onDelete(cubit.savedView);
Navigator.pop(context);
}
},
),
IconButton(
icon: Icon(
_viewType == ViewType.list ? Icons.grid_view_rounded : Icons.list,
),
onPressed: () => setState(() => _viewType = _viewType.toggle()),
),
BlocBuilder<SavedViewDetailsCubit, SavedViewDetailsState>(
builder: (context, state) {
return ViewTypeSelectionWidget(
viewType: state.viewType,
onChanged: cubit.setViewType,
);
},
)
],
),
body: BlocBuilder<SavedViewDetailsCubit, SavedViewDetailsState>(
@@ -100,7 +94,7 @@ class _SavedViewPageState extends State<SavedViewPage> {
isLoading: state.isLoading,
hasLoaded: state.hasLoaded,
onTap: _onOpenDocumentDetails,
viewType: _viewType,
viewType: state.viewType,
),
if (state.hasLoaded && state.isLoading)
const SliverToBoxAdapter(

View File

@@ -1,9 +1,14 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:paperless_mobile/features/login/services/authentication_service.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_state.dart';
import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart';
import 'package:paperless_mobile/features/settings/model/view_type.dart';
import 'package:paperless_mobile/generated/l10n.dart';
part 'application_settings_cubit.g.dart';
part 'application_settings_state.dart';
class ApplicationSettingsCubit extends HydratedCubit<ApplicationSettingsState> {
final LocalAuthenticationService _localAuthenticationService;
@@ -33,11 +38,6 @@ class ApplicationSettingsCubit extends HydratedCubit<ApplicationSettingsState> {
_updateSettings(updatedSettings);
}
void setViewType(ViewType viewType) {
final updatedSettings = state.copyWith(preferredViewType: viewType);
_updateSettings(updatedSettings);
}
void setColorSchemeOption(ColorSchemeOption schemeOption) {
final updatedSettings =
state.copyWith(preferredColorSchemeOption: schemeOption);

View File

@@ -1,12 +1,4 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart';
import 'package:paperless_mobile/features/settings/model/view_type.dart';
import 'package:paperless_mobile/generated/l10n.dart';
part 'application_settings_state.g.dart';
part of 'application_settings_cubit.dart';
///
/// State holding the current application settings such as selected language, theme mode and more.
@@ -20,14 +12,12 @@ class ApplicationSettingsState {
final bool isLocalAuthenticationEnabled;
final String preferredLocaleSubtag;
final ThemeMode preferredThemeMode;
final ViewType preferredViewType;
final ColorSchemeOption preferredColorSchemeOption;
ApplicationSettingsState({
required this.preferredLocaleSubtag,
this.preferredThemeMode = ThemeMode.system,
this.isLocalAuthenticationEnabled = false,
this.preferredViewType = ViewType.list,
this.preferredColorSchemeOption = ColorSchemeOption.classic,
});
@@ -39,7 +29,6 @@ class ApplicationSettingsState {
bool? isLocalAuthenticationEnabled,
String? preferredLocaleSubtag,
ThemeMode? preferredThemeMode,
ViewType? preferredViewType,
ColorSchemeOption? preferredColorSchemeOption,
}) {
return ApplicationSettingsState(
@@ -48,7 +37,6 @@ class ApplicationSettingsState {
preferredLocaleSubtag:
preferredLocaleSubtag ?? this.preferredLocaleSubtag,
preferredThemeMode: preferredThemeMode ?? this.preferredThemeMode,
preferredViewType: preferredViewType ?? this.preferredViewType,
preferredColorSchemeOption:
preferredColorSchemeOption ?? this.preferredColorSchemeOption,
);

View File

@@ -8,8 +8,8 @@ import 'package:paperless_mobile/core/repository/label_repository.dart';
import 'package:paperless_mobile/core/repository/saved_view_repository.dart';
import 'package:paperless_mobile/core/widgets/hint_card.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
@@ -48,14 +48,14 @@ class AccountSettingsDialog extends StatelessWidget {
),
],
),
Divider(),
const Divider(),
ListTile(
dense: true,
leading: const Icon(Icons.person_add_rounded),
title: Text(S.of(context).accountSettingsAddAnotherAccount),
onTap: () {},
),
Divider(),
const Divider(),
FilledButton(
style: ButtonStyle(
backgroundColor: MaterialStatePropertyAll(

View File

@@ -1,22 +1,12 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart';
import 'package:paperless_mobile/core/bloc/paperless_server_information_state.dart';
import 'package:paperless_mobile/core/repository/label_repository.dart';
import 'package:paperless_mobile/core/repository/saved_view_repository.dart';
import 'package:paperless_mobile/core/repository/state/impl/correspondent_repository_state.dart';
import 'package:paperless_mobile/core/repository/state/impl/document_type_repository_state.dart';
import 'package:paperless_mobile/core/repository/state/impl/storage_path_repository_state.dart';
import 'package:paperless_mobile/core/repository/state/impl/tag_repository_state.dart';
import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/view/pages/application_settings_page.dart';
import 'package:paperless_mobile/features/settings/view/pages/security_settings_page.dart';
import 'package:paperless_mobile/features/settings/view/pages/storage_settings_page.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/helpers/message_helpers.dart';
class SettingsPage extends StatelessWidget {
const SettingsPage({super.key});

View File

@@ -1,10 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/features/login/services/authentication_service.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_state.dart';
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:provider/provider.dart';
class BiometricAuthenticationSetting extends StatelessWidget {
const BiometricAuthenticationSetting({super.key});

View File

@@ -2,16 +2,13 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/constants.dart';
import 'package:paperless_mobile/core/translation/color_scheme_option_localization_mapper.dart';
import 'package:paperless_mobile/core/widgets/hint_card.dart';
import 'package:paperless_mobile/features/login/services/authentication_service.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_state.dart';
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart';
import 'package:paperless_mobile/features/settings/view/widgets/radio_settings_dialog.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/constants.dart';
import 'package:provider/provider.dart';
class ColorSchemeOptionSetting extends StatelessWidget {
const ColorSchemeOptionSetting({super.key});

View File

@@ -1,8 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/core/widgets/hint_card.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_state.dart';
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/view/widgets/radio_settings_dialog.dart';
import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -1,7 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_state.dart';
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/view/widgets/radio_settings_dialog.dart';
import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -35,13 +35,11 @@ import 'package:paperless_mobile/core/service/file_service.dart';
import 'package:paperless_mobile/features/app_intro/application_intro_slideshow.dart';
import 'package:paperless_mobile/features/home/view/home_page.dart';
import 'package:paperless_mobile/features/home/view/widget/verify_identity_page.dart';
import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart';
import 'package:paperless_mobile/features/login/bloc/authentication_state.dart';
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
import 'package:paperless_mobile/features/login/services/authentication_service.dart';
import 'package:paperless_mobile/features/login/view/login_page.dart';
import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/bloc/application_settings_state.dart';
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
import 'package:paperless_mobile/features/sharing/share_intent_queue.dart';
import 'package:paperless_mobile/features/tasks/cubit/task_status_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -1,9 +1,8 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/repository/provider/label_repositories_provider.dart';
import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart';
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
import 'package:paperless_mobile/features/document_details/view/pages/document_details_page.dart';
class DocumentDetailsRoute extends StatelessWidget {

View File

@@ -1,15 +1,18 @@
import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
part 'paged_search_result.g.dart';
const pageRegex = r".*page=(\d+).*";
class PagedSearchResultJsonSerializer<T> {
final Map<String, dynamic> json;
JsonConverter<T, Map<String, dynamic>> converter;
JsonConverter<T, Object?> converter;
PagedSearchResultJsonSerializer(this.json, this.converter);
}
@JsonSerializable(genericArgumentFactories: true)
class PagedSearchResult<T> extends Equatable {
/// Total number of available items
final int count;
@@ -53,32 +56,24 @@ class PagedSearchResult<T> extends Equatable {
required this.results,
});
factory PagedSearchResult.fromJsonT(Map<String, dynamic> json,
JsonConverter<T, Map<String, dynamic>> converter) {
return PagedSearchResult(
count: json['count'],
next: json['next'],
previous: json['previous'],
results: List<Map<String, dynamic>>.from(json['results'])
.map<T>(converter.fromJson)
.toList(),
);
}
factory PagedSearchResult.fromJson(
Map<String, dynamic> json,
T Function(Object?) fromJsonT,
) =>
_$PagedSearchResultFromJson(json, fromJsonT);
Map<String, dynamic> toJson(
JsonConverter<T, Map<String, dynamic>> converter) {
return {
'count': count,
'next': next,
'previous': previous,
'results': results.map((e) => converter.toJson(e)).toList()
};
}
Object? Function(T value) toJsonT,
) =>
_$PagedSearchResultToJson(this, toJsonT);
factory PagedSearchResult.fromJsonSingleParam(
PagedSearchResultJsonSerializer<T> serializer,
) {
return PagedSearchResult.fromJsonT(serializer.json, serializer.converter);
return PagedSearchResult.fromJson(
serializer.json,
serializer.converter.fromJson,
);
}
PagedSearchResult<T> copyWith({

View File

@@ -1,10 +1,10 @@
// import 'package:bloc_test/bloc_test.dart';
// import 'package:paperless_api/paperless_api.dart';
// import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
// import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
// import 'package:flutter_test/flutter_test.dart';
// import 'package:mockito/annotations.dart';
// import 'package:mockito/mockito.dart';
// import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
// import 'package:paperless_mobile/features/documents/cubit/documents_state.dart';
// import '../../utils.dart';
// @GenerateNiceMocks([MockSpec<PaperlessDocumentsApi>()])