mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-13 08:12:14 -06:00
feat: Add hive type adapters to api models, migrate to freezed
This commit is contained in:
@@ -1,21 +1,23 @@
|
|||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/custom_adapters/theme_mode_adapter.dart';
|
import 'package:paperless_mobile/core/config/hive/custom_adapters/theme_mode_adapter.dart';
|
||||||
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
|
import 'package:paperless_mobile/core/database/tables/user_app_state.dart';
|
||||||
|
import 'package:paperless_mobile/core/database/tables/user_credentials.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/authentication_information.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/client_certificate.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_credentials.dart';
|
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
|
||||||
import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart';
|
import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/user_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/user_settings.dart';
|
||||||
|
|
||||||
class HiveBoxes {
|
class HiveBoxes {
|
||||||
HiveBoxes._();
|
HiveBoxes._();
|
||||||
static const globalSettings = 'globalSettings';
|
static const globalSettings = 'globalSettings';
|
||||||
static const userSettings = 'userSettings';
|
|
||||||
static const authentication = 'authentication';
|
static const authentication = 'authentication';
|
||||||
static const userCredentials = 'userCredentials';
|
static const userCredentials = 'userCredentials';
|
||||||
static const userAccount = 'userAccount';
|
static const userAccount = 'userAccount';
|
||||||
|
static const userAppState = 'userAppState';
|
||||||
|
static const userSettings = 'userSettings';
|
||||||
}
|
}
|
||||||
|
|
||||||
class HiveTypeIds {
|
class HiveTypeIds {
|
||||||
@@ -28,9 +30,11 @@ class HiveTypeIds {
|
|||||||
static const clientCertificate = 5;
|
static const clientCertificate = 5;
|
||||||
static const userCredentials = 6;
|
static const userCredentials = 6;
|
||||||
static const userAccount = 7;
|
static const userAccount = 7;
|
||||||
|
static const userAppState = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerHiveAdapters() {
|
void registerHiveAdapters() {
|
||||||
|
registerPaperlessApiHiveTypeAdapters();
|
||||||
Hive.registerAdapter(ColorSchemeOptionAdapter());
|
Hive.registerAdapter(ColorSchemeOptionAdapter());
|
||||||
Hive.registerAdapter(ThemeModeAdapter());
|
Hive.registerAdapter(ThemeModeAdapter());
|
||||||
Hive.registerAdapter(GlobalSettingsAdapter());
|
Hive.registerAdapter(GlobalSettingsAdapter());
|
||||||
@@ -39,7 +43,7 @@ void registerHiveAdapters() {
|
|||||||
Hive.registerAdapter(UserSettingsAdapter());
|
Hive.registerAdapter(UserSettingsAdapter());
|
||||||
Hive.registerAdapter(UserCredentialsAdapter());
|
Hive.registerAdapter(UserCredentialsAdapter());
|
||||||
Hive.registerAdapter(UserAccountAdapter());
|
Hive.registerAdapter(UserAccountAdapter());
|
||||||
Hive.registerAdapter(DocumentFilterAdapter());
|
Hive.registerAdapter(UserAppStateAdapter());
|
||||||
}
|
}
|
||||||
|
|
||||||
extension HiveSingleValueBox<T> on Box<T> {
|
extension HiveSingleValueBox<T> on Box<T> {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/user_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/user_settings.dart';
|
||||||
|
|
||||||
part 'user_account.g.dart';
|
part 'user_account.g.dart';
|
||||||
|
|
||||||
22
lib/core/database/tables/user_app_state.dart
Normal file
22
lib/core/database/tables/user_app_state.dart
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:hive_flutter/adapters.dart';
|
||||||
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
|
part 'user_app_state.g.dart';
|
||||||
|
|
||||||
|
@HiveType(typeId: HiveTypeIds.userAppState)
|
||||||
|
class UserAppState extends HiveObject {
|
||||||
|
@HiveField(0)
|
||||||
|
final String userId;
|
||||||
|
|
||||||
|
@HiveField(1)
|
||||||
|
DocumentFilter currentDocumentFilter;
|
||||||
|
|
||||||
|
@HiveField(2)
|
||||||
|
List<String> documentSearchHistory;
|
||||||
|
|
||||||
|
UserAppState({
|
||||||
|
required this.userId,
|
||||||
|
this.currentDocumentFilter = const DocumentFilter(),
|
||||||
|
this.documentSearchHistory = const [],
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -9,11 +9,7 @@ class UserSettings with HiveObjectMixin {
|
|||||||
@HiveField(0)
|
@HiveField(0)
|
||||||
bool isBiometricAuthenticationEnabled;
|
bool isBiometricAuthenticationEnabled;
|
||||||
|
|
||||||
@HiveField(1)
|
|
||||||
DocumentFilter currentDocumentFilter;
|
|
||||||
|
|
||||||
UserSettings({
|
UserSettings({
|
||||||
this.isBiometricAuthenticationEnabled = false,
|
this.isBiometricAuthenticationEnabled = false,
|
||||||
required this.currentDocumentFilter,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -9,7 +9,7 @@ import 'package:paperless_mobile/core/bloc/document_status_cubit.dart';
|
|||||||
import 'package:paperless_mobile/core/model/document_processing_status.dart';
|
import 'package:paperless_mobile/core/model/document_processing_status.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/authentication_information.dart';
|
import 'package:paperless_mobile/features/login/model/authentication_information.dart';
|
||||||
import 'package:paperless_mobile/constants.dart';
|
import 'package:paperless_mobile/constants.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_credentials.dart';
|
import 'package:paperless_mobile/core/database/tables/user_credentials.dart';
|
||||||
import 'package:web_socket_channel/io.dart';
|
import 'package:web_socket_channel/io.dart';
|
||||||
|
|
||||||
abstract class StatusService {
|
abstract class StatusService {
|
||||||
|
|||||||
@@ -8,8 +8,7 @@ import 'package:paperless_mobile/features/document_bulk_action/cubit/document_bu
|
|||||||
import 'package:paperless_mobile/features/labels/view/widgets/label_form_field.dart';
|
import 'package:paperless_mobile/features/labels/view/widgets/label_form_field.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
typedef LabelOptionsSelector<T extends Label> = Map<int, T> Function(
|
typedef LabelOptionsSelector<T extends Label> = Map<int, T> Function(DocumentBulkActionState state);
|
||||||
DocumentBulkActionState state);
|
|
||||||
|
|
||||||
class BulkEditLabelBottomSheet<T extends Label> extends StatefulWidget {
|
class BulkEditLabelBottomSheet<T extends Label> extends StatefulWidget {
|
||||||
final String title;
|
final String title;
|
||||||
@@ -30,19 +29,16 @@ class BulkEditLabelBottomSheet<T extends Label> extends StatefulWidget {
|
|||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<BulkEditLabelBottomSheet<T>> createState() =>
|
State<BulkEditLabelBottomSheet<T>> createState() => _BulkEditLabelBottomSheetState<T>();
|
||||||
_BulkEditLabelBottomSheetState<T>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BulkEditLabelBottomSheetState<T extends Label>
|
class _BulkEditLabelBottomSheetState<T extends Label> extends State<BulkEditLabelBottomSheet<T>> {
|
||||||
extends State<BulkEditLabelBottomSheet<T>> {
|
|
||||||
final _formKey = GlobalKey<FormBuilderState>();
|
final _formKey = GlobalKey<FormBuilderState>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Padding(
|
return Padding(
|
||||||
padding:
|
padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
||||||
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
|
|
||||||
child: BlocBuilder<DocumentBulkActionCubit, DocumentBulkActionState>(
|
child: BlocBuilder<DocumentBulkActionCubit, DocumentBulkActionState>(
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return Padding(
|
return Padding(
|
||||||
@@ -59,8 +55,7 @@ class _BulkEditLabelBottomSheetState<T extends Label>
|
|||||||
FormBuilder(
|
FormBuilder(
|
||||||
key: _formKey,
|
key: _formKey,
|
||||||
child: LabelFormField<T>(
|
child: LabelFormField<T>(
|
||||||
initialValue:
|
initialValue: IdQueryParameter.fromId(widget.initialValue),
|
||||||
IdQueryParameter.fromId(widget.initialValue),
|
|
||||||
name: "labelFormField",
|
name: "labelFormField",
|
||||||
options: widget.availableOptionsSelector(state),
|
options: widget.availableOptionsSelector(state),
|
||||||
labelText: widget.formFieldLabel,
|
labelText: widget.formFieldLabel,
|
||||||
@@ -75,12 +70,11 @@ class _BulkEditLabelBottomSheetState<T extends Label>
|
|||||||
const SizedBox(width: 16),
|
const SizedBox(width: 16),
|
||||||
FilledButton(
|
FilledButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (_formKey.currentState?.saveAndValidate() ??
|
if (_formKey.currentState?.saveAndValidate() ?? false) {
|
||||||
false) {
|
final value = _formKey.currentState?.getRawValue('labelFormField')
|
||||||
final value = _formKey.currentState
|
|
||||||
?.getRawValue('labelFormField')
|
|
||||||
as IdQueryParameter?;
|
as IdQueryParameter?;
|
||||||
widget.onSubmit(value?.id);
|
widget
|
||||||
|
.onSubmit(value?.maybeWhen(fromId: (id) => id, orElse: () => null));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
child: Text(S.of(context)!.apply),
|
child: Text(S.of(context)!.apply),
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'package:paperless_api/paperless_api.dart';
|
|||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/view/dialogs/select_file_type_dialog.dart';
|
import 'package:paperless_mobile/features/document_details/view/dialogs/select_file_type_dialog.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
||||||
|
|||||||
@@ -50,8 +50,8 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_filteredSuggestions = widget.suggestions
|
_filteredSuggestions =
|
||||||
?.documentDifference(context.read<DocumentEditCubit>().state.document);
|
widget.suggestions?.documentDifference(context.read<DocumentEditCubit>().state.document);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -95,16 +95,14 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
ListView(
|
ListView(
|
||||||
children: [
|
children: [
|
||||||
_buildTitleFormField(state.document.title).padded(),
|
_buildTitleFormField(state.document.title).padded(),
|
||||||
_buildCreatedAtFormField(state.document.created)
|
_buildCreatedAtFormField(state.document.created).padded(),
|
||||||
.padded(),
|
|
||||||
// Correspondent form field
|
// Correspondent form field
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
LabelFormField<Correspondent>(
|
LabelFormField<Correspondent>(
|
||||||
showAnyAssignedOption: false,
|
showAnyAssignedOption: false,
|
||||||
showNotAssignedOption: false,
|
showNotAssignedOption: false,
|
||||||
addLabelPageBuilder: (initialValue) =>
|
addLabelPageBuilder: (initialValue) => RepositoryProvider.value(
|
||||||
RepositoryProvider.value(
|
|
||||||
value: context.read<LabelRepository>(),
|
value: context.read<LabelRepository>(),
|
||||||
child: AddCorrespondentPage(
|
child: AddCorrespondentPage(
|
||||||
initialName: initialValue,
|
initialName: initialValue,
|
||||||
@@ -112,30 +110,20 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
),
|
),
|
||||||
addLabelText: S.of(context)!.addCorrespondent,
|
addLabelText: S.of(context)!.addCorrespondent,
|
||||||
labelText: S.of(context)!.correspondent,
|
labelText: S.of(context)!.correspondent,
|
||||||
options: context
|
options: context.watch<DocumentEditCubit>().state.correspondents,
|
||||||
.watch<DocumentEditCubit>()
|
|
||||||
.state
|
|
||||||
.correspondents,
|
|
||||||
initialValue: IdQueryParameter.fromId(
|
initialValue: IdQueryParameter.fromId(
|
||||||
state.document.correspondent,
|
state.document.correspondent,
|
||||||
),
|
),
|
||||||
name: fkCorrespondent,
|
name: fkCorrespondent,
|
||||||
prefixIcon: const Icon(Icons.person_outlined),
|
prefixIcon: const Icon(Icons.person_outlined),
|
||||||
),
|
),
|
||||||
if (_filteredSuggestions
|
if (_filteredSuggestions?.hasSuggestedCorrespondents ?? false)
|
||||||
?.hasSuggestedCorrespondents ??
|
|
||||||
false)
|
|
||||||
_buildSuggestionsSkeleton<int>(
|
_buildSuggestionsSkeleton<int>(
|
||||||
suggestions:
|
suggestions: _filteredSuggestions!.correspondents,
|
||||||
_filteredSuggestions!.correspondents,
|
itemBuilder: (context, itemData) => ActionChip(
|
||||||
itemBuilder: (context, itemData) =>
|
label: Text(state.correspondents[itemData]!.name),
|
||||||
ActionChip(
|
|
||||||
label: Text(
|
|
||||||
state.correspondents[itemData]!.name),
|
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_formKey
|
_formKey.currentState?.fields[fkCorrespondent]?.didChange(
|
||||||
.currentState?.fields[fkCorrespondent]
|
|
||||||
?.didChange(
|
|
||||||
IdQueryParameter.fromId(itemData),
|
IdQueryParameter.fromId(itemData),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -149,8 +137,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
LabelFormField<DocumentType>(
|
LabelFormField<DocumentType>(
|
||||||
showAnyAssignedOption: false,
|
showAnyAssignedOption: false,
|
||||||
showNotAssignedOption: false,
|
showNotAssignedOption: false,
|
||||||
addLabelPageBuilder: (currentInput) =>
|
addLabelPageBuilder: (currentInput) => RepositoryProvider.value(
|
||||||
RepositoryProvider.value(
|
|
||||||
value: context.read<LabelRepository>(),
|
value: context.read<LabelRepository>(),
|
||||||
child: AddDocumentTypePage(
|
child: AddDocumentTypePage(
|
||||||
initialName: currentInput,
|
initialName: currentInput,
|
||||||
@@ -158,26 +145,18 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
),
|
),
|
||||||
addLabelText: S.of(context)!.addDocumentType,
|
addLabelText: S.of(context)!.addDocumentType,
|
||||||
labelText: S.of(context)!.documentType,
|
labelText: S.of(context)!.documentType,
|
||||||
initialValue: IdQueryParameter.fromId(
|
initialValue: IdQueryParameter.fromId(state.document.documentType),
|
||||||
state.document.documentType),
|
|
||||||
options: state.documentTypes,
|
options: state.documentTypes,
|
||||||
name: _DocumentEditPageState.fkDocumentType,
|
name: _DocumentEditPageState.fkDocumentType,
|
||||||
prefixIcon:
|
prefixIcon: const Icon(Icons.description_outlined),
|
||||||
const Icon(Icons.description_outlined),
|
|
||||||
),
|
),
|
||||||
if (_filteredSuggestions
|
if (_filteredSuggestions?.hasSuggestedDocumentTypes ?? false)
|
||||||
?.hasSuggestedDocumentTypes ??
|
|
||||||
false)
|
|
||||||
_buildSuggestionsSkeleton<int>(
|
_buildSuggestionsSkeleton<int>(
|
||||||
suggestions:
|
suggestions: _filteredSuggestions!.documentTypes,
|
||||||
_filteredSuggestions!.documentTypes,
|
itemBuilder: (context, itemData) => ActionChip(
|
||||||
itemBuilder: (context, itemData) =>
|
label: Text(state.documentTypes[itemData]!.name),
|
||||||
ActionChip(
|
onPressed: () =>
|
||||||
label: Text(
|
_formKey.currentState?.fields[fkDocumentType]?.didChange(
|
||||||
state.documentTypes[itemData]!.name),
|
|
||||||
onPressed: () => _formKey
|
|
||||||
.currentState?.fields[fkDocumentType]
|
|
||||||
?.didChange(
|
|
||||||
IdQueryParameter.fromId(itemData),
|
IdQueryParameter.fromId(itemData),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -190,17 +169,14 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
LabelFormField<StoragePath>(
|
LabelFormField<StoragePath>(
|
||||||
showAnyAssignedOption: false,
|
showAnyAssignedOption: false,
|
||||||
showNotAssignedOption: false,
|
showNotAssignedOption: false,
|
||||||
addLabelPageBuilder: (initialValue) =>
|
addLabelPageBuilder: (initialValue) => RepositoryProvider.value(
|
||||||
RepositoryProvider.value(
|
|
||||||
value: context.read<LabelRepository>(),
|
value: context.read<LabelRepository>(),
|
||||||
child: AddStoragePathPage(
|
child: AddStoragePathPage(initalName: initialValue),
|
||||||
initalName: initialValue),
|
|
||||||
),
|
),
|
||||||
addLabelText: S.of(context)!.addStoragePath,
|
addLabelText: S.of(context)!.addStoragePath,
|
||||||
labelText: S.of(context)!.storagePath,
|
labelText: S.of(context)!.storagePath,
|
||||||
options: state.storagePaths,
|
options: state.storagePaths,
|
||||||
initialValue: IdQueryParameter.fromId(
|
initialValue: IdQueryParameter.fromId(state.document.storagePath),
|
||||||
state.document.storagePath),
|
|
||||||
name: fkStoragePath,
|
name: fkStoragePath,
|
||||||
prefixIcon: const Icon(Icons.folder_outlined),
|
prefixIcon: const Icon(Icons.folder_outlined),
|
||||||
),
|
),
|
||||||
@@ -213,8 +189,8 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
allowOnlySelection: true,
|
allowOnlySelection: true,
|
||||||
allowCreation: true,
|
allowCreation: true,
|
||||||
allowExclude: false,
|
allowExclude: false,
|
||||||
initialValue: IdsTagsQuery.included(
|
initialValue: TagsQuery.ids(
|
||||||
state.document.tags,
|
include: state.document.tags,
|
||||||
),
|
),
|
||||||
).padded(),
|
).padded(),
|
||||||
if (_filteredSuggestions?.tags
|
if (_filteredSuggestions?.tags
|
||||||
@@ -223,8 +199,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
.isNotEmpty ??
|
.isNotEmpty ??
|
||||||
false)
|
false)
|
||||||
_buildSuggestionsSkeleton<int>(
|
_buildSuggestionsSkeleton<int>(
|
||||||
suggestions:
|
suggestions: (_filteredSuggestions?.tags.toSet() ?? {}),
|
||||||
(_filteredSuggestions?.tags.toSet() ?? {}),
|
|
||||||
itemBuilder: (context, itemData) {
|
itemBuilder: (context, itemData) {
|
||||||
final tag = state.tags[itemData]!;
|
final tag = state.tags[itemData]!;
|
||||||
return ActionChip(
|
return ActionChip(
|
||||||
@@ -234,17 +209,15 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
),
|
),
|
||||||
backgroundColor: tag.color,
|
backgroundColor: tag.color,
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
final currentTags = _formKey.currentState
|
final currentTags =
|
||||||
?.fields[fkTags]?.value as TagsQuery;
|
_formKey.currentState?.fields[fkTags]?.value as TagsQuery;
|
||||||
if (currentTags is IdsTagsQuery) {
|
_formKey.currentState?.fields[fkTags]?.didChange(
|
||||||
_formKey.currentState?.fields[fkTags]
|
currentTags.maybeWhen(
|
||||||
?.didChange((IdsTagsQuery.fromIds(
|
ids: (include, exclude) => TagsQuery.ids(
|
||||||
{...currentTags.ids, itemData})));
|
include: [...include, itemData], exclude: exclude),
|
||||||
} else {
|
orElse: () => TagsQuery.ids(include: [itemData]),
|
||||||
_formKey.currentState?.fields[fkTags]
|
),
|
||||||
?.didChange((IdsTagsQuery.fromIds(
|
);
|
||||||
{itemData})));
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -284,11 +257,12 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
var mergedDocument = document.copyWith(
|
var mergedDocument = document.copyWith(
|
||||||
title: values[fkTitle],
|
title: values[fkTitle],
|
||||||
created: values[fkCreatedDate],
|
created: values[fkCreatedDate],
|
||||||
documentType: () => (values[fkDocumentType] as IdQueryParameter).id,
|
documentType: () => (values[fkDocumentType] as SetIdQueryParameter).id,
|
||||||
correspondent: () => (values[fkCorrespondent] as IdQueryParameter).id,
|
correspondent: () => (values[fkCorrespondent] as SetIdQueryParameter).id,
|
||||||
storagePath: () => (values[fkStoragePath] as IdQueryParameter).id,
|
storagePath: () => (values[fkStoragePath] as SetIdQueryParameter).id,
|
||||||
tags: (values[fkTags] as IdsTagsQuery).includedIds,
|
tags: (values[fkTags] as IdsTagsQuery).include,
|
||||||
content: values[fkContent]);
|
content: values[fkContent],
|
||||||
|
);
|
||||||
setState(() {
|
setState(() {
|
||||||
_isSubmitLoading = true;
|
_isSubmitLoading = true;
|
||||||
});
|
});
|
||||||
@@ -342,8 +316,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
suggestions: _filteredSuggestions!.dates,
|
suggestions: _filteredSuggestions!.dates,
|
||||||
itemBuilder: (context, itemData) => ActionChip(
|
itemBuilder: (context, itemData) => ActionChip(
|
||||||
label: Text(DateFormat.yMMMd().format(itemData)),
|
label: Text(DateFormat.yMMMd().format(itemData)),
|
||||||
onPressed: () => _formKey.currentState?.fields[fkCreatedDate]
|
onPressed: () => _formKey.currentState?.fields[fkCreatedDate]?.didChange(itemData),
|
||||||
?.didChange(itemData),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -372,8 +345,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
itemBuilder: (context, index) => ColoredChipWrapper(
|
itemBuilder: (context, index) => ColoredChipWrapper(
|
||||||
child: itemBuilder(context, suggestions.elementAt(index)),
|
child: itemBuilder(context, suggestions.elementAt(index)),
|
||||||
),
|
),
|
||||||
separatorBuilder: (BuildContext context, int index) =>
|
separatorBuilder: (BuildContext context, int index) => const SizedBox(width: 4.0),
|
||||||
const SizedBox(width: 4.0),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -3,18 +3,17 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
|
|||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/paged_document_view/cubit/document_paging_bloc_mixin.dart';
|
import 'package:paperless_mobile/features/paged_document_view/cubit/document_paging_bloc_mixin.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:paperless_mobile/features/paged_document_view/cubit/paged_documents_state.dart';
|
import 'package:paperless_mobile/features/paged_document_view/cubit/paged_documents_state.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/user_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/user_settings.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/view_type.dart';
|
import 'package:paperless_mobile/features/settings/model/view_type.dart';
|
||||||
|
|
||||||
part 'document_search_state.dart';
|
part 'document_search_state.dart';
|
||||||
part 'document_search_cubit.g.dart';
|
part 'document_search_cubit.g.dart';
|
||||||
|
|
||||||
class DocumentSearchCubit extends HydratedCubit<DocumentSearchState>
|
class DocumentSearchCubit extends HydratedCubit<DocumentSearchState> with DocumentPagingBlocMixin {
|
||||||
with DocumentPagingBlocMixin {
|
|
||||||
@override
|
@override
|
||||||
final PaperlessDocumentsApi api;
|
final PaperlessDocumentsApi api;
|
||||||
|
|
||||||
@@ -58,8 +57,7 @@ class DocumentSearchCubit extends HydratedCubit<DocumentSearchState>
|
|||||||
state.copyWith(
|
state.copyWith(
|
||||||
searchHistory: [
|
searchHistory: [
|
||||||
query,
|
query,
|
||||||
...state.searchHistory
|
...state.searchHistory.whereNot((previousQuery) => previousQuery == query)
|
||||||
.whereNot((previousQuery) => previousQuery == query)
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -72,9 +70,7 @@ class DocumentSearchCubit extends HydratedCubit<DocumentSearchState>
|
|||||||
void removeHistoryEntry(String entry) {
|
void removeHistoryEntry(String entry) {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
searchHistory: state.searchHistory
|
searchHistory: state.searchHistory.whereNot((element) => element == entry).toList(),
|
||||||
.whereNot((element) => element == entry)
|
|
||||||
.toList(),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -121,6 +117,5 @@ class DocumentSearchCubit extends HydratedCubit<DocumentSearchState>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
// TODO: implement account
|
Future<void> onFilterUpdated(DocumentFilter filter) async {}
|
||||||
UserAccount get account => throw UnimplementedError();
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,10 +5,9 @@ import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.da
|
|||||||
import 'package:paperless_mobile/core/bloc/paperless_server_information_state.dart';
|
import 'package:paperless_mobile/core/bloc/paperless_server_information_state.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/delegate/customizable_sliver_persistent_header_delegate.dart';
|
import 'package:paperless_mobile/core/delegate/customizable_sliver_persistent_header_delegate.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/material/search/m3_search_bar.dart'
|
import 'package:paperless_mobile/core/widgets/material/search/m3_search_bar.dart' as s;
|
||||||
as s;
|
|
||||||
import 'package:paperless_mobile/features/document_search/view/document_search_page.dart';
|
import 'package:paperless_mobile/features/document_search/view/document_search_page.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/dialogs/account_settings_dialog.dart';
|
import 'package:paperless_mobile/features/settings/view/dialogs/account_settings_dialog.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/manage_accounts_page.dart';
|
import 'package:paperless_mobile/features/settings/view/manage_accounts_page.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
||||||
@@ -46,14 +45,10 @@ class SliverSearchBar extends StatelessWidget {
|
|||||||
icon: GlobalSettingsBuilder(
|
icon: GlobalSettingsBuilder(
|
||||||
builder: (context, settings) {
|
builder: (context, settings) {
|
||||||
return ValueListenableBuilder(
|
return ValueListenableBuilder(
|
||||||
valueListenable:
|
valueListenable: Hive.box<UserAccount>(HiveBoxes.userAccount).listenable(),
|
||||||
Hive.box<UserAccount>(HiveBoxes.userAccount)
|
|
||||||
.listenable(),
|
|
||||||
builder: (context, box, _) {
|
builder: (context, box, _) {
|
||||||
final account = box.get(settings.currentLoggedInUser!)!;
|
final account = box.get(settings.currentLoggedInUser!)!;
|
||||||
return UserAvatar(
|
return UserAvatar(userId: settings.currentLoggedInUser!, account: account);
|
||||||
userId: settings.currentLoggedInUser!,
|
|
||||||
account: account);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -41,12 +41,10 @@ class DocumentUploadPreparationPage extends StatefulWidget {
|
|||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<DocumentUploadPreparationPage> createState() =>
|
State<DocumentUploadPreparationPage> createState() => _DocumentUploadPreparationPageState();
|
||||||
_DocumentUploadPreparationPageState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DocumentUploadPreparationPageState
|
class _DocumentUploadPreparationPageState extends State<DocumentUploadPreparationPage> {
|
||||||
extends State<DocumentUploadPreparationPage> {
|
|
||||||
static const fkFileName = "filename";
|
static const fkFileName = "filename";
|
||||||
static final fileNameDateFormat = DateFormat("yyyy_MM_ddTHH_mm_ss");
|
static final fileNameDateFormat = DateFormat("yyyy_MM_ddTHH_mm_ss");
|
||||||
|
|
||||||
@@ -73,8 +71,7 @@ class _DocumentUploadPreparationPageState
|
|||||||
title: Text(S.of(context)!.prepareDocument),
|
title: Text(S.of(context)!.prepareDocument),
|
||||||
bottom: _isUploadLoading
|
bottom: _isUploadLoading
|
||||||
? const PreferredSize(
|
? const PreferredSize(
|
||||||
child: LinearProgressIndicator(),
|
child: LinearProgressIndicator(), preferredSize: Size.fromHeight(4.0))
|
||||||
preferredSize: Size.fromHeight(4.0))
|
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
floatingActionButton: Visibility(
|
floatingActionButton: Visibility(
|
||||||
@@ -95,8 +92,7 @@ class _DocumentUploadPreparationPageState
|
|||||||
FormBuilderTextField(
|
FormBuilderTextField(
|
||||||
autovalidateMode: AutovalidateMode.always,
|
autovalidateMode: AutovalidateMode.always,
|
||||||
name: DocumentModel.titleKey,
|
name: DocumentModel.titleKey,
|
||||||
initialValue:
|
initialValue: widget.title ?? "scan_${fileNameDateFormat.format(_now)}",
|
||||||
widget.title ?? "scan_${fileNameDateFormat.format(_now)}",
|
|
||||||
validator: (value) {
|
validator: (value) {
|
||||||
if (value?.trim().isEmpty ?? true) {
|
if (value?.trim().isEmpty ?? true) {
|
||||||
return S.of(context)!.thisFieldIsRequired;
|
return S.of(context)!.thisFieldIsRequired;
|
||||||
@@ -108,22 +104,18 @@ class _DocumentUploadPreparationPageState
|
|||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: const Icon(Icons.close),
|
icon: const Icon(Icons.close),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_formKey.currentState?.fields[DocumentModel.titleKey]
|
_formKey.currentState?.fields[DocumentModel.titleKey]?.didChange("");
|
||||||
?.didChange("");
|
|
||||||
if (_syncTitleAndFilename) {
|
if (_syncTitleAndFilename) {
|
||||||
_formKey.currentState?.fields[fkFileName]
|
_formKey.currentState?.fields[fkFileName]?.didChange("");
|
||||||
?.didChange("");
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
errorText: _errors[DocumentModel.titleKey],
|
errorText: _errors[DocumentModel.titleKey],
|
||||||
),
|
),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
final String transformedValue =
|
final String transformedValue = _formatFilename(value ?? '');
|
||||||
_formatFilename(value ?? '');
|
|
||||||
if (_syncTitleAndFilename) {
|
if (_syncTitleAndFilename) {
|
||||||
_formKey.currentState?.fields[fkFileName]
|
_formKey.currentState?.fields[fkFileName]?.didChange(transformedValue);
|
||||||
?.didChange(transformedValue);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -138,12 +130,10 @@ class _DocumentUploadPreparationPageState
|
|||||||
suffixText: widget.fileExtension,
|
suffixText: widget.fileExtension,
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: const Icon(Icons.clear),
|
icon: const Icon(Icons.clear),
|
||||||
onPressed: () => _formKey.currentState?.fields[fkFileName]
|
onPressed: () => _formKey.currentState?.fields[fkFileName]?.didChange(''),
|
||||||
?.didChange(''),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
initialValue: widget.filename ??
|
initialValue: widget.filename ?? "scan_${fileNameDateFormat.format(_now)}",
|
||||||
"scan_${fileNameDateFormat.format(_now)}",
|
|
||||||
),
|
),
|
||||||
// Synchronize title and filename
|
// Synchronize title and filename
|
||||||
SwitchListTile(
|
SwitchListTile(
|
||||||
@@ -153,13 +143,10 @@ class _DocumentUploadPreparationPageState
|
|||||||
() => _syncTitleAndFilename = value,
|
() => _syncTitleAndFilename = value,
|
||||||
);
|
);
|
||||||
if (_syncTitleAndFilename) {
|
if (_syncTitleAndFilename) {
|
||||||
final String transformedValue = _formatFilename(_formKey
|
final String transformedValue = _formatFilename(
|
||||||
.currentState
|
_formKey.currentState?.fields[DocumentModel.titleKey]?.value as String);
|
||||||
?.fields[DocumentModel.titleKey]
|
|
||||||
?.value as String);
|
|
||||||
if (_syncTitleAndFilename) {
|
if (_syncTitleAndFilename) {
|
||||||
_formKey.currentState?.fields[fkFileName]
|
_formKey.currentState?.fields[fkFileName]?.didChange(transformedValue);
|
||||||
?.didChange(transformedValue);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -184,8 +171,7 @@ class _DocumentUploadPreparationPageState
|
|||||||
? IconButton(
|
? IconButton(
|
||||||
icon: const Icon(Icons.close),
|
icon: const Icon(Icons.close),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
_formKey.currentState!
|
_formKey.currentState!.fields[DocumentModel.createdKey]
|
||||||
.fields[DocumentModel.createdKey]
|
|
||||||
?.didChange(null);
|
?.didChange(null);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@@ -196,8 +182,7 @@ class _DocumentUploadPreparationPageState
|
|||||||
LabelFormField<Correspondent>(
|
LabelFormField<Correspondent>(
|
||||||
showAnyAssignedOption: false,
|
showAnyAssignedOption: false,
|
||||||
showNotAssignedOption: false,
|
showNotAssignedOption: false,
|
||||||
addLabelPageBuilder: (initialName) =>
|
addLabelPageBuilder: (initialName) => RepositoryProvider.value(
|
||||||
RepositoryProvider.value(
|
|
||||||
value: context.read<LabelRepository>(),
|
value: context.read<LabelRepository>(),
|
||||||
child: AddCorrespondentPage(initialName: initialName),
|
child: AddCorrespondentPage(initialName: initialName),
|
||||||
),
|
),
|
||||||
@@ -211,8 +196,7 @@ class _DocumentUploadPreparationPageState
|
|||||||
LabelFormField<DocumentType>(
|
LabelFormField<DocumentType>(
|
||||||
showAnyAssignedOption: false,
|
showAnyAssignedOption: false,
|
||||||
showNotAssignedOption: false,
|
showNotAssignedOption: false,
|
||||||
addLabelPageBuilder: (initialName) =>
|
addLabelPageBuilder: (initialName) => RepositoryProvider.value(
|
||||||
RepositoryProvider.value(
|
|
||||||
value: context.read<LabelRepository>(),
|
value: context.read<LabelRepository>(),
|
||||||
child: AddDocumentTypePage(initialName: initialName),
|
child: AddDocumentTypePage(initialName: initialName),
|
||||||
),
|
),
|
||||||
@@ -252,10 +236,9 @@ class _DocumentUploadPreparationPageState
|
|||||||
|
|
||||||
final createdAt = fv[DocumentModel.createdKey] as DateTime?;
|
final createdAt = fv[DocumentModel.createdKey] as DateTime?;
|
||||||
final title = fv[DocumentModel.titleKey] as String;
|
final title = fv[DocumentModel.titleKey] as String;
|
||||||
final docType = fv[DocumentModel.documentTypeKey] as IdQueryParameter;
|
final docType = fv[DocumentModel.documentTypeKey] as SetIdQueryParameter;
|
||||||
final tags = fv[DocumentModel.tagsKey] as IdsTagsQuery;
|
final tags = fv[DocumentModel.tagsKey] as IdsTagsQuery;
|
||||||
final correspondent =
|
final correspondent = fv[DocumentModel.correspondentKey] as SetIdQueryParameter;
|
||||||
fv[DocumentModel.correspondentKey] as IdQueryParameter;
|
|
||||||
|
|
||||||
final taskId = await cubit.upload(
|
final taskId = await cubit.upload(
|
||||||
widget.fileBytes,
|
widget.fileBytes,
|
||||||
@@ -266,7 +249,7 @@ class _DocumentUploadPreparationPageState
|
|||||||
title: title,
|
title: title,
|
||||||
documentType: docType.id,
|
documentType: docType.id,
|
||||||
correspondent: correspondent.id,
|
correspondent: correspondent.id,
|
||||||
tags: tags.ids,
|
tags: tags.include,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
);
|
);
|
||||||
showSnackBar(
|
showSnackBar(
|
||||||
@@ -283,8 +266,7 @@ class _DocumentUploadPreparationPageState
|
|||||||
setState(() => _errors = errors);
|
setState(() => _errors = errors);
|
||||||
} catch (unknownError, stackTrace) {
|
} catch (unknownError, stackTrace) {
|
||||||
debugPrint(unknownError.toString());
|
debugPrint(unknownError.toString());
|
||||||
showErrorMessage(
|
showErrorMessage(context, const PaperlessServerException.unknown(), stackTrace);
|
||||||
context, const PaperlessServerException.unknown(), stackTrace);
|
|
||||||
} finally {
|
} finally {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isUploadLoading = false;
|
_isUploadLoading = false;
|
||||||
|
|||||||
@@ -4,9 +4,10 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
|
import 'package:paperless_mobile/core/database/tables/user_app_state.dart';
|
||||||
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/paged_document_view/cubit/document_paging_bloc_mixin.dart';
|
import 'package:paperless_mobile/features/paged_document_view/cubit/document_paging_bloc_mixin.dart';
|
||||||
import 'package:paperless_mobile/features/paged_document_view/cubit/paged_documents_state.dart';
|
import 'package:paperless_mobile/features/paged_document_view/cubit/paged_documents_state.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/view_type.dart';
|
import 'package:paperless_mobile/features/settings/model/view_type.dart';
|
||||||
@@ -14,8 +15,7 @@ import 'package:paperless_mobile/features/settings/model/view_type.dart';
|
|||||||
part 'documents_cubit.g.dart';
|
part 'documents_cubit.g.dart';
|
||||||
part 'documents_state.dart';
|
part 'documents_state.dart';
|
||||||
|
|
||||||
class DocumentsCubit extends HydratedCubit<DocumentsState>
|
class DocumentsCubit extends HydratedCubit<DocumentsState> with DocumentPagingBlocMixin {
|
||||||
with DocumentPagingBlocMixin {
|
|
||||||
@override
|
@override
|
||||||
final PaperlessDocumentsApi api;
|
final PaperlessDocumentsApi api;
|
||||||
|
|
||||||
@@ -24,24 +24,21 @@ class DocumentsCubit extends HydratedCubit<DocumentsState>
|
|||||||
@override
|
@override
|
||||||
final DocumentChangedNotifier notifier;
|
final DocumentChangedNotifier notifier;
|
||||||
|
|
||||||
@override
|
final UserAppState _userState;
|
||||||
final UserAccount account;
|
|
||||||
|
|
||||||
DocumentsCubit(
|
DocumentsCubit(
|
||||||
this.api,
|
this.api,
|
||||||
this.notifier,
|
this.notifier,
|
||||||
this._labelRepository,
|
this._labelRepository,
|
||||||
this.account,
|
this._userState,
|
||||||
) : super(DocumentsState(filter: account.settings.currentDocumentFilter)) {
|
) : super(DocumentsState(filter: _userState.currentDocumentFilter)) {
|
||||||
notifier.addListener(
|
notifier.addListener(
|
||||||
this,
|
this,
|
||||||
onUpdated: (document) {
|
onUpdated: (document) {
|
||||||
replace(document);
|
replace(document);
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
selection: state.selection
|
selection: state.selection.map((e) => e.id == document.id ? document : e).toList(),
|
||||||
.map((e) => e.id == document.id ? document : e)
|
|
||||||
.toList(),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -49,8 +46,7 @@ class DocumentsCubit extends HydratedCubit<DocumentsState>
|
|||||||
remove(document);
|
remove(document);
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
selection:
|
selection: state.selection.where((e) => e.id != document.id).toList(),
|
||||||
state.selection.where((e) => e.id != document.id).toList(),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@@ -84,9 +80,7 @@ class DocumentsCubit extends HydratedCubit<DocumentsState>
|
|||||||
if (state.selectedIds.contains(model.id)) {
|
if (state.selectedIds.contains(model.id)) {
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
selection: state.selection
|
selection: state.selection.where((element) => element.id != model.id).toList(),
|
||||||
.where((element) => element.id != model.id)
|
|
||||||
.toList(),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -129,4 +123,10 @@ class DocumentsCubit extends HydratedCubit<DocumentsState>
|
|||||||
void setViewType(ViewType viewType) {
|
void setViewType(ViewType viewType) {
|
||||||
emit(state.copyWith(viewType: viewType));
|
emit(state.copyWith(viewType: viewType));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onFilterUpdated(DocumentFilter filter) async {
|
||||||
|
_userState.currentDocumentFilter = filter;
|
||||||
|
await _userState.save();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:badges/badges.dart' as b;
|
import 'package:badges/badges.dart' as b;
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
@@ -41,12 +42,9 @@ class DocumentsPage extends StatefulWidget {
|
|||||||
State<DocumentsPage> createState() => _DocumentsPageState();
|
State<DocumentsPage> createState() => _DocumentsPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _DocumentsPageState extends State<DocumentsPage>
|
class _DocumentsPageState extends State<DocumentsPage> with SingleTickerProviderStateMixin {
|
||||||
with SingleTickerProviderStateMixin {
|
final SliverOverlapAbsorberHandle searchBarHandle = SliverOverlapAbsorberHandle();
|
||||||
final SliverOverlapAbsorberHandle searchBarHandle =
|
final SliverOverlapAbsorberHandle tabBarHandle = SliverOverlapAbsorberHandle();
|
||||||
SliverOverlapAbsorberHandle();
|
|
||||||
final SliverOverlapAbsorberHandle tabBarHandle =
|
|
||||||
SliverOverlapAbsorberHandle();
|
|
||||||
late final TabController _tabController;
|
late final TabController _tabController;
|
||||||
|
|
||||||
int _currentTab = 0;
|
int _currentTab = 0;
|
||||||
@@ -83,8 +81,7 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return BlocListener<TaskStatusCubit, TaskStatusState>(
|
return BlocListener<TaskStatusCubit, TaskStatusState>(
|
||||||
listenWhen: (previous, current) =>
|
listenWhen: (previous, current) => !previous.isSuccess && current.isSuccess,
|
||||||
!previous.isSuccess && current.isSuccess,
|
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
showSnackBar(
|
showSnackBar(
|
||||||
context,
|
context,
|
||||||
@@ -101,8 +98,7 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
},
|
},
|
||||||
child: BlocConsumer<ConnectivityCubit, ConnectivityState>(
|
child: BlocConsumer<ConnectivityCubit, ConnectivityState>(
|
||||||
listenWhen: (previous, current) =>
|
listenWhen: (previous, current) =>
|
||||||
previous != ConnectivityState.connected &&
|
previous != ConnectivityState.connected && current == ConnectivityState.connected,
|
||||||
current == ConnectivityState.connected,
|
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
try {
|
try {
|
||||||
context.read<DocumentsCubit>().reload();
|
context.read<DocumentsCubit>().reload();
|
||||||
@@ -150,11 +146,7 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
resizeToAvoidBottomInset: true,
|
resizeToAvoidBottomInset: true,
|
||||||
body: WillPopScope(
|
body: WillPopScope(
|
||||||
onWillPop: () async {
|
onWillPop: () async {
|
||||||
if (context
|
if (context.read<DocumentsCubit>().state.selection.isNotEmpty) {
|
||||||
.read<DocumentsCubit>()
|
|
||||||
.state
|
|
||||||
.selection
|
|
||||||
.isNotEmpty) {
|
|
||||||
context.read<DocumentsCubit>().resetSelection();
|
context.read<DocumentsCubit>().resetSelection();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -189,8 +181,7 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
}
|
}
|
||||||
return SliverPersistentHeader(
|
return SliverPersistentHeader(
|
||||||
pinned: true,
|
pinned: true,
|
||||||
delegate:
|
delegate: CustomizableSliverPersistentHeaderDelegate(
|
||||||
CustomizableSliverPersistentHeaderDelegate(
|
|
||||||
minExtent: kTextTabBarHeight,
|
minExtent: kTextTabBarHeight,
|
||||||
maxExtent: kTextTabBarHeight,
|
maxExtent: kTextTabBarHeight,
|
||||||
child: ColoredTabBar(
|
child: ColoredTabBar(
|
||||||
@@ -214,22 +205,15 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
if (metrics.maxScrollExtent == 0) {
|
if (metrics.maxScrollExtent == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final desiredTab =
|
final desiredTab = (metrics.pixels / metrics.maxScrollExtent).round();
|
||||||
(metrics.pixels / metrics.maxScrollExtent)
|
if (metrics.axis == Axis.horizontal && _currentTab != desiredTab) {
|
||||||
.round();
|
|
||||||
if (metrics.axis == Axis.horizontal &&
|
|
||||||
_currentTab != desiredTab) {
|
|
||||||
setState(() => _currentTab = desiredTab);
|
setState(() => _currentTab = desiredTab);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
child: TabBarView(
|
child: TabBarView(
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
physics: context
|
physics: context.watch<DocumentsCubit>().state.selection.isNotEmpty
|
||||||
.watch<DocumentsCubit>()
|
|
||||||
.state
|
|
||||||
.selection
|
|
||||||
.isNotEmpty
|
|
||||||
? const NeverScrollableScrollPhysics()
|
? const NeverScrollableScrollPhysics()
|
||||||
: null,
|
: null,
|
||||||
children: [
|
children: [
|
||||||
@@ -297,19 +281,13 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
|
|
||||||
final currState = context.read<DocumentsCubit>().state;
|
final currState = context.read<DocumentsCubit>().state;
|
||||||
final max = notification.metrics.maxScrollExtent;
|
final max = notification.metrics.maxScrollExtent;
|
||||||
if (max == 0 ||
|
if (max == 0 || _currentTab != 0 || currState.isLoading || currState.isLastPageLoaded) {
|
||||||
_currentTab != 0 ||
|
|
||||||
currState.isLoading ||
|
|
||||||
currState.isLastPageLoaded) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final offset = notification.metrics.pixels;
|
final offset = notification.metrics.pixels;
|
||||||
if (offset >= max * 0.7) {
|
if (offset >= max * 0.7) {
|
||||||
context
|
context.read<DocumentsCubit>().loadMore().onError<PaperlessServerException>(
|
||||||
.read<DocumentsCubit>()
|
|
||||||
.loadMore()
|
|
||||||
.onError<PaperlessServerException>(
|
|
||||||
(error, stackTrace) => showErrorMessage(
|
(error, stackTrace) => showErrorMessage(
|
||||||
context,
|
context,
|
||||||
error,
|
error,
|
||||||
@@ -344,8 +322,7 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
return SliverAdaptiveDocumentsView(
|
return SliverAdaptiveDocumentsView(
|
||||||
viewType: state.viewType,
|
viewType: state.viewType,
|
||||||
onTap: _openDetails,
|
onTap: _openDetails,
|
||||||
onSelected:
|
onSelected: context.read<DocumentsCubit>().toggleDocumentSelection,
|
||||||
context.read<DocumentsCubit>().toggleDocumentSelection,
|
|
||||||
hasInternetConnection: connectivityState.isConnected,
|
hasInternetConnection: connectivityState.isConnected,
|
||||||
onTagSelected: _addTagToFilter,
|
onTagSelected: _addTagToFilter,
|
||||||
onCorrespondentSelected: _addCorrespondentToFilter,
|
onCorrespondentSelected: _addCorrespondentToFilter,
|
||||||
@@ -436,8 +413,7 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
snapSizes: const [0.9, 1],
|
snapSizes: const [0.9, 1],
|
||||||
initialChildSize: .9,
|
initialChildSize: .9,
|
||||||
maxChildSize: 1,
|
maxChildSize: 1,
|
||||||
builder: (context, controller) =>
|
builder: (context, controller) => BlocBuilder<DocumentsCubit, DocumentsState>(
|
||||||
BlocBuilder<DocumentsCubit, DocumentsState>(
|
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
return DocumentFilterPanel(
|
return DocumentFilterPanel(
|
||||||
initialFilter: context.read<DocumentsCubit>().state.filter,
|
initialFilter: context.read<DocumentsCubit>().state.filter,
|
||||||
@@ -458,9 +434,7 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
if (filterIntent.shouldReset) {
|
if (filterIntent.shouldReset) {
|
||||||
await context.read<DocumentsCubit>().resetFilter();
|
await context.read<DocumentsCubit>().resetFilter();
|
||||||
} else {
|
} else {
|
||||||
await context
|
await context.read<DocumentsCubit>().updateFilter(filter: filterIntent.filter!);
|
||||||
.read<DocumentsCubit>()
|
|
||||||
.updateFilter(filter: filterIntent.filter!);
|
|
||||||
}
|
}
|
||||||
} on PaperlessServerException catch (error, stackTrace) {
|
} on PaperlessServerException catch (error, stackTrace) {
|
||||||
showErrorMessage(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
@@ -480,20 +454,21 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
|
|
||||||
void _addTagToFilter(int tagId) {
|
void _addTagToFilter(int tagId) {
|
||||||
try {
|
try {
|
||||||
final tagsQuery =
|
final tagsQuery = context.read<DocumentsCubit>().state.filter.tags is IdsTagsQuery
|
||||||
context.read<DocumentsCubit>().state.filter.tags is IdsTagsQuery
|
|
||||||
? context.read<DocumentsCubit>().state.filter.tags as IdsTagsQuery
|
? context.read<DocumentsCubit>().state.filter.tags as IdsTagsQuery
|
||||||
: const IdsTagsQuery();
|
: const IdsTagsQuery();
|
||||||
if (tagsQuery.includedIds.contains(tagId)) {
|
if (tagsQuery.include.contains(tagId)) {
|
||||||
context.read<DocumentsCubit>().updateCurrentFilter(
|
context.read<DocumentsCubit>().updateCurrentFilter(
|
||||||
(filter) => filter.copyWith(
|
(filter) => filter.copyWith(
|
||||||
tags: tagsQuery.withIdsRemoved([tagId]),
|
tags: tagsQuery.copyWith(
|
||||||
|
include: tagsQuery.include.whereNot((id) => id == tagId),
|
||||||
|
exclude: tagsQuery.exclude.whereNot((id) => id == tagId)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
context.read<DocumentsCubit>().updateCurrentFilter(
|
context.read<DocumentsCubit>().updateCurrentFilter(
|
||||||
(filter) => filter.copyWith(
|
(filter) => filter.copyWith(
|
||||||
tags: tagsQuery.withIdQueriesAdded([IncludeTagIdQuery(tagId)]),
|
tags: tagsQuery.copyWith(include: [...tagsQuery.include, tagId]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -505,17 +480,18 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
void _addCorrespondentToFilter(int? correspondentId) {
|
void _addCorrespondentToFilter(int? correspondentId) {
|
||||||
final cubit = context.read<DocumentsCubit>();
|
final cubit = context.read<DocumentsCubit>();
|
||||||
try {
|
try {
|
||||||
if (cubit.state.filter.correspondent.id == correspondentId) {
|
final correspondent = cubit.state.filter.correspondent;
|
||||||
|
if (correspondent is SetIdQueryParameter) {
|
||||||
|
if (correspondent.id == correspondentId) {
|
||||||
cubit.updateCurrentFilter(
|
cubit.updateCurrentFilter(
|
||||||
(filter) =>
|
(filter) => filter.copyWith(correspondent: const IdQueryParameter.unset()),
|
||||||
filter.copyWith(correspondent: const IdQueryParameter.unset()),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
cubit.updateCurrentFilter(
|
cubit.updateCurrentFilter(
|
||||||
(filter) => filter.copyWith(
|
(filter) => filter.copyWith(correspondent: IdQueryParameter.fromId(correspondentId)),
|
||||||
correspondent: IdQueryParameter.fromId(correspondentId)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} on PaperlessServerException catch (error, stackTrace) {
|
} on PaperlessServerException catch (error, stackTrace) {
|
||||||
showErrorMessage(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
@@ -524,17 +500,18 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
void _addDocumentTypeToFilter(int? documentTypeId) {
|
void _addDocumentTypeToFilter(int? documentTypeId) {
|
||||||
final cubit = context.read<DocumentsCubit>();
|
final cubit = context.read<DocumentsCubit>();
|
||||||
try {
|
try {
|
||||||
if (cubit.state.filter.documentType.id == documentTypeId) {
|
final documentType = cubit.state.filter.documentType;
|
||||||
|
if (documentType is SetIdQueryParameter) {
|
||||||
|
if (documentType.id == documentTypeId) {
|
||||||
cubit.updateCurrentFilter(
|
cubit.updateCurrentFilter(
|
||||||
(filter) =>
|
(filter) => filter.copyWith(documentType: const IdQueryParameter.unset()),
|
||||||
filter.copyWith(documentType: const IdQueryParameter.unset()),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
cubit.updateCurrentFilter(
|
cubit.updateCurrentFilter(
|
||||||
(filter) => filter.copyWith(
|
(filter) => filter.copyWith(documentType: IdQueryParameter.fromId(documentTypeId)),
|
||||||
documentType: IdQueryParameter.fromId(documentTypeId)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} on PaperlessServerException catch (error, stackTrace) {
|
} on PaperlessServerException catch (error, stackTrace) {
|
||||||
showErrorMessage(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
@@ -543,17 +520,18 @@ class _DocumentsPageState extends State<DocumentsPage>
|
|||||||
void _addStoragePathToFilter(int? pathId) {
|
void _addStoragePathToFilter(int? pathId) {
|
||||||
final cubit = context.read<DocumentsCubit>();
|
final cubit = context.read<DocumentsCubit>();
|
||||||
try {
|
try {
|
||||||
if (cubit.state.filter.correspondent.id == pathId) {
|
final path = cubit.state.filter.documentType;
|
||||||
|
if (path is SetIdQueryParameter) {
|
||||||
|
if (path.id == pathId) {
|
||||||
cubit.updateCurrentFilter(
|
cubit.updateCurrentFilter(
|
||||||
(filter) =>
|
(filter) => filter.copyWith(storagePath: const IdQueryParameter.unset()),
|
||||||
filter.copyWith(storagePath: const IdQueryParameter.unset()),
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
cubit.updateCurrentFilter(
|
cubit.updateCurrentFilter(
|
||||||
(filter) =>
|
(filter) => filter.copyWith(storagePath: IdQueryParameter.fromId(pathId)),
|
||||||
filter.copyWith(storagePath: IdQueryParameter.fromId(pathId)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} on PaperlessServerException catch (error, stackTrace) {
|
} on PaperlessServerException catch (error, stackTrace) {
|
||||||
showErrorMessage(context, error, stackTrace);
|
showErrorMessage(context, error, stackTrace);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'package:paperless_api/paperless_api.dart';
|
|||||||
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
||||||
import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart';
|
import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
|
import 'package:paperless_mobile/core/database/tables/user_app_state.dart';
|
||||||
import 'package:paperless_mobile/core/global/constants.dart';
|
import 'package:paperless_mobile/core/global/constants.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.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/saved_view_repository.dart';
|
||||||
@@ -28,7 +29,7 @@ import 'package:paperless_mobile/features/inbox/view/pages/inbox_page.dart';
|
|||||||
import 'package:paperless_mobile/features/labels/cubit/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/labels/view/pages/labels_page.dart';
|
||||||
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/notifications/services/local_notification_service.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/saved_view/cubit/saved_view_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/sharing/share_intent_queue.dart';
|
import 'package:paperless_mobile/features/sharing/share_intent_queue.dart';
|
||||||
@@ -245,7 +246,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
|||||||
context.read(),
|
context.read(),
|
||||||
context.read(),
|
context.read(),
|
||||||
context.read(),
|
context.read(),
|
||||||
Hive.box<UserAccount>(HiveBoxes.userAccount).get(userId)!,
|
Hive.box<UserAppState>(HiveBoxes.userAppState).get(userId)!,
|
||||||
)..reload(),
|
)..reload(),
|
||||||
),
|
),
|
||||||
BlocProvider(
|
BlocProvider(
|
||||||
@@ -280,8 +281,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
|||||||
listeners: [
|
listeners: [
|
||||||
BlocListener<ConnectivityCubit, ConnectivityState>(
|
BlocListener<ConnectivityCubit, ConnectivityState>(
|
||||||
//Only re-initialize data if the connectivity changed from not connected to connected
|
//Only re-initialize data if the connectivity changed from not connected to connected
|
||||||
listenWhen: (previous, current) =>
|
listenWhen: (previous, current) => current == ConnectivityState.connected,
|
||||||
current == ConnectivityState.connected,
|
|
||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
_initializeData(context);
|
_initializeData(context);
|
||||||
},
|
},
|
||||||
@@ -290,9 +290,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
|||||||
listener: (context, state) {
|
listener: (context, state) {
|
||||||
if (state.task != null) {
|
if (state.task != null) {
|
||||||
// Handle local notifications on task change (only when app is running for now).
|
// Handle local notifications on task change (only when app is running for now).
|
||||||
context
|
context.read<LocalNotificationService>().notifyTaskChanged(state.task!);
|
||||||
.read<LocalNotificationService>()
|
|
||||||
.notifyTaskChanged(state.task!);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -305,9 +303,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
|||||||
children: [
|
children: [
|
||||||
NavigationRail(
|
NavigationRail(
|
||||||
labelType: NavigationRailLabelType.all,
|
labelType: NavigationRailLabelType.all,
|
||||||
destinations: destinations
|
destinations: destinations.map((e) => e.toNavigationRailDestination()).toList(),
|
||||||
.map((e) => e.toNavigationRailDestination())
|
|
||||||
.toList(),
|
|
||||||
selectedIndex: _currentIndex,
|
selectedIndex: _currentIndex,
|
||||||
onDestinationSelected: _onNavigationChanged,
|
onDestinationSelected: _onNavigationChanged,
|
||||||
),
|
),
|
||||||
@@ -325,8 +321,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
|
|||||||
elevation: 4.0,
|
elevation: 4.0,
|
||||||
selectedIndex: _currentIndex,
|
selectedIndex: _currentIndex,
|
||||||
onDestinationSelected: _onNavigationChanged,
|
onDestinationSelected: _onNavigationChanged,
|
||||||
destinations:
|
destinations: destinations.map((e) => e.toNavigationDestination()).toList(),
|
||||||
destinations.map((e) => e.toNavigationDestination()).toList(),
|
|
||||||
),
|
),
|
||||||
body: routes[_currentIndex],
|
body: routes[_currentIndex],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ 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/saved_view_repository.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
|
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/user_settings_builder.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/user_settings_builder.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
@@ -32,9 +32,7 @@ class VerifyIdentityPage extends StatelessWidget {
|
|||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(S
|
Text(S.of(context)!.useTheConfiguredBiometricFactorToAuthenticate)
|
||||||
.of(context)!
|
|
||||||
.useTheConfiguredBiometricFactorToAuthenticate)
|
|
||||||
.paddedSymmetrically(horizontal: 16),
|
.paddedSymmetrically(horizontal: 16),
|
||||||
const Icon(
|
const Icon(
|
||||||
Icons.fingerprint,
|
Icons.fingerprint,
|
||||||
@@ -56,9 +54,7 @@ class VerifyIdentityPage extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () => context
|
onPressed: () => context.read<AuthenticationCubit>().restoreSessionState(),
|
||||||
.read<AuthenticationCubit>()
|
|
||||||
.restoreSessionState(),
|
|
||||||
child: Text(S.of(context)!.verifyIdentity),
|
child: Text(S.of(context)!.verifyIdentity),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ import 'package:paperless_mobile/features/paged_document_view/cubit/document_pag
|
|||||||
part 'inbox_cubit.g.dart';
|
part 'inbox_cubit.g.dart';
|
||||||
part 'inbox_state.dart';
|
part 'inbox_state.dart';
|
||||||
|
|
||||||
class InboxCubit extends HydratedCubit<InboxState>
|
class InboxCubit extends HydratedCubit<InboxState> with DocumentPagingBlocMixin {
|
||||||
with DocumentPagingBlocMixin {
|
|
||||||
final LabelRepository _labelRepository;
|
final LabelRepository _labelRepository;
|
||||||
|
|
||||||
final PaperlessDocumentsApi _documentsApi;
|
final PaperlessDocumentsApi _documentsApi;
|
||||||
@@ -39,10 +38,7 @@ class InboxCubit extends HydratedCubit<InboxState>
|
|||||||
this,
|
this,
|
||||||
onDeleted: remove,
|
onDeleted: remove,
|
||||||
onUpdated: (document) {
|
onUpdated: (document) {
|
||||||
if (document.tags
|
if (document.tags.toSet().intersection(state.inboxTags.toSet()).isEmpty) {
|
||||||
.toSet()
|
|
||||||
.intersection(state.inboxTags.toSet())
|
|
||||||
.isEmpty) {
|
|
||||||
remove(document);
|
remove(document);
|
||||||
emit(state.copyWith(itemsInInboxCount: state.itemsInInboxCount - 1));
|
emit(state.copyWith(itemsInInboxCount: state.itemsInInboxCount - 1));
|
||||||
} else {
|
} else {
|
||||||
@@ -101,7 +97,7 @@ class InboxCubit extends HydratedCubit<InboxState>
|
|||||||
updateFilter(
|
updateFilter(
|
||||||
filter: DocumentFilter(
|
filter: DocumentFilter(
|
||||||
sortField: SortField.added,
|
sortField: SortField.added,
|
||||||
tags: IdsTagsQuery.fromIds(inboxTags),
|
tags: TagsQuery.ids(include: inboxTags),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -131,7 +127,7 @@ class InboxCubit extends HydratedCubit<InboxState>
|
|||||||
updateFilter(
|
updateFilter(
|
||||||
filter: DocumentFilter(
|
filter: DocumentFilter(
|
||||||
sortField: SortField.added,
|
sortField: SortField.added,
|
||||||
tags: IdsTagsQuery.fromIds(inboxTags),
|
tags: TagsQuery.ids(include: inboxTags),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -141,8 +137,7 @@ class InboxCubit extends HydratedCubit<InboxState>
|
|||||||
/// from the inbox.
|
/// from the inbox.
|
||||||
///
|
///
|
||||||
Future<Iterable<int>> removeFromInbox(DocumentModel document) async {
|
Future<Iterable<int>> removeFromInbox(DocumentModel document) async {
|
||||||
final tagsToRemove =
|
final tagsToRemove = document.tags.toSet().intersection(state.inboxTags.toSet());
|
||||||
document.tags.toSet().intersection(state.inboxTags.toSet());
|
|
||||||
|
|
||||||
final updatedTags = {...document.tags}..removeAll(tagsToRemove);
|
final updatedTags = {...document.tags}..removeAll(tagsToRemove);
|
||||||
final updatedDocument = await api.update(
|
final updatedDocument = await api.update(
|
||||||
@@ -196,8 +191,8 @@ class InboxCubit extends HydratedCubit<InboxState>
|
|||||||
Future<void> assignAsn(DocumentModel document) async {
|
Future<void> assignAsn(DocumentModel document) async {
|
||||||
if (document.archiveSerialNumber == null) {
|
if (document.archiveSerialNumber == null) {
|
||||||
final int asn = await _documentsApi.findNextAsn();
|
final int asn = await _documentsApi.findNextAsn();
|
||||||
final updatedDocument = await _documentsApi
|
final updatedDocument =
|
||||||
.update(document.copyWith(archiveSerialNumber: () => asn));
|
await _documentsApi.update(document.copyWith(archiveSerialNumber: () => asn));
|
||||||
|
|
||||||
replace(updatedDocument);
|
replace(updatedDocument);
|
||||||
}
|
}
|
||||||
@@ -222,4 +217,7 @@ class InboxCubit extends HydratedCubit<InboxState>
|
|||||||
_labelRepository.removeListener(this);
|
_labelRepository.removeListener(this);
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onFilterUpdated(DocumentFilter filter) async {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,12 +44,12 @@ class _FullscreenTagsFormState extends State<FullscreenTagsForm> {
|
|||||||
_options = widget.options.values.toList();
|
_options = widget.options.values.toList();
|
||||||
final value = widget.initialValue;
|
final value = widget.initialValue;
|
||||||
if (value is IdsTagsQuery) {
|
if (value is IdsTagsQuery) {
|
||||||
_include = value.includedIds.toList();
|
_include = value.include.toList();
|
||||||
_exclude = value.excludedIds.toList();
|
_exclude = value.include.toList();
|
||||||
} else if (value is AnyAssignedTagsQuery) {
|
} else if (value is AnyAssignedTagsQuery) {
|
||||||
_include = value.tagIds.toList();
|
_include = value.tagIds.toList();
|
||||||
_anyAssigned = true;
|
_anyAssigned = true;
|
||||||
} else if (value is OnlyNotAssignedTagsQuery) {
|
} else if (value is NotAssignedTagsQuery) {
|
||||||
_notAssigned = true;
|
_notAssigned = true;
|
||||||
}
|
}
|
||||||
_textEditingController.addListener(() => setState(() {
|
_textEditingController.addListener(() => setState(() {
|
||||||
@@ -113,28 +113,24 @@ class _FullscreenTagsFormState extends State<FullscreenTagsForm> {
|
|||||||
icon: const Icon(Icons.done),
|
icon: const Icon(Icons.done),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
if (widget.allowOnlySelection) {
|
if (widget.allowOnlySelection) {
|
||||||
widget.onSubmit(returnValue: IdsTagsQuery.included(_include));
|
widget.onSubmit(returnValue: TagsQuery.ids(include: _include));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
late final TagsQuery query;
|
late final TagsQuery query;
|
||||||
if (_notAssigned) {
|
if (_notAssigned) {
|
||||||
query = const OnlyNotAssignedTagsQuery();
|
query = const TagsQuery.notAssigned();
|
||||||
} else if (_anyAssigned) {
|
} else if (_anyAssigned) {
|
||||||
query = AnyAssignedTagsQuery(tagIds: _include);
|
query = TagsQuery.anyAssigned(tagIds: _include);
|
||||||
} else {
|
} else {
|
||||||
query = IdsTagsQuery([
|
query = TagsQuery.ids(include: _include, exclude: _exclude);
|
||||||
for (var id in _include) IncludeTagIdQuery(id),
|
|
||||||
for (var id in _exclude) ExcludeTagIdQuery(id),
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
widget.onSubmit(returnValue: query);
|
widget.onSubmit(returnValue: query);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
bottom: PreferredSize(
|
bottom: PreferredSize(
|
||||||
preferredSize: !widget.allowOnlySelection
|
preferredSize:
|
||||||
? const Size.fromHeight(32)
|
!widget.allowOnlySelection ? const Size.fromHeight(32) : const Size.fromHeight(1),
|
||||||
: const Size.fromHeight(1),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
Divider(color: theme.colorScheme.outline),
|
Divider(color: theme.colorScheme.outline),
|
||||||
@@ -237,8 +233,7 @@ class _FullscreenTagsFormState extends State<FullscreenTagsForm> {
|
|||||||
yield _buildNotAssignedOption();
|
yield _buildNotAssignedOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
var matches = _options
|
var matches = _options.where((e) => e.name.trim().toLowerCase().contains(normalizedQuery));
|
||||||
.where((e) => e.name.trim().toLowerCase().contains(normalizedQuery));
|
|
||||||
if (matches.isEmpty && widget.allowCreation) {
|
if (matches.isEmpty && widget.allowCreation) {
|
||||||
yield Text(S.of(context)!.noItemsFound);
|
yield Text(S.of(context)!.noItemsFound);
|
||||||
yield TextButton(
|
yield TextButton(
|
||||||
@@ -304,9 +299,7 @@ class SelectableTagWidget extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ListTile(
|
return ListTile(
|
||||||
title: Text(tag.name),
|
title: Text(tag.name),
|
||||||
trailing: excluded
|
trailing: excluded ? const Icon(Icons.close) : (selected ? const Icon(Icons.done) : null),
|
||||||
? const Icon(Icons.close)
|
|
||||||
: (selected ? const Icon(Icons.done) : null),
|
|
||||||
leading: CircleAvatar(
|
leading: CircleAvatar(
|
||||||
backgroundColor: tag.color,
|
backgroundColor: tag.color,
|
||||||
child: (tag.isInboxTag)
|
child: (tag.isInboxTag)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:developer';
|
import 'dart:developer';
|
||||||
|
|
||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
@@ -32,8 +33,8 @@ class TagsFormField extends StatelessWidget {
|
|||||||
initialValue: initialValue,
|
initialValue: initialValue,
|
||||||
builder: (field) {
|
builder: (field) {
|
||||||
final values = _generateOptions(context, field.value, field).toList();
|
final values = _generateOptions(context, field.value, field).toList();
|
||||||
final isEmpty = (field.value is IdsTagsQuery &&
|
final isEmpty =
|
||||||
(field.value as IdsTagsQuery).ids.isEmpty) ||
|
(field.value is IdsTagsQuery && (field.value as IdsTagsQuery).include.isEmpty) ||
|
||||||
field.value == null;
|
field.value == null;
|
||||||
bool anyAssigned = field.value is AnyAssignedTagsQuery;
|
bool anyAssigned = field.value is AnyAssignedTagsQuery;
|
||||||
return OpenContainer<TagsQuery>(
|
return OpenContainer<TagsQuery>(
|
||||||
@@ -59,8 +60,7 @@ class TagsFormField extends StatelessWidget {
|
|||||||
height: 32,
|
height: 32,
|
||||||
child: ListView.separated(
|
child: ListView.separated(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
separatorBuilder: (context, index) =>
|
separatorBuilder: (context, index) => const SizedBox(width: 4),
|
||||||
const SizedBox(width: 4),
|
|
||||||
itemBuilder: (context, index) => values[index],
|
itemBuilder: (context, index) => values[index],
|
||||||
itemCount: values.length,
|
itemCount: values.length,
|
||||||
),
|
),
|
||||||
@@ -93,33 +93,56 @@ class TagsFormField extends StatelessWidget {
|
|||||||
) sync* {
|
) sync* {
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
yield Container();
|
yield Container();
|
||||||
} else if (query is IdsTagsQuery) {
|
} else {
|
||||||
for (final e in query.queries) {
|
final widgets = query.map(
|
||||||
yield _buildTagIdQueryWidget(context, e, field);
|
ids: (value) => [
|
||||||
}
|
for (var inc in value.include) _buildTagIdQueryWidget(context, inc, field, false),
|
||||||
} else if (query is OnlyNotAssignedTagsQuery) {
|
for (var exc in value.exclude) _buildTagIdQueryWidget(context, exc, field, true),
|
||||||
yield _buildNotAssignedTagWidget(context, field);
|
],
|
||||||
} else if (query is AnyAssignedTagsQuery) {
|
anyAssigned: (value) => [
|
||||||
for (final e in query.tagIds) {
|
for (var id in value.tagIds) _buildAnyAssignedTagWidget(context, id, field, value),
|
||||||
yield _buildAnyAssignedTagWidget(context, e, field, query);
|
],
|
||||||
|
notAssigned: (value) => [_buildNotAssignedTagWidget(context, field)],
|
||||||
|
);
|
||||||
|
for (var child in widgets) {
|
||||||
|
yield child;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildTagIdQueryWidget(
|
Widget _buildTagIdQueryWidget(
|
||||||
BuildContext context,
|
BuildContext context,
|
||||||
TagIdQuery e,
|
int id,
|
||||||
FormFieldState<TagsQuery?> field,
|
FormFieldState<TagsQuery?> field,
|
||||||
|
bool exclude,
|
||||||
) {
|
) {
|
||||||
assert(field.value is IdsTagsQuery);
|
assert(field.value is IdsTagsQuery);
|
||||||
final formValue = field.value as IdsTagsQuery;
|
final formValue = field.value as IdsTagsQuery;
|
||||||
final tag = options[e.id]!;
|
final tag = options[id]!;
|
||||||
return QueryTagChip(
|
return QueryTagChip(
|
||||||
onDeleted: () => field.didChange(formValue.withIdsRemoved([e.id])),
|
onDeleted: () => field.didChange(formValue.copyWith(
|
||||||
|
include: formValue.include.whereNot((element) => element == id),
|
||||||
|
exclude: formValue.exclude.whereNot((element) => element == id),
|
||||||
|
)),
|
||||||
onSelected: allowExclude
|
onSelected: allowExclude
|
||||||
? () => field.didChange(formValue.withIdQueryToggled(e.id))
|
? () {
|
||||||
|
if (formValue.include.contains(id)) {
|
||||||
|
field.didChange(
|
||||||
|
formValue.copyWith(
|
||||||
|
include: formValue.include.whereNot((element) => element == id),
|
||||||
|
exclude: [...formValue.exclude, id],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else if (formValue.exclude.contains(id)) {}
|
||||||
|
field.didChange(
|
||||||
|
formValue.copyWith(
|
||||||
|
include: [...formValue.include, id],
|
||||||
|
exclude: formValue.exclude.whereNot((element) => element == id),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
: null,
|
: null,
|
||||||
exclude: e is ExcludeTagIdQuery,
|
exclude: exclude,
|
||||||
backgroundColor: tag.color,
|
backgroundColor: tag.color,
|
||||||
foregroundColor: tag.textColor,
|
foregroundColor: tag.textColor,
|
||||||
labelText: tag.name,
|
labelText: tag.name,
|
||||||
@@ -147,9 +170,11 @@ class TagsFormField extends StatelessWidget {
|
|||||||
) {
|
) {
|
||||||
return QueryTagChip(
|
return QueryTagChip(
|
||||||
onDeleted: () {
|
onDeleted: () {
|
||||||
final updatedQuery = query.withRemoved([e]);
|
final updatedQuery = query.copyWith(
|
||||||
|
tagIds: query.tagIds.whereNot((element) => element == e),
|
||||||
|
);
|
||||||
if (updatedQuery.tagIds.isEmpty) {
|
if (updatedQuery.tagIds.isEmpty) {
|
||||||
field.didChange(const IdsTagsQuery());
|
field.didChange(const TagsQuery.ids());
|
||||||
} else {
|
} else {
|
||||||
field.didChange(updatedQuery);
|
field.didChange(updatedQuery);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,12 +27,9 @@ class LabelsPage extends StatefulWidget {
|
|||||||
State<LabelsPage> createState() => _LabelsPageState();
|
State<LabelsPage> createState() => _LabelsPageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _LabelsPageState extends State<LabelsPage>
|
class _LabelsPageState extends State<LabelsPage> with SingleTickerProviderStateMixin {
|
||||||
with SingleTickerProviderStateMixin {
|
final SliverOverlapAbsorberHandle searchBarHandle = SliverOverlapAbsorberHandle();
|
||||||
final SliverOverlapAbsorberHandle searchBarHandle =
|
final SliverOverlapAbsorberHandle tabBarHandle = SliverOverlapAbsorberHandle();
|
||||||
SliverOverlapAbsorberHandle();
|
|
||||||
final SliverOverlapAbsorberHandle tabBarHandle =
|
|
||||||
SliverOverlapAbsorberHandle();
|
|
||||||
|
|
||||||
late final TabController _tabController;
|
late final TabController _tabController;
|
||||||
int _currentIndex = 0;
|
int _currentIndex = 0;
|
||||||
@@ -82,33 +79,25 @@ class _LabelsPageState extends State<LabelsPage>
|
|||||||
Tab(
|
Tab(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.person_outline,
|
Icons.person_outline,
|
||||||
color: Theme.of(context)
|
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
.colorScheme
|
|
||||||
.onPrimaryContainer,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.description_outlined,
|
Icons.description_outlined,
|
||||||
color: Theme.of(context)
|
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
.colorScheme
|
|
||||||
.onPrimaryContainer,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.label_outline,
|
Icons.label_outline,
|
||||||
color: Theme.of(context)
|
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
.colorScheme
|
|
||||||
.onPrimaryContainer,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Tab(
|
Tab(
|
||||||
icon: Icon(
|
icon: Icon(
|
||||||
Icons.folder_open,
|
Icons.folder_open,
|
||||||
color: Theme.of(context)
|
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
.colorScheme
|
|
||||||
.onPrimaryContainer,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -126,20 +115,17 @@ class _LabelsPageState extends State<LabelsPage>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
final desiredTab =
|
final desiredTab =
|
||||||
((metrics.pixels / metrics.maxScrollExtent) *
|
((metrics.pixels / metrics.maxScrollExtent) * (_tabController.length - 1))
|
||||||
(_tabController.length - 1))
|
|
||||||
.round();
|
.round();
|
||||||
|
|
||||||
if (metrics.axis == Axis.horizontal &&
|
if (metrics.axis == Axis.horizontal && _currentIndex != desiredTab) {
|
||||||
_currentIndex != desiredTab) {
|
|
||||||
setState(() => _currentIndex = desiredTab);
|
setState(() => _currentIndex = desiredTab);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
child: RefreshIndicator(
|
child: RefreshIndicator(
|
||||||
edgeOffset: kTextTabBarHeight,
|
edgeOffset: kTextTabBarHeight,
|
||||||
notificationPredicate: (notification) =>
|
notificationPredicate: (notification) => connectedState.isConnected,
|
||||||
connectedState.isConnected,
|
|
||||||
onRefresh: () => [
|
onRefresh: () => [
|
||||||
context.read<LabelCubit>().reloadCorrespondents,
|
context.read<LabelCubit>().reloadCorrespondents,
|
||||||
context.read<LabelCubit>().reloadDocumentTypes,
|
context.read<LabelCubit>().reloadDocumentTypes,
|
||||||
@@ -157,20 +143,14 @@ class _LabelsPageState extends State<LabelsPage>
|
|||||||
SliverOverlapInjector(handle: searchBarHandle),
|
SliverOverlapInjector(handle: searchBarHandle),
|
||||||
SliverOverlapInjector(handle: tabBarHandle),
|
SliverOverlapInjector(handle: tabBarHandle),
|
||||||
LabelTabView<Correspondent>(
|
LabelTabView<Correspondent>(
|
||||||
labels: context
|
labels: context.watch<LabelCubit>().state.correspondents,
|
||||||
.watch<LabelCubit>()
|
|
||||||
.state
|
|
||||||
.correspondents,
|
|
||||||
filterBuilder: (label) => DocumentFilter(
|
filterBuilder: (label) => DocumentFilter(
|
||||||
correspondent:
|
correspondent: IdQueryParameter.fromId(label.id),
|
||||||
IdQueryParameter.fromId(label.id),
|
|
||||||
pageSize: label.documentCount ?? 0,
|
pageSize: label.documentCount ?? 0,
|
||||||
),
|
),
|
||||||
onEdit: _openEditCorrespondentPage,
|
onEdit: _openEditCorrespondentPage,
|
||||||
emptyStateActionButtonLabel:
|
emptyStateActionButtonLabel: S.of(context)!.addNewCorrespondent,
|
||||||
S.of(context)!.addNewCorrespondent,
|
emptyStateDescription: S.of(context)!.noCorrespondentsSetUp,
|
||||||
emptyStateDescription:
|
|
||||||
S.of(context)!.noCorrespondentsSetUp,
|
|
||||||
onAddNew: _openAddCorrespondentPage,
|
onAddNew: _openAddCorrespondentPage,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -184,20 +164,14 @@ class _LabelsPageState extends State<LabelsPage>
|
|||||||
SliverOverlapInjector(handle: searchBarHandle),
|
SliverOverlapInjector(handle: searchBarHandle),
|
||||||
SliverOverlapInjector(handle: tabBarHandle),
|
SliverOverlapInjector(handle: tabBarHandle),
|
||||||
LabelTabView<DocumentType>(
|
LabelTabView<DocumentType>(
|
||||||
labels: context
|
labels: context.watch<LabelCubit>().state.documentTypes,
|
||||||
.watch<LabelCubit>()
|
|
||||||
.state
|
|
||||||
.documentTypes,
|
|
||||||
filterBuilder: (label) => DocumentFilter(
|
filterBuilder: (label) => DocumentFilter(
|
||||||
documentType:
|
documentType: IdQueryParameter.fromId(label.id),
|
||||||
IdQueryParameter.fromId(label.id),
|
|
||||||
pageSize: label.documentCount ?? 0,
|
pageSize: label.documentCount ?? 0,
|
||||||
),
|
),
|
||||||
onEdit: _openEditDocumentTypePage,
|
onEdit: _openEditDocumentTypePage,
|
||||||
emptyStateActionButtonLabel:
|
emptyStateActionButtonLabel: S.of(context)!.addNewDocumentType,
|
||||||
S.of(context)!.addNewDocumentType,
|
emptyStateDescription: S.of(context)!.noDocumentTypesSetUp,
|
||||||
emptyStateDescription:
|
|
||||||
S.of(context)!.noDocumentTypesSetUp,
|
|
||||||
onAddNew: _openAddDocumentTypePage,
|
onAddNew: _openAddDocumentTypePage,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -211,10 +185,9 @@ class _LabelsPageState extends State<LabelsPage>
|
|||||||
SliverOverlapInjector(handle: searchBarHandle),
|
SliverOverlapInjector(handle: searchBarHandle),
|
||||||
SliverOverlapInjector(handle: tabBarHandle),
|
SliverOverlapInjector(handle: tabBarHandle),
|
||||||
LabelTabView<Tag>(
|
LabelTabView<Tag>(
|
||||||
labels:
|
labels: context.watch<LabelCubit>().state.tags,
|
||||||
context.watch<LabelCubit>().state.tags,
|
|
||||||
filterBuilder: (label) => DocumentFilter(
|
filterBuilder: (label) => DocumentFilter(
|
||||||
tags: IdsTagsQuery.fromIds([label.id!]),
|
tags: TagsQuery.ids(include: [label.id!]),
|
||||||
pageSize: label.documentCount ?? 0,
|
pageSize: label.documentCount ?? 0,
|
||||||
),
|
),
|
||||||
onEdit: _openEditTagPage,
|
onEdit: _openEditTagPage,
|
||||||
@@ -227,10 +200,8 @@ class _LabelsPageState extends State<LabelsPage>
|
|||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
emptyStateActionButtonLabel:
|
emptyStateActionButtonLabel: S.of(context)!.addNewTag,
|
||||||
S.of(context)!.addNewTag,
|
emptyStateDescription: S.of(context)!.noTagsSetUp,
|
||||||
emptyStateDescription:
|
|
||||||
S.of(context)!.noTagsSetUp,
|
|
||||||
onAddNew: _openAddTagPage,
|
onAddNew: _openAddTagPage,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -244,21 +215,15 @@ class _LabelsPageState extends State<LabelsPage>
|
|||||||
SliverOverlapInjector(handle: searchBarHandle),
|
SliverOverlapInjector(handle: searchBarHandle),
|
||||||
SliverOverlapInjector(handle: tabBarHandle),
|
SliverOverlapInjector(handle: tabBarHandle),
|
||||||
LabelTabView<StoragePath>(
|
LabelTabView<StoragePath>(
|
||||||
labels: context
|
labels: context.watch<LabelCubit>().state.storagePaths,
|
||||||
.watch<LabelCubit>()
|
|
||||||
.state
|
|
||||||
.storagePaths,
|
|
||||||
onEdit: _openEditStoragePathPage,
|
onEdit: _openEditStoragePathPage,
|
||||||
filterBuilder: (label) => DocumentFilter(
|
filterBuilder: (label) => DocumentFilter(
|
||||||
storagePath:
|
storagePath: IdQueryParameter.fromId(label.id),
|
||||||
IdQueryParameter.fromId(label.id),
|
|
||||||
pageSize: label.documentCount ?? 0,
|
pageSize: label.documentCount ?? 0,
|
||||||
),
|
),
|
||||||
contentBuilder: (path) => Text(path.path),
|
contentBuilder: (path) => Text(path.path),
|
||||||
emptyStateActionButtonLabel:
|
emptyStateActionButtonLabel: S.of(context)!.addNewStoragePath,
|
||||||
S.of(context)!.addNewStoragePath,
|
emptyStateDescription: S.of(context)!.noStoragePathsSetUp,
|
||||||
emptyStateDescription:
|
|
||||||
S.of(context)!.noStoragePathsSetUp,
|
|
||||||
onAddNew: _openAddStoragePathPage,
|
onAddNew: _openAddStoragePathPage,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ class FullscreenLabelForm<T extends Label> extends StatefulWidget {
|
|||||||
this.addNewLabelText,
|
this.addNewLabelText,
|
||||||
this.autofocus = true,
|
this.autofocus = true,
|
||||||
}) : assert(
|
}) : assert(
|
||||||
!(initialValue?.onlyAssigned ?? false) || showAnyAssignedOption,
|
!(initialValue?.isOnlyAssigned() ?? false) || showAnyAssignedOption,
|
||||||
),
|
),
|
||||||
assert(
|
assert(
|
||||||
!(initialValue?.onlyNotAssigned ?? false) || showNotAssignedOption,
|
!(initialValue?.isOnlyNotAssigned() ?? false) || showNotAssignedOption,
|
||||||
),
|
),
|
||||||
assert((addNewLabelText != null) == (onCreateNewLabel != null));
|
assert((addNewLabelText != null) == (onCreateNewLabel != null));
|
||||||
|
|
||||||
@@ -39,8 +39,7 @@ class FullscreenLabelForm<T extends Label> extends StatefulWidget {
|
|||||||
State<FullscreenLabelForm> createState() => _FullscreenLabelFormState();
|
State<FullscreenLabelForm> createState() => _FullscreenLabelFormState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _FullscreenLabelFormState<T extends Label>
|
class _FullscreenLabelFormState<T extends Label> extends State<FullscreenLabelForm<T>> {
|
||||||
extends State<FullscreenLabelForm<T>> {
|
|
||||||
bool _showClearIcon = false;
|
bool _showClearIcon = false;
|
||||||
final _textEditingController = TextEditingController();
|
final _textEditingController = TextEditingController();
|
||||||
final _focusNode = FocusNode();
|
final _focusNode = FocusNode();
|
||||||
@@ -80,7 +79,12 @@ class _FullscreenLabelFormState<T extends Label>
|
|||||||
FocusScope.of(context).unfocus();
|
FocusScope.of(context).unfocus();
|
||||||
final index = AutocompleteHighlightedOption.of(context);
|
final index = AutocompleteHighlightedOption.of(context);
|
||||||
final value = index.isNegative ? null : options.elementAt(index);
|
final value = index.isNegative ? null : options.elementAt(index);
|
||||||
widget.onSubmit(returnValue: IdQueryParameter.fromId(value?.id));
|
widget.onSubmit(
|
||||||
|
returnValue: IdQueryParameter.fromId(
|
||||||
|
value?.whenOrNull(
|
||||||
|
fromId: (id) => id,
|
||||||
|
),
|
||||||
|
));
|
||||||
},
|
},
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
style: theme.textTheme.bodyLarge?.apply(
|
style: theme.textTheme.bodyLarge?.apply(
|
||||||
@@ -124,11 +128,9 @@ class _FullscreenLabelFormState<T extends Label>
|
|||||||
itemCount: options.length,
|
itemCount: options.length,
|
||||||
itemBuilder: (BuildContext context, int index) {
|
itemBuilder: (BuildContext context, int index) {
|
||||||
final option = options.elementAt(index);
|
final option = options.elementAt(index);
|
||||||
final highlight =
|
final highlight = AutocompleteHighlightedOption.of(context) == index;
|
||||||
AutocompleteHighlightedOption.of(context) == index;
|
|
||||||
if (highlight) {
|
if (highlight) {
|
||||||
SchedulerBinding.instance
|
SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) {
|
||||||
.addPostFrameCallback((Duration timeStamp) {
|
|
||||||
Scrollable.ensureVisible(
|
Scrollable.ensureVisible(
|
||||||
context,
|
context,
|
||||||
alignment: 0,
|
alignment: 0,
|
||||||
@@ -183,7 +185,8 @@ class _FullscreenLabelFormState<T extends Label>
|
|||||||
}
|
}
|
||||||
for (final option in widget.options.values) {
|
for (final option in widget.options.values) {
|
||||||
// Don't include the initial value in the selection
|
// Don't include the initial value in the selection
|
||||||
if (option.id == widget.initialValue?.id) {
|
final initialValue = widget.initialValue;
|
||||||
|
if (initialValue is SetIdQueryParameter && option.id == initialValue.id) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
yield IdQueryParameter.fromId(option.id);
|
yield IdQueryParameter.fromId(option.id);
|
||||||
@@ -191,8 +194,8 @@ class _FullscreenLabelFormState<T extends Label>
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Show filtered options, if no matching option is found, always show not assigned and any assigned (if enabled) and proceed.
|
// Show filtered options, if no matching option is found, always show not assigned and any assigned (if enabled) and proceed.
|
||||||
final matches = widget.options.values
|
final matches =
|
||||||
.where((e) => e.name.trim().toLowerCase().contains(normalizedQuery));
|
widget.options.values.where((e) => e.name.trim().toLowerCase().contains(normalizedQuery));
|
||||||
if (matches.isNotEmpty) {
|
if (matches.isNotEmpty) {
|
||||||
for (final match in matches) {
|
for (final match in matches) {
|
||||||
yield IdQueryParameter.fromId(match.id);
|
yield IdQueryParameter.fromId(match.id);
|
||||||
@@ -218,33 +221,18 @@ class _FullscreenLabelFormState<T extends Label>
|
|||||||
}
|
}
|
||||||
|
|
||||||
String? _buildHintText() {
|
String? _buildHintText() {
|
||||||
if (widget.initialValue?.isSet ?? false) {
|
return widget.initialValue?.when(
|
||||||
return widget.options[widget.initialValue!.id]!.name;
|
unset: () => S.of(context)!.startTyping,
|
||||||
}
|
notAssigned: () => S.of(context)!.notAssigned,
|
||||||
if (widget.initialValue?.onlyNotAssigned ?? false) {
|
anyAssigned: () => S.of(context)!.anyAssigned,
|
||||||
return S.of(context)!.notAssigned;
|
fromId: (id) => widget.options[id]!.name,
|
||||||
}
|
);
|
||||||
if (widget.initialValue?.onlyAssigned ?? false) {
|
|
||||||
return S.of(context)!.anyAssigned;
|
|
||||||
}
|
|
||||||
|
|
||||||
return S.of(context)!.startTyping;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildOptionWidget(IdQueryParameter option, bool highlight) {
|
Widget _buildOptionWidget(IdQueryParameter option, bool highlight) {
|
||||||
void onTap() => widget.onSubmit(returnValue: option);
|
void onTap() => widget.onSubmit(returnValue: option);
|
||||||
late final String title;
|
|
||||||
|
|
||||||
if (option.isSet) {
|
if (option.isUnset()) {
|
||||||
title = widget.options[option.id]!.name;
|
|
||||||
}
|
|
||||||
if (option.onlyNotAssigned) {
|
|
||||||
title = S.of(context)!.notAssigned;
|
|
||||||
}
|
|
||||||
if (option.onlyAssigned) {
|
|
||||||
title = S.of(context)!.anyAssigned;
|
|
||||||
}
|
|
||||||
if (option.isUnset) {
|
|
||||||
return Center(
|
return Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
@@ -258,6 +246,12 @@ class _FullscreenLabelFormState<T extends Label>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final title = option.whenOrNull(
|
||||||
|
notAssigned: () => S.of(context)!.notAssigned,
|
||||||
|
anyAssigned: () => S.of(context)!.anyAssigned,
|
||||||
|
fromId: (id) => widget.options[id]!.name,
|
||||||
|
)!; // Never null, since we already return on unset before
|
||||||
return ListTile(
|
return ListTile(
|
||||||
selected: highlight,
|
selected: highlight,
|
||||||
selectedTileColor: Theme.of(context).focusColor,
|
selectedTileColor: Theme.of(context).focusColor,
|
||||||
|
|||||||
@@ -45,20 +45,19 @@ class LabelFormField<T extends Label> extends StatelessWidget {
|
|||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
String _buildText(BuildContext context, IdQueryParameter? value) {
|
String _buildText(BuildContext context, IdQueryParameter? value) {
|
||||||
if (value?.isSet ?? false) {
|
return value?.when(
|
||||||
return options[value!.id]!.name;
|
unset: () => '',
|
||||||
} else if (value?.onlyNotAssigned ?? false) {
|
notAssigned: () => S.of(context)!.notAssigned,
|
||||||
return S.of(context)!.notAssigned;
|
anyAssigned: () => S.of(context)!.anyAssigned,
|
||||||
} else if (value?.onlyAssigned ?? false) {
|
fromId: (id) => options[id]!.name,
|
||||||
return S.of(context)!.anyAssigned;
|
) ??
|
||||||
}
|
'';
|
||||||
return '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final isEnabled = options.values.any((e) => (e.documentCount ?? 0) > 0) ||
|
final isEnabled =
|
||||||
addLabelPageBuilder != null;
|
options.values.any((e) => (e.documentCount ?? 0) > 0) || addLabelPageBuilder != null;
|
||||||
return FormBuilderField<IdQueryParameter>(
|
return FormBuilderField<IdQueryParameter>(
|
||||||
name: name,
|
name: name,
|
||||||
initialValue: initialValue,
|
initialValue: initialValue,
|
||||||
@@ -68,8 +67,9 @@ class LabelFormField<T extends Label> extends StatelessWidget {
|
|||||||
final controller = TextEditingController(
|
final controller = TextEditingController(
|
||||||
text: _buildText(context, field.value),
|
text: _buildText(context, field.value),
|
||||||
);
|
);
|
||||||
final displayedSuggestions =
|
final displayedSuggestions = suggestions
|
||||||
suggestions.whereNot((e) => e.id == field.value?.id).toList();
|
.whereNot((e) => e.id == field.value?.maybeWhen(fromId: (id) => id, orElse: () => -1))
|
||||||
|
.toList();
|
||||||
|
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
@@ -93,8 +93,7 @@ class LabelFormField<T extends Label> extends StatelessWidget {
|
|||||||
suffixIcon: controller.text.isNotEmpty
|
suffixIcon: controller.text.isNotEmpty
|
||||||
? IconButton(
|
? IconButton(
|
||||||
icon: const Icon(Icons.clear),
|
icon: const Icon(Icons.clear),
|
||||||
onPressed: () =>
|
onPressed: () => field.didChange(const IdQueryParameter.unset()),
|
||||||
field.didChange(const IdQueryParameter.unset()),
|
|
||||||
)
|
)
|
||||||
: null,
|
: null,
|
||||||
),
|
),
|
||||||
@@ -107,8 +106,7 @@ class LabelFormField<T extends Label> extends StatelessWidget {
|
|||||||
? (initialName) {
|
? (initialName) {
|
||||||
return Navigator.of(context).push<T>(
|
return Navigator.of(context).push<T>(
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) =>
|
builder: (context) => addLabelPageBuilder!(initialName),
|
||||||
addLabelPageBuilder!(initialName),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -139,8 +137,7 @@ class LabelFormField<T extends Label> extends StatelessWidget {
|
|||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
itemCount: displayedSuggestions.length,
|
itemCount: displayedSuggestions.length,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
final suggestion =
|
final suggestion = displayedSuggestions.elementAt(index);
|
||||||
displayedSuggestions.elementAt(index);
|
|
||||||
return ColoredChipWrapper(
|
return ColoredChipWrapper(
|
||||||
child: ActionChip(
|
child: ActionChip(
|
||||||
label: Text(suggestion.name),
|
label: Text(suggestion.name),
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import 'package:paperless_api/paperless_api.dart';
|
|||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/features/linked_documents/cubit/linked_documents_cubit.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/features/linked_documents/view/linked_documents_page.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/helpers/format_helpers.dart';
|
import 'package:paperless_mobile/helpers/format_helpers.dart';
|
||||||
|
|
||||||
class LabelItem<T extends Label> extends StatelessWidget {
|
class LabelItem<T extends Label> extends StatelessWidget {
|
||||||
@@ -46,8 +46,7 @@ class LabelItem<T extends Label> extends StatelessWidget {
|
|||||||
onPressed: (label.documentCount ?? 0) == 0
|
onPressed: (label.documentCount ?? 0) == 0
|
||||||
? null
|
? null
|
||||||
: () {
|
: () {
|
||||||
final currentUser =
|
final currentUser = Hive.box<GlobalSettings>(HiveBoxes.globalSettings)
|
||||||
Hive.box<GlobalSettings>(HiveBoxes.globalSettings)
|
|
||||||
.getValue()!
|
.getValue()!
|
||||||
.currentLoggedInUser!;
|
.currentLoggedInUser!;
|
||||||
final filter = filterBuilder(label);
|
final filter = filterBuilder(label);
|
||||||
@@ -60,8 +59,7 @@ class LabelItem<T extends Label> extends StatelessWidget {
|
|||||||
context.read(),
|
context.read(),
|
||||||
context.read(),
|
context.read(),
|
||||||
context.read(),
|
context.read(),
|
||||||
Hive.box<UserAccount>(HiveBoxes.userAccount)
|
Hive.box<UserAccount>(HiveBoxes.userAccount).get(currentUser)!,
|
||||||
.get(currentUser)!,
|
|
||||||
),
|
),
|
||||||
child: const LinkedDocumentsPage(),
|
child: const LinkedDocumentsPage(),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:json_annotation/json_annotation.dart';
|
|||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/paged_document_view/cubit/paged_documents_state.dart';
|
import 'package:paperless_mobile/features/paged_document_view/cubit/paged_documents_state.dart';
|
||||||
import 'package:paperless_mobile/features/paged_document_view/cubit/document_paging_bloc_mixin.dart';
|
import 'package:paperless_mobile/features/paged_document_view/cubit/document_paging_bloc_mixin.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/view_type.dart';
|
import 'package:paperless_mobile/features/settings/model/view_type.dart';
|
||||||
@@ -73,4 +73,7 @@ class LinkedDocumentsCubit extends HydratedCubit<LinkedDocumentsState>
|
|||||||
Map<String, dynamic>? toJson(LinkedDocumentsState state) {
|
Map<String, dynamic>? toJson(LinkedDocumentsState state) {
|
||||||
return state.toJson();
|
return state.toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onFilterUpdated(DocumentFilter filter) async {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,17 +7,18 @@ import 'package:hive_flutter/adapters.dart';
|
|||||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
|
import 'package:paperless_mobile/core/database/tables/user_app_state.dart';
|
||||||
import 'package:paperless_mobile/core/interceptor/dio_http_error_interceptor.dart';
|
import 'package:paperless_mobile/core/interceptor/dio_http_error_interceptor.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.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/saved_view_repository.dart';
|
||||||
import 'package:paperless_mobile/core/security/session_manager.dart';
|
import 'package:paperless_mobile/core/security/session_manager.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_credentials.dart';
|
import 'package:paperless_mobile/core/database/tables/user_credentials.dart';
|
||||||
import 'package:paperless_mobile/features/login/services/authentication_service.dart';
|
import 'package:paperless_mobile/features/login/services/authentication_service.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/user_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/user_settings.dart';
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
part 'authentication_state.dart';
|
part 'authentication_state.dart';
|
||||||
|
|
||||||
@@ -58,33 +59,33 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
clientCertificate: clientCertificate,
|
clientCertificate: clientCertificate,
|
||||||
authToken: token,
|
authToken: token,
|
||||||
);
|
);
|
||||||
|
final userAccountBox = Hive.box<UserAccount>(HiveBoxes.userAccount);
|
||||||
|
final userStateBox = Hive.box<UserAppState>(HiveBoxes.userAppState);
|
||||||
|
|
||||||
final userId = "${credentials.username}@$serverUrl";
|
final userId = "${credentials.username}@$serverUrl";
|
||||||
|
|
||||||
// If it is first time login, create settings for this user.
|
if (userAccountBox.containsKey(userId)) {
|
||||||
final userAccountBox = Hive.box<UserAccount>(HiveBoxes.userAccount);
|
throw Exception("User with id $userId already exists!");
|
||||||
|
}
|
||||||
|
|
||||||
final fullName = await _fetchFullName();
|
final fullName = await _fetchFullName();
|
||||||
if (!userAccountBox.containsKey(userId)) {
|
// Create user account
|
||||||
userAccountBox.put(
|
await userAccountBox.put(
|
||||||
userId,
|
userId,
|
||||||
UserAccount(
|
UserAccount(
|
||||||
id: userId,
|
id: userId,
|
||||||
settings: UserSettings(
|
settings: UserSettings(),
|
||||||
currentDocumentFilter: DocumentFilter(),
|
|
||||||
),
|
|
||||||
serverUrl: serverUrl,
|
serverUrl: serverUrl,
|
||||||
username: credentials.username!,
|
username: credentials.username!,
|
||||||
fullName: fullName,
|
fullName: fullName,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
// Mark logged in user as currently active user.
|
// Create user state
|
||||||
final globalSettings =
|
await userStateBox.put(
|
||||||
Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
userId,
|
||||||
globalSettings.currentLoggedInUser = userId;
|
UserAppState(userId: userId),
|
||||||
globalSettings.save();
|
);
|
||||||
|
|
||||||
// Save credentials in encrypted box
|
// Save credentials in encrypted box
|
||||||
final userCredentialsBox = await _getUserCredentialsBox();
|
final userCredentialsBox = await _getUserCredentialsBox();
|
||||||
@@ -96,21 +97,25 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
userCredentialsBox.close();
|
userCredentialsBox.close();
|
||||||
|
|
||||||
|
// Mark logged in user as currently active user.
|
||||||
|
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
||||||
|
globalSettings.currentLoggedInUser = userId;
|
||||||
|
await globalSettings.save();
|
||||||
|
|
||||||
emit(
|
emit(
|
||||||
AuthenticationState(
|
AuthenticationState(
|
||||||
isAuthenticated: true,
|
isAuthenticated: true,
|
||||||
username: credentials.username,
|
username: credentials.username,
|
||||||
userId: userId,
|
userId: userId,
|
||||||
fullName: fullName,
|
fullName: fullName,
|
||||||
//TODO: Query ui settings with full name and add as parameter here...
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Switches to another account if it exists.
|
/// Switches to another account if it exists.
|
||||||
Future<void> switchAccount(String userId) async {
|
Future<void> switchAccount(String userId) async {
|
||||||
final globalSettings =
|
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
||||||
Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
|
||||||
if (globalSettings.currentLoggedInUser == userId) {
|
if (globalSettings.currentLoggedInUser == userId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -124,8 +129,8 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
final account = userAccountBox.get(userId)!;
|
final account = userAccountBox.get(userId)!;
|
||||||
|
|
||||||
if (account.settings.isBiometricAuthenticationEnabled) {
|
if (account.settings.isBiometricAuthenticationEnabled) {
|
||||||
final authenticated = await _localAuthService
|
final authenticated =
|
||||||
.authenticateLocalUser("Authenticate to switch your account.");
|
await _localAuthService.authenticateLocalUser("Authenticate to switch your account.");
|
||||||
if (!authenticated) {
|
if (!authenticated) {
|
||||||
debugPrint("User not authenticated.");
|
debugPrint("User not authenticated.");
|
||||||
return;
|
return;
|
||||||
@@ -172,6 +177,7 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
final userId = "${credentials.username}@$serverUrl";
|
final userId = "${credentials.username}@$serverUrl";
|
||||||
|
|
||||||
final userAccountsBox = Hive.box<UserAccount>(HiveBoxes.userAccount);
|
final userAccountsBox = Hive.box<UserAccount>(HiveBoxes.userAccount);
|
||||||
|
final userStateBox = Hive.box<UserAppState>(HiveBoxes.userAppState);
|
||||||
|
|
||||||
if (userAccountsBox.containsKey(userId)) {
|
if (userAccountsBox.containsKey(userId)) {
|
||||||
throw Exception("User already exists");
|
throw Exception("User already exists");
|
||||||
@@ -202,12 +208,18 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
username: credentials.username!,
|
username: credentials.username!,
|
||||||
settings: UserSettings(
|
settings: UserSettings(
|
||||||
isBiometricAuthenticationEnabled: enableBiometricAuthentication,
|
isBiometricAuthenticationEnabled: enableBiometricAuthentication,
|
||||||
currentDocumentFilter: DocumentFilter(),
|
|
||||||
),
|
),
|
||||||
fullName: fullName,
|
fullName: fullName,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await userStateBox.put(
|
||||||
|
userId,
|
||||||
|
UserAppState(
|
||||||
|
userId: userId,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
final userCredentialsBox = await _getUserCredentialsBox();
|
final userCredentialsBox = await _getUserCredentialsBox();
|
||||||
await userCredentialsBox.put(
|
await userCredentialsBox.put(
|
||||||
userId,
|
userId,
|
||||||
@@ -221,14 +233,16 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> removeAccount(String userId) async {
|
Future<void> removeAccount(String userId) async {
|
||||||
final globalSettings =
|
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
||||||
Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
|
||||||
final currentUser = globalSettings.currentLoggedInUser;
|
|
||||||
final userAccountBox = Hive.box<UserAccount>(HiveBoxes.userAccount);
|
final userAccountBox = Hive.box<UserAccount>(HiveBoxes.userAccount);
|
||||||
final userCredentialsBox = await _getUserCredentialsBox();
|
final userCredentialsBox = await _getUserCredentialsBox();
|
||||||
|
final userAppStateBox = Hive.box<UserAppState>(HiveBoxes.userAppState);
|
||||||
|
final currentUser = globalSettings.currentLoggedInUser;
|
||||||
|
|
||||||
await userAccountBox.delete(userId);
|
await userAccountBox.delete(userId);
|
||||||
|
await userAppStateBox.delete(userId);
|
||||||
await userCredentialsBox.delete(userId);
|
await userCredentialsBox.delete(userId);
|
||||||
|
await userAccountBox.close();
|
||||||
|
|
||||||
if (currentUser == userId) {
|
if (currentUser == userId) {
|
||||||
return logout();
|
return logout();
|
||||||
@@ -239,31 +253,31 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
/// Performs a conditional hydration based on the local authentication success.
|
/// Performs a conditional hydration based on the local authentication success.
|
||||||
///
|
///
|
||||||
Future<void> restoreSessionState() async {
|
Future<void> restoreSessionState() async {
|
||||||
final globalSettings =
|
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
||||||
Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
|
||||||
final userId = globalSettings.currentLoggedInUser;
|
final userId = globalSettings.currentLoggedInUser;
|
||||||
if (userId == null) {
|
if (userId == null) {
|
||||||
// If there is nothing to restore, we can quit here.
|
// If there is nothing to restore, we can quit here.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final userAccount =
|
final userAccount = Hive.box<UserAccount>(HiveBoxes.userAccount).get(userId)!;
|
||||||
Hive.box<UserAccount>(HiveBoxes.userAccount).get(userId)!;
|
|
||||||
|
|
||||||
if (userAccount.settings.isBiometricAuthenticationEnabled) {
|
if (userAccount.settings.isBiometricAuthenticationEnabled) {
|
||||||
final localAuthSuccess = await _localAuthService
|
final localAuthSuccess =
|
||||||
.authenticateLocalUser("Authenticate to log back in"); //TODO: INTL
|
await _localAuthService.authenticateLocalUser("Authenticate to log back in"); //TODO: INTL
|
||||||
if (!localAuthSuccess) {
|
if (!localAuthSuccess) {
|
||||||
emit(
|
emit(const AuthenticationState(showBiometricAuthenticationScreen: true));
|
||||||
const AuthenticationState(showBiometricAuthenticationScreen: true));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final userCredentialsBox = await _getUserCredentialsBox();
|
final userCredentialsBox = await _getUserCredentialsBox();
|
||||||
|
final authentication = userCredentialsBox.get(globalSettings.currentLoggedInUser!);
|
||||||
|
|
||||||
final authentication =
|
await userCredentialsBox.close();
|
||||||
userCredentialsBox.get(globalSettings.currentLoggedInUser!);
|
|
||||||
if (authentication != null) {
|
if (authentication == null) {
|
||||||
|
throw Exception("User should be authenticated but no authentication information was found.");
|
||||||
|
}
|
||||||
_dioWrapper.updateSettings(
|
_dioWrapper.updateSettings(
|
||||||
clientCertificate: authentication.clientCertificate,
|
clientCertificate: authentication.clientCertificate,
|
||||||
authToken: authentication.token,
|
authToken: authentication.token,
|
||||||
@@ -277,16 +291,11 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
|
|||||||
username: userAccount.username,
|
username: userAccount.username,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
throw Exception(
|
|
||||||
"User should be authenticated but no authentication information was found.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> logout() async {
|
Future<void> logout() async {
|
||||||
await _resetExternalState();
|
await _resetExternalState();
|
||||||
final globalSettings =
|
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
||||||
Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
|
||||||
globalSettings
|
globalSettings
|
||||||
..currentLoggedInUser = null
|
..currentLoggedInUser = null
|
||||||
..save();
|
..save();
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import 'package:paperless_mobile/features/login/view/widgets/form_fields/client_
|
|||||||
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/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/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/features/login/view/widgets/login_pages/server_connection_page.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
||||||
|
|
||||||
import 'widgets/login_pages/server_login_page.dart';
|
import 'widgets/login_pages/server_login_page.dart';
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
|
||||||
|
|
||||||
import 'paged_documents_state.dart';
|
import 'paged_documents_state.dart';
|
||||||
|
|
||||||
@@ -10,11 +9,11 @@ import 'paged_documents_state.dart';
|
|||||||
/// Mixin which can be used on cubits that handle documents.
|
/// Mixin which can be used on cubits that handle documents.
|
||||||
/// This implements all paging and filtering logic.
|
/// This implements all paging and filtering logic.
|
||||||
///
|
///
|
||||||
mixin DocumentPagingBlocMixin<State extends DocumentPagingState>
|
mixin DocumentPagingBlocMixin<State extends DocumentPagingState> on BlocBase<State> {
|
||||||
on BlocBase<State> {
|
|
||||||
PaperlessDocumentsApi get api;
|
PaperlessDocumentsApi get api;
|
||||||
DocumentChangedNotifier get notifier;
|
DocumentChangedNotifier get notifier;
|
||||||
UserAccount get account;
|
|
||||||
|
Future<void> onFilterUpdated(DocumentFilter filter);
|
||||||
|
|
||||||
Future<void> loadMore() async {
|
Future<void> loadMore() async {
|
||||||
if (state.isLastPageLoaded) {
|
if (state.isLastPageLoaded) {
|
||||||
@@ -30,8 +29,7 @@ mixin DocumentPagingBlocMixin<State extends DocumentPagingState>
|
|||||||
value: [...state.value, result],
|
value: [...state.value, result],
|
||||||
));
|
));
|
||||||
} finally {
|
} finally {
|
||||||
account.settings.currentDocumentFilter = newFilter;
|
await onFilterUpdated(newFilter);
|
||||||
account.save();
|
|
||||||
emit(state.copyWithPaged(isLoading: false));
|
emit(state.copyWithPaged(isLoading: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -52,8 +50,7 @@ mixin DocumentPagingBlocMixin<State extends DocumentPagingState>
|
|||||||
hasLoaded: true,
|
hasLoaded: true,
|
||||||
));
|
));
|
||||||
} finally {
|
} finally {
|
||||||
account.settings.currentDocumentFilter = filter;
|
await onFilterUpdated(filter);
|
||||||
account.save();
|
|
||||||
emit(state.copyWithPaged(isLoading: false));
|
emit(state.copyWithPaged(isLoading: false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -66,13 +63,11 @@ mixin DocumentPagingBlocMixin<State extends DocumentPagingState>
|
|||||||
) async =>
|
) async =>
|
||||||
updateFilter(filter: transformFn(state.filter));
|
updateFilter(filter: transformFn(state.filter));
|
||||||
|
|
||||||
Future<void> resetFilter() {
|
Future<void> resetFilter() async {
|
||||||
final filter = DocumentFilter.initial.copyWith(
|
final filter = DocumentFilter.initial.copyWith(
|
||||||
sortField: state.filter.sortField,
|
sortField: state.filter.sortField,
|
||||||
sortOrder: state.filter.sortOrder,
|
sortOrder: state.filter.sortOrder,
|
||||||
);
|
);
|
||||||
account.settings.currentDocumentFilter = filter;
|
|
||||||
account.save();
|
|
||||||
return updateFilter(filter: filter);
|
return updateFilter(filter: filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,8 +85,7 @@ mixin DocumentPagingBlocMixin<State extends DocumentPagingState>
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
account.settings.currentDocumentFilter = filter;
|
await onFilterUpdated(filter);
|
||||||
account.save();
|
|
||||||
if (!isClosed) {
|
if (!isClosed) {
|
||||||
emit(state.copyWithPaged(isLoading: false));
|
emit(state.copyWithPaged(isLoading: false));
|
||||||
}
|
}
|
||||||
@@ -132,8 +126,7 @@ mixin DocumentPagingBlocMixin<State extends DocumentPagingState>
|
|||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
final foundPage = state.value[index];
|
final foundPage = state.value[index];
|
||||||
final replacementPage = foundPage.copyWith(
|
final replacementPage = foundPage.copyWith(
|
||||||
results: foundPage.results
|
results: foundPage.results..removeWhere((element) => element.id == document.id),
|
||||||
..removeWhere((element) => element.id == document.id),
|
|
||||||
);
|
);
|
||||||
final newCount = foundPage.count - 1;
|
final newCount = foundPage.count - 1;
|
||||||
emit(
|
emit(
|
||||||
@@ -141,8 +134,7 @@ mixin DocumentPagingBlocMixin<State extends DocumentPagingState>
|
|||||||
value: state.value
|
value: state.value
|
||||||
.mapIndexed(
|
.mapIndexed(
|
||||||
(currIndex, element) =>
|
(currIndex, element) =>
|
||||||
(currIndex == index ? replacementPage : element)
|
(currIndex == index ? replacementPage : element).copyWith(count: newCount),
|
||||||
.copyWith(count: newCount),
|
|
||||||
)
|
)
|
||||||
.toList(),
|
.toList(),
|
||||||
),
|
),
|
||||||
@@ -165,14 +157,11 @@ mixin DocumentPagingBlocMixin<State extends DocumentPagingState>
|
|||||||
if (pageIndex != -1) {
|
if (pageIndex != -1) {
|
||||||
final foundPage = state.value[pageIndex];
|
final foundPage = state.value[pageIndex];
|
||||||
final replacementPage = foundPage.copyWith(
|
final replacementPage = foundPage.copyWith(
|
||||||
results: foundPage.results
|
results: foundPage.results.map((doc) => doc.id == document.id ? document : doc).toList(),
|
||||||
.map((doc) => doc.id == document.id ? document : doc)
|
|
||||||
.toList(),
|
|
||||||
);
|
);
|
||||||
final newState = state.copyWithPaged(
|
final newState = state.copyWithPaged(
|
||||||
value: state.value
|
value: state.value
|
||||||
.mapIndexed((currIndex, element) =>
|
.mapIndexed((currIndex, element) => currIndex == pageIndex ? replacementPage : element)
|
||||||
currIndex == pageIndex ? replacementPage : element)
|
|
||||||
.toList(),
|
.toList(),
|
||||||
);
|
);
|
||||||
emit(newState);
|
emit(newState);
|
||||||
|
|||||||
@@ -69,4 +69,7 @@ class SavedViewDetailsCubit extends HydratedCubit<SavedViewDetailsState>
|
|||||||
Map<String, dynamic>? toJson(SavedViewDetailsState state) {
|
Map<String, dynamic>? toJson(SavedViewDetailsState state) {
|
||||||
return state.toJson();
|
return state.toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onFilterUpdated(DocumentFilter filter) async {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
|||||||
import 'package:paperless_mobile/core/widgets/hint_card.dart';
|
import 'package:paperless_mobile/core/widgets/hint_card.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
|||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/login/view/login_page.dart';
|
import 'package:paperless_mobile/features/login/view/login_page.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/dialogs/switch_account_dialog.dart';
|
import 'package:paperless_mobile/features/settings/view/dialogs/switch_account_dialog.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/pages/switching_accounts_page.dart';
|
import 'package:paperless_mobile/features/settings/view/pages/switching_accounts_page.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
||||||
@@ -26,13 +26,11 @@ class ManageAccountsPage extends StatelessWidget {
|
|||||||
return GlobalSettingsBuilder(
|
return GlobalSettingsBuilder(
|
||||||
builder: (context, globalSettings) {
|
builder: (context, globalSettings) {
|
||||||
return ValueListenableBuilder(
|
return ValueListenableBuilder(
|
||||||
valueListenable:
|
valueListenable: Hive.box<UserAccount>(HiveBoxes.userAccount).listenable(),
|
||||||
Hive.box<UserAccount>(HiveBoxes.userAccount).listenable(),
|
|
||||||
builder: (context, box, _) {
|
builder: (context, box, _) {
|
||||||
final userIds = box.keys.toList().cast<String>();
|
final userIds = box.keys.toList().cast<String>();
|
||||||
final otherAccounts = userIds
|
final otherAccounts = userIds
|
||||||
.whereNot(
|
.whereNot((element) => element == globalSettings.currentLoggedInUser)
|
||||||
(element) => element == globalSettings.currentLoggedInUser)
|
|
||||||
.toList();
|
.toList();
|
||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
insetPadding: EdgeInsets.all(24),
|
insetPadding: EdgeInsets.all(24),
|
||||||
@@ -51,11 +49,8 @@ class ManageAccountsPage extends StatelessWidget {
|
|||||||
borderRadius: BorderRadius.circular(24),
|
borderRadius: BorderRadius.circular(24),
|
||||||
),
|
),
|
||||||
children: [
|
children: [
|
||||||
_buildAccountTile(
|
_buildAccountTile(context, globalSettings.currentLoggedInUser!,
|
||||||
context,
|
box.get(globalSettings.currentLoggedInUser!)!, globalSettings),
|
||||||
globalSettings.currentLoggedInUser!,
|
|
||||||
box.get(globalSettings.currentLoggedInUser!)!,
|
|
||||||
globalSettings),
|
|
||||||
// if (otherAccounts.isNotEmpty) Text("Other accounts"),
|
// if (otherAccounts.isNotEmpty) Text("Other accounts"),
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
@@ -188,8 +183,7 @@ class ManageAccountsPage extends StatelessWidget {
|
|||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
builder: (context) => LoginPage(
|
builder: (context) => LoginPage(
|
||||||
titleString: "Add account", //TODO: INTL
|
titleString: "Add account", //TODO: INTL
|
||||||
onSubmit: (context, username, password, serverUrl,
|
onSubmit: (context, username, password, serverUrl, clientCertificate) async {
|
||||||
clientCertificate) async {
|
|
||||||
final userId = await context.read<AuthenticationCubit>().addAccount(
|
final userId = await context.read<AuthenticationCubit>().addAccount(
|
||||||
credentials: LoginFormCredentials(
|
credentials: LoginFormCredentials(
|
||||||
username: username,
|
username: username,
|
||||||
@@ -202,8 +196,8 @@ class ManageAccountsPage extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
final shoudSwitch = await showDialog(
|
final shoudSwitch = await showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
builder: (context) => SwitchAccountDialog(
|
builder: (context) =>
|
||||||
username: username, serverUrl: serverUrl),
|
SwitchAccountDialog(username: username, serverUrl: serverUrl),
|
||||||
) ??
|
) ??
|
||||||
false;
|
false;
|
||||||
if (shoudSwitch) {
|
if (shoudSwitch) {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/features/login/services/authentication_service.dart';
|
import 'package:paperless_mobile/features/login/services/authentication_service.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/user_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/user_settings.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/user_settings_builder.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/user_settings_builder.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import 'package:paperless_mobile/constants.dart';
|
|||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/translation/color_scheme_option_localization_mapper.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/core/widgets/hint_card.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart';
|
import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/radio_settings_dialog.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/radio_settings_dialog.dart';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter/src/widgets/framework.dart';
|
|||||||
import 'package:flutter/src/widgets/placeholder.dart';
|
import 'package:flutter/src/widgets/placeholder.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
|
|
||||||
class GlobalSettingsBuilder extends StatelessWidget {
|
class GlobalSettingsBuilder extends StatelessWidget {
|
||||||
final Widget Function(BuildContext context, GlobalSettings settings) builder;
|
final Widget Function(BuildContext context, GlobalSettings settings) builder;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/radio_settings_dialog.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/radio_settings_dialog.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
|
|
||||||
class UserAvatar extends StatelessWidget {
|
class UserAvatar extends StatelessWidget {
|
||||||
final String userId;
|
final String userId;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/user_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/user_settings.dart';
|
||||||
|
|
||||||
class UserAccountBuilder extends StatelessWidget {
|
class UserAccountBuilder extends StatelessWidget {
|
||||||
final Widget Function(
|
final Widget Function(
|
||||||
@@ -19,12 +19,10 @@ class UserAccountBuilder extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return ValueListenableBuilder<Box<UserAccount>>(
|
return ValueListenableBuilder<Box<UserAccount>>(
|
||||||
valueListenable:
|
valueListenable: Hive.box<UserAccount>(HiveBoxes.userAccount).listenable(),
|
||||||
Hive.box<UserAccount>(HiveBoxes.userAccount).listenable(),
|
|
||||||
builder: (context, accountBox, _) {
|
builder: (context, accountBox, _) {
|
||||||
final currentUser = Hive.box<GlobalSettings>(HiveBoxes.globalSettings)
|
final currentUser =
|
||||||
.getValue()!
|
Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!.currentLoggedInUser;
|
||||||
.currentLoggedInUser;
|
|
||||||
if (currentUser != null) {
|
if (currentUser != null) {
|
||||||
final account = accountBox.get(currentUser);
|
final account = accountBox.get(currentUser);
|
||||||
return builder(context, account);
|
return builder(context, account);
|
||||||
|
|||||||
@@ -7,8 +7,7 @@ import 'package:paperless_mobile/features/paged_document_view/cubit/paged_docume
|
|||||||
|
|
||||||
part 'similar_documents_state.dart';
|
part 'similar_documents_state.dart';
|
||||||
|
|
||||||
class SimilarDocumentsCubit extends Cubit<SimilarDocumentsState>
|
class SimilarDocumentsCubit extends Cubit<SimilarDocumentsState> with DocumentPagingBlocMixin {
|
||||||
with DocumentPagingBlocMixin {
|
|
||||||
final int documentId;
|
final int documentId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -60,4 +59,7 @@ class SimilarDocumentsCubit extends Cubit<SimilarDocumentsState>
|
|||||||
_labelRepository.removeListener(this);
|
_labelRepository.removeListener(this);
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<void> onFilterUpdated(DocumentFilter filter) async {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import 'package:paperless_mobile/constants.dart';
|
|||||||
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
||||||
import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart';
|
import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
||||||
|
import 'package:paperless_mobile/core/database/tables/user_app_state.dart';
|
||||||
import 'package:paperless_mobile/core/interceptor/dio_http_error_interceptor.dart';
|
import 'package:paperless_mobile/core/interceptor/dio_http_error_interceptor.dart';
|
||||||
import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart';
|
import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart';
|
||||||
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
@@ -35,12 +36,11 @@ import 'package:paperless_mobile/features/home/view/widget/verify_identity_page.
|
|||||||
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/user_account.dart';
|
||||||
import 'package:paperless_mobile/features/login/services/authentication_service.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/login/view/login_page.dart';
|
||||||
import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart';
|
import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/user_settings.dart';
|
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
||||||
import 'package:paperless_mobile/features/sharing/share_intent_queue.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/features/tasks/cubit/task_status_cubit.dart';
|
||||||
@@ -54,8 +54,7 @@ import 'package:receive_sharing_intent/receive_sharing_intent.dart';
|
|||||||
|
|
||||||
String get defaultPreferredLocaleSubtag {
|
String get defaultPreferredLocaleSubtag {
|
||||||
String preferredLocale = Platform.localeName.split("_").first;
|
String preferredLocale = Platform.localeName.split("_").first;
|
||||||
if (!S.supportedLocales
|
if (!S.supportedLocales.any((locale) => locale.languageCode == preferredLocale)) {
|
||||||
.any((locale) => locale.languageCode == preferredLocale)) {
|
|
||||||
preferredLocale = 'en';
|
preferredLocale = 'en';
|
||||||
}
|
}
|
||||||
return preferredLocale;
|
return preferredLocale;
|
||||||
@@ -63,14 +62,13 @@ String get defaultPreferredLocaleSubtag {
|
|||||||
|
|
||||||
Future<void> _initHive() async {
|
Future<void> _initHive() async {
|
||||||
await Hive.initFlutter();
|
await Hive.initFlutter();
|
||||||
//TODO: REMOVE!
|
// //TODO: REMOVE!
|
||||||
// await getApplicationDocumentsDirectory()
|
// await getApplicationDocumentsDirectory().then((value) => value.delete(recursive: true));
|
||||||
// .then((value) => value.delete(recursive: true));
|
|
||||||
|
|
||||||
registerHiveAdapters();
|
registerHiveAdapters();
|
||||||
await Hive.openBox<UserAccount>(HiveBoxes.userAccount);
|
await Hive.openBox<UserAccount>(HiveBoxes.userAccount);
|
||||||
final globalSettingsBox =
|
await Hive.openBox<UserAppState>(HiveBoxes.userAppState);
|
||||||
await Hive.openBox<GlobalSettings>(HiveBoxes.globalSettings);
|
final globalSettingsBox = await Hive.openBox<GlobalSettings>(HiveBoxes.globalSettings);
|
||||||
|
|
||||||
if (!globalSettingsBox.hasValue) {
|
if (!globalSettingsBox.hasValue) {
|
||||||
await globalSettingsBox.setValue(
|
await globalSettingsBox.setValue(
|
||||||
@@ -155,8 +153,7 @@ void main() async {
|
|||||||
|
|
||||||
//Update language header in interceptor on language change.
|
//Update language header in interceptor on language change.
|
||||||
globalSettingsBox.listenable().addListener(() {
|
globalSettingsBox.listenable().addListener(() {
|
||||||
languageHeaderInterceptor.preferredLocaleSubtag =
|
languageHeaderInterceptor.preferredLocaleSubtag = globalSettings.preferredLocaleSubtag;
|
||||||
globalSettings.preferredLocaleSubtag;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
runApp(
|
runApp(
|
||||||
@@ -180,8 +177,7 @@ void main() async {
|
|||||||
Provider<ConnectivityStatusService>.value(
|
Provider<ConnectivityStatusService>.value(
|
||||||
value: connectivityStatusService,
|
value: connectivityStatusService,
|
||||||
),
|
),
|
||||||
Provider<LocalNotificationService>.value(
|
Provider<LocalNotificationService>.value(value: localNotificationService),
|
||||||
value: localNotificationService),
|
|
||||||
Provider.value(value: DocumentChangedNotifier()),
|
Provider.value(value: DocumentChangedNotifier()),
|
||||||
],
|
],
|
||||||
child: MultiRepositoryProvider(
|
child: MultiRepositoryProvider(
|
||||||
@@ -211,8 +207,7 @@ class PaperlessMobileEntrypoint extends StatefulWidget {
|
|||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<PaperlessMobileEntrypoint> createState() =>
|
State<PaperlessMobileEntrypoint> createState() => _PaperlessMobileEntrypointState();
|
||||||
_PaperlessMobileEntrypointState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _PaperlessMobileEntrypointState extends State<PaperlessMobileEntrypoint> {
|
class _PaperlessMobileEntrypointState extends State<PaperlessMobileEntrypoint> {
|
||||||
@@ -247,8 +242,7 @@ class _PaperlessMobileEntrypointState extends State<PaperlessMobileEntrypoint> {
|
|||||||
GlobalWidgetsLocalizations.delegate,
|
GlobalWidgetsLocalizations.delegate,
|
||||||
],
|
],
|
||||||
routes: {
|
routes: {
|
||||||
DocumentDetailsRoute.routeName: (context) =>
|
DocumentDetailsRoute.routeName: (context) => const DocumentDetailsRoute(),
|
||||||
const DocumentDetailsRoute(),
|
|
||||||
},
|
},
|
||||||
home: const AuthenticationWrapper(),
|
home: const AuthenticationWrapper(),
|
||||||
);
|
);
|
||||||
@@ -283,11 +277,9 @@ class _AuthenticationWrapperState extends State<AuthenticationWrapper> {
|
|||||||
}
|
}
|
||||||
initializeDateFormatting();
|
initializeDateFormatting();
|
||||||
// For sharing files coming from outside the app while the app is still opened
|
// For sharing files coming from outside the app while the app is still opened
|
||||||
ReceiveSharingIntent.getMediaStream()
|
ReceiveSharingIntent.getMediaStream().listen(ShareIntentQueue.instance.addAll);
|
||||||
.listen(ShareIntentQueue.instance.addAll);
|
|
||||||
// For sharing files coming from outside the app while the app is closed
|
// For sharing files coming from outside the app while the app is closed
|
||||||
ReceiveSharingIntent.getInitialMedia()
|
ReceiveSharingIntent.getInitialMedia().then(ShareIntentQueue.instance.addAll);
|
||||||
.then(ShareIntentQueue.instance.addAll);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _setOptimalDisplayMode() async {
|
Future<void> _setOptimalDisplayMode() async {
|
||||||
@@ -299,8 +291,7 @@ class _AuthenticationWrapperState extends State<AuthenticationWrapper> {
|
|||||||
.toList()
|
.toList()
|
||||||
..sort((a, b) => b.refreshRate.compareTo(a.refreshRate));
|
..sort((a, b) => b.refreshRate.compareTo(a.refreshRate));
|
||||||
|
|
||||||
final DisplayMode mostOptimalMode =
|
final DisplayMode mostOptimalMode = sameResolution.isNotEmpty ? sameResolution.first : active;
|
||||||
sameResolution.isNotEmpty ? sameResolution.first : active;
|
|
||||||
debugPrint('Setting refresh rate to ${mostOptimalMode.refreshRate}');
|
debugPrint('Setting refresh rate to ${mostOptimalMode.refreshRate}');
|
||||||
|
|
||||||
await FlutterDisplayMode.setPreferredMode(mostOptimalMode);
|
await FlutterDisplayMode.setPreferredMode(mostOptimalMode);
|
||||||
@@ -351,14 +342,12 @@ class _AuthenticationWrapperState extends State<AuthenticationWrapper> {
|
|||||||
) async {
|
) async {
|
||||||
try {
|
try {
|
||||||
await context.read<AuthenticationCubit>().login(
|
await context.read<AuthenticationCubit>().login(
|
||||||
credentials:
|
credentials: LoginFormCredentials(username: username, password: password),
|
||||||
LoginFormCredentials(username: username, password: password),
|
|
||||||
serverUrl: serverUrl,
|
serverUrl: serverUrl,
|
||||||
clientCertificate: clientCertificate,
|
clientCertificate: clientCertificate,
|
||||||
);
|
);
|
||||||
// Show onboarding after first login!
|
// Show onboarding after first login!
|
||||||
final globalSettings =
|
final globalSettings = Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
||||||
Hive.box<GlobalSettings>(HiveBoxes.globalSettings).getValue()!;
|
|
||||||
if (globalSettings.showOnboarding) {
|
if (globalSettings.showOnboarding) {
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@@ -1,4 +1,49 @@
|
|||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
|
|
||||||
class PaperlessApiHiveTypeIds {
|
class PaperlessApiHiveTypeIds {
|
||||||
PaperlessApiHiveTypeIds._();
|
PaperlessApiHiveTypeIds._();
|
||||||
static const int documentFilter = 1000;
|
static const int documentFilter = 100;
|
||||||
|
static const int idQueryParameter = 101;
|
||||||
|
static const int tagsQuery = 102;
|
||||||
|
static const int anyAssignedTagsQuery = 103;
|
||||||
|
static const int tagIdQuery = 104;
|
||||||
|
static const int includeTagIdQuery = 105;
|
||||||
|
static const int idsTagsQuery = 106;
|
||||||
|
static const int excludeTagIdQuery = 107;
|
||||||
|
static const int sortField = 108;
|
||||||
|
static const int sortOrder = 109;
|
||||||
|
static const int absoluteDateRangeQuery = 110;
|
||||||
|
static const int relativeDateRangeQuery = 111;
|
||||||
|
static const int dateRangeUnit = 112;
|
||||||
|
static const int unsetDateRangeQuery = 113;
|
||||||
|
static const int textQuery = 114;
|
||||||
|
static const int queryType = 115;
|
||||||
|
static const int unsetIdQueryParameter = 116;
|
||||||
|
static const int notAssignedIdQueryParameter = 117;
|
||||||
|
static const int anyAssignedIdQueryParameter = 118;
|
||||||
|
static const int setIdQueryParameter = 119;
|
||||||
|
static const int notAssignedTagsQuery = 120;
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerPaperlessApiHiveTypeAdapters() {
|
||||||
|
Hive.registerAdapter(DocumentFilterAdapter());
|
||||||
|
// TagsQuery
|
||||||
|
Hive.registerAdapter(AnyAssignedTagsQueryAdapter());
|
||||||
|
Hive.registerAdapter(NotAssignedTagsQueryAdapter());
|
||||||
|
Hive.registerAdapter(IdsTagsQueryAdapter());
|
||||||
|
|
||||||
|
Hive.registerAdapter(SortFieldAdapter());
|
||||||
|
Hive.registerAdapter(SortOrderAdapter());
|
||||||
|
Hive.registerAdapter(AbsoluteDateRangeQueryAdapter());
|
||||||
|
Hive.registerAdapter(RelativeDateRangeQueryAdapter());
|
||||||
|
Hive.registerAdapter(DateRangeUnitAdapter());
|
||||||
|
Hive.registerAdapter(UnsetDateRangeQueryAdapter());
|
||||||
|
Hive.registerAdapter(TextQueryAdapter());
|
||||||
|
Hive.registerAdapter(QueryTypeAdapter());
|
||||||
|
// IdQueryParameter
|
||||||
|
Hive.registerAdapter(SetIdQueryParameterAdapter());
|
||||||
|
Hive.registerAdapter(UnsetIdQueryParameterAdapter());
|
||||||
|
Hive.registerAdapter(AnyAssignedIdQueryParameterAdapter());
|
||||||
|
Hive.registerAdapter(NotAssignedIdQueryParameterAdapter());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ library paperless_api;
|
|||||||
export 'src/models/models.dart';
|
export 'src/models/models.dart';
|
||||||
export 'src/modules/modules.dart';
|
export 'src/modules/modules.dart';
|
||||||
export 'src/converters/converters.dart';
|
export 'src/converters/converters.dart';
|
||||||
|
export 'config/hive/hive_type_ids.dart';
|
||||||
|
|||||||
@@ -1,34 +0,0 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
|
||||||
import 'package:paperless_api/src/models/query_parameters/tags_query/any_assigned_tags_query.dart';
|
|
||||||
import 'package:paperless_api/src/models/query_parameters/tags_query/ids_tags_query.dart';
|
|
||||||
import 'package:paperless_api/src/models/query_parameters/tags_query/only_not_assigned_tags_query.dart';
|
|
||||||
|
|
||||||
import '../models/query_parameters/tags_query/tags_query.dart';
|
|
||||||
|
|
||||||
class TagsQueryJsonConverter
|
|
||||||
extends JsonConverter<TagsQuery, Map<String, dynamic>> {
|
|
||||||
const TagsQueryJsonConverter();
|
|
||||||
@override
|
|
||||||
TagsQuery fromJson(Map<String, dynamic> json) {
|
|
||||||
final type = json['type'] as String;
|
|
||||||
final data = json['data'] as Map<String, dynamic>;
|
|
||||||
switch (type) {
|
|
||||||
case 'OnlyNotAssignedTagsQuery':
|
|
||||||
return const OnlyNotAssignedTagsQuery();
|
|
||||||
case 'AnyAssignedTagsQuery':
|
|
||||||
return AnyAssignedTagsQuery.fromJson(data);
|
|
||||||
case 'IdsTagsQuery':
|
|
||||||
return IdsTagsQuery.fromJson(data);
|
|
||||||
default:
|
|
||||||
throw Exception('Error parsing TagsQuery: Unknown type $type');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> toJson(TagsQuery object) {
|
|
||||||
return {
|
|
||||||
'type': object.runtimeType.toString(),
|
|
||||||
'data': object.toJson(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,11 +4,10 @@ import 'package:hive/hive.dart';
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_api/src/converters/tags_query_json_converter.dart';
|
import 'package:paperless_api/src/models/query_parameters/tags_query/tags_query.dart';
|
||||||
|
|
||||||
part 'document_filter.g.dart';
|
part 'document_filter.g.dart';
|
||||||
|
|
||||||
@TagsQueryJsonConverter()
|
|
||||||
@DateRangeQueryJsonConverter()
|
@DateRangeQueryJsonConverter()
|
||||||
@JsonSerializable(explicitToJson: true)
|
@JsonSerializable(explicitToJson: true)
|
||||||
@HiveType(typeId: PaperlessApiHiveTypeIds.documentFilter)
|
@HiveType(typeId: PaperlessApiHiveTypeIds.documentFilter)
|
||||||
@@ -48,8 +47,6 @@ class DocumentFilter extends Equatable {
|
|||||||
final DateRangeQuery modified;
|
final DateRangeQuery modified;
|
||||||
@HiveField(12)
|
@HiveField(12)
|
||||||
final TextQuery query;
|
final TextQuery query;
|
||||||
|
|
||||||
/// Query documents similar to the document with this id.
|
|
||||||
@HiveField(13)
|
@HiveField(13)
|
||||||
final int? moreLike;
|
final int? moreLike;
|
||||||
|
|
||||||
@@ -58,7 +55,7 @@ class DocumentFilter extends Equatable {
|
|||||||
this.correspondent = const IdQueryParameter.unset(),
|
this.correspondent = const IdQueryParameter.unset(),
|
||||||
this.storagePath = const IdQueryParameter.unset(),
|
this.storagePath = const IdQueryParameter.unset(),
|
||||||
this.asnQuery = const IdQueryParameter.unset(),
|
this.asnQuery = const IdQueryParameter.unset(),
|
||||||
this.tags = const IdsTagsQuery(),
|
this.tags = const TagsQuery.ids(),
|
||||||
this.sortField = SortField.created,
|
this.sortField = SortField.created,
|
||||||
this.sortOrder = SortOrder.descending,
|
this.sortOrder = SortOrder.descending,
|
||||||
this.page = 1,
|
this.page = 1,
|
||||||
@@ -107,9 +104,7 @@ class DocumentFilter extends Equatable {
|
|||||||
final queryParams = groupBy(params, (e) => e.key).map(
|
final queryParams = groupBy(params, (e) => e.key).map(
|
||||||
(key, entries) => MapEntry(
|
(key, entries) => MapEntry(
|
||||||
key,
|
key,
|
||||||
entries.length == 1
|
entries.length == 1 ? entries.first.value : entries.map((e) => e.value).join(","),
|
||||||
? entries.first.value
|
|
||||||
: entries.map((e) => e.value).join(","),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return queryParams;
|
return queryParams;
|
||||||
@@ -150,8 +145,7 @@ class DocumentFilter extends Equatable {
|
|||||||
modified: modified ?? this.modified,
|
modified: modified ?? this.modified,
|
||||||
moreLike: moreLike != null ? moreLike.call() : this.moreLike,
|
moreLike: moreLike != null ? moreLike.call() : this.moreLike,
|
||||||
);
|
);
|
||||||
if (query?.queryType != QueryType.extended &&
|
if (query?.queryType != QueryType.extended && newFilter.forceExtendedQuery) {
|
||||||
newFilter.forceExtendedQuery) {
|
|
||||||
//Prevents infinite recursion
|
//Prevents infinite recursion
|
||||||
return newFilter.copyWith(
|
return newFilter.copyWith(
|
||||||
query: newFilter.query.copyWith(queryType: QueryType.extended),
|
query: newFilter.query.copyWith(queryType: QueryType.extended),
|
||||||
@@ -207,8 +201,7 @@ class DocumentFilter extends Equatable {
|
|||||||
query,
|
query,
|
||||||
];
|
];
|
||||||
|
|
||||||
factory DocumentFilter.fromJson(Map<String, dynamic> json) =>
|
factory DocumentFilter.fromJson(Map<String, dynamic> json) => _$DocumentFilterFromJson(json);
|
||||||
_$DocumentFilterFromJson(json);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$DocumentFilterToJson(this);
|
Map<String, dynamic> toJson() => _$DocumentFilterToJson(this);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,7 @@ import 'package:json_annotation/json_annotation.dart';
|
|||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_api/src/constants.dart';
|
import 'package:paperless_api/src/constants.dart';
|
||||||
import 'package:paperless_api/src/converters/local_date_time_json_converter.dart';
|
import 'package:paperless_api/src/converters/local_date_time_json_converter.dart';
|
||||||
|
import 'package:paperless_api/src/models/query_parameters/tags_query/tags_query.dart';
|
||||||
import 'query_parameters/tags_query/any_assigned_tags_query.dart';
|
|
||||||
import 'query_parameters/tags_query/exclude_tag_id_query.dart';
|
|
||||||
import 'query_parameters/tags_query/ids_tags_query.dart';
|
|
||||||
import 'query_parameters/tags_query/include_tag_id_query.dart';
|
|
||||||
import 'query_parameters/tags_query/only_not_assigned_tags_query.dart';
|
|
||||||
|
|
||||||
part 'filter_rule_model.g.dart';
|
part 'filter_rule_model.g.dart';
|
||||||
|
|
||||||
@@ -77,21 +72,29 @@ class FilterRule with EquatableMixin {
|
|||||||
);
|
);
|
||||||
case hasAnyTag:
|
case hasAnyTag:
|
||||||
return filter.copyWith(
|
return filter.copyWith(
|
||||||
tags: value == "true"
|
tags: value == "true" ? const TagsQuery.anyAssigned() : const TagsQuery.notAssigned(),
|
||||||
? const AnyAssignedTagsQuery()
|
|
||||||
: const OnlyNotAssignedTagsQuery(),
|
|
||||||
);
|
);
|
||||||
case includeTagsRule:
|
case includeTagsRule:
|
||||||
assert(filter.tags is IdsTagsQuery);
|
assert(filter.tags is IdsTagsQuery);
|
||||||
return filter.copyWith(
|
return filter.copyWith(
|
||||||
tags: (filter.tags as IdsTagsQuery)
|
tags: filter.tags.maybeWhen(
|
||||||
.withIdQueriesAdded([IncludeTagIdQuery(int.parse(value!))]),
|
ids: (include, exclude) => TagsQuery.ids(
|
||||||
|
include: [...include, int.parse(value!)],
|
||||||
|
exclude: exclude,
|
||||||
|
),
|
||||||
|
orElse: () => filter.tags,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
case excludeTagsRule:
|
case excludeTagsRule:
|
||||||
assert(filter.tags is IdsTagsQuery);
|
assert(filter.tags is IdsTagsQuery);
|
||||||
return filter.copyWith(
|
return filter.copyWith(
|
||||||
tags: (filter.tags as IdsTagsQuery)
|
tags: filter.tags.maybeWhen(
|
||||||
.withIdQueriesAdded([ExcludeTagIdQuery(int.parse(value!))]),
|
ids: (include, exclude) => TagsQuery.ids(
|
||||||
|
include: include,
|
||||||
|
exclude: [...exclude, int.parse(value!)],
|
||||||
|
),
|
||||||
|
orElse: () => filter.tags,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
case createdBeforeRule:
|
case createdBeforeRule:
|
||||||
if (filter.created is AbsoluteDateRangeQuery) {
|
if (filter.created is AbsoluteDateRangeQuery) {
|
||||||
@@ -101,8 +104,7 @@ class FilterRule with EquatableMixin {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return filter.copyWith(
|
return filter.copyWith(
|
||||||
created: AbsoluteDateRangeQuery(
|
created: AbsoluteDateRangeQuery(before: _dateTimeConverter.fromJson(value!)),
|
||||||
before: _dateTimeConverter.fromJson(value!)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case createdAfterRule:
|
case createdAfterRule:
|
||||||
@@ -113,8 +115,7 @@ class FilterRule with EquatableMixin {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return filter.copyWith(
|
return filter.copyWith(
|
||||||
created: AbsoluteDateRangeQuery(
|
created: AbsoluteDateRangeQuery(after: _dateTimeConverter.fromJson(value!)),
|
||||||
after: _dateTimeConverter.fromJson(value!)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case addedBeforeRule:
|
case addedBeforeRule:
|
||||||
@@ -125,8 +126,7 @@ class FilterRule with EquatableMixin {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return filter.copyWith(
|
return filter.copyWith(
|
||||||
added: AbsoluteDateRangeQuery(
|
added: AbsoluteDateRangeQuery(before: _dateTimeConverter.fromJson(value!)),
|
||||||
before: _dateTimeConverter.fromJson(value!)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case addedAfterRule:
|
case addedAfterRule:
|
||||||
@@ -137,8 +137,7 @@ class FilterRule with EquatableMixin {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return filter.copyWith(
|
return filter.copyWith(
|
||||||
added: AbsoluteDateRangeQuery(
|
added: AbsoluteDateRangeQuery(after: _dateTimeConverter.fromJson(value!)),
|
||||||
after: _dateTimeConverter.fromJson(value!)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case modifiedBeforeRule:
|
case modifiedBeforeRule:
|
||||||
@@ -149,8 +148,7 @@ class FilterRule with EquatableMixin {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return filter.copyWith(
|
return filter.copyWith(
|
||||||
modified: AbsoluteDateRangeQuery(
|
modified: AbsoluteDateRangeQuery(before: _dateTimeConverter.fromJson(value!)),
|
||||||
before: _dateTimeConverter.fromJson(value!)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case modifiedAfterRule:
|
case modifiedAfterRule:
|
||||||
@@ -161,8 +159,7 @@ class FilterRule with EquatableMixin {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return filter.copyWith(
|
return filter.copyWith(
|
||||||
added: AbsoluteDateRangeQuery(
|
added: AbsoluteDateRangeQuery(after: _dateTimeConverter.fromJson(value!)),
|
||||||
after: _dateTimeConverter.fromJson(value!)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
case titleAndContentRule:
|
case titleAndContentRule:
|
||||||
@@ -236,49 +233,46 @@ class FilterRule with EquatableMixin {
|
|||||||
///
|
///
|
||||||
static List<FilterRule> fromFilter(final DocumentFilter filter) {
|
static List<FilterRule> fromFilter(final DocumentFilter filter) {
|
||||||
List<FilterRule> filterRules = [];
|
List<FilterRule> filterRules = [];
|
||||||
if (filter.correspondent.onlyNotAssigned) {
|
final corrRule = filter.correspondent.whenOrNull(
|
||||||
filterRules.add(FilterRule(correspondentRule, null));
|
notAssigned: () => FilterRule(correspondentRule, null),
|
||||||
|
fromId: (id) => FilterRule(correspondentRule, id.toString()),
|
||||||
|
);
|
||||||
|
if (corrRule != null) {
|
||||||
|
filterRules.add(corrRule);
|
||||||
}
|
}
|
||||||
if (filter.correspondent.isSet) {
|
|
||||||
filterRules.add(
|
final docTypeRule = filter.documentType.whenOrNull(
|
||||||
FilterRule(correspondentRule, filter.correspondent.id!.toString()));
|
notAssigned: () => FilterRule(documentTypeRule, null),
|
||||||
|
fromId: (id) => FilterRule(documentTypeRule, id.toString()),
|
||||||
|
);
|
||||||
|
if (docTypeRule != null) {
|
||||||
|
filterRules.add(docTypeRule);
|
||||||
}
|
}
|
||||||
if (filter.documentType.onlyNotAssigned) {
|
|
||||||
filterRules.add(FilterRule(documentTypeRule, null));
|
final sPathRule = filter.documentType.whenOrNull(
|
||||||
}
|
notAssigned: () => FilterRule(storagePathRule, null),
|
||||||
if (filter.documentType.isSet) {
|
fromId: (id) => FilterRule(storagePathRule, id.toString()),
|
||||||
filterRules.add(
|
);
|
||||||
FilterRule(documentTypeRule, filter.documentType.id!.toString()));
|
if (sPathRule != null) {
|
||||||
}
|
filterRules.add(sPathRule);
|
||||||
if (filter.storagePath.onlyNotAssigned) {
|
|
||||||
filterRules.add(FilterRule(storagePathRule, null));
|
|
||||||
}
|
|
||||||
if (filter.storagePath.isSet) {
|
|
||||||
filterRules
|
|
||||||
.add(FilterRule(storagePathRule, filter.storagePath.id!.toString()));
|
|
||||||
}
|
|
||||||
if (filter.tags is OnlyNotAssignedTagsQuery) {
|
|
||||||
filterRules.add(FilterRule(hasAnyTag, false.toString()));
|
|
||||||
}
|
|
||||||
if (filter.tags is AnyAssignedTagsQuery) {
|
|
||||||
filterRules.add(FilterRule(hasAnyTag, true.toString()));
|
|
||||||
}
|
|
||||||
if (filter.tags is IdsTagsQuery) {
|
|
||||||
filterRules.addAll((filter.tags as IdsTagsQuery)
|
|
||||||
.includedIds
|
|
||||||
.map((id) => FilterRule(includeTagsRule, id.toString())));
|
|
||||||
filterRules.addAll((filter.tags as IdsTagsQuery)
|
|
||||||
.excludedIds
|
|
||||||
.map((id) => FilterRule(excludeTagsRule, id.toString())));
|
|
||||||
}
|
}
|
||||||
|
final tagRules = filter.tags.when(
|
||||||
|
notAssigned: () => [FilterRule(hasAnyTag, 'false')],
|
||||||
|
anyAssigned: (_) => [FilterRule(hasAnyTag, 'true')],
|
||||||
|
ids: (include, exclude) => [
|
||||||
|
...include.map((id) => FilterRule(includeTagsRule, id.toString())),
|
||||||
|
...exclude.map((id) => FilterRule(excludeTagsRule, id.toString())),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
filterRules.addAll(tagRules);
|
||||||
|
|
||||||
if (filter.query.queryText != null) {
|
if (filter.query.queryText != null) {
|
||||||
switch (filter.query.queryType) {
|
switch (filter.query.queryType) {
|
||||||
case QueryType.title:
|
case QueryType.title:
|
||||||
filterRules.add(FilterRule(titleRule, filter.query.queryText!));
|
filterRules.add(FilterRule(titleRule, filter.query.queryText!));
|
||||||
break;
|
break;
|
||||||
case QueryType.titleAndContent:
|
case QueryType.titleAndContent:
|
||||||
filterRules
|
filterRules.add(FilterRule(titleAndContentRule, filter.query.queryText!));
|
||||||
.add(FilterRule(titleAndContentRule, filter.query.queryText!));
|
|
||||||
break;
|
break;
|
||||||
case QueryType.extended:
|
case QueryType.extended:
|
||||||
filterRules.add(FilterRule(extendedRule, filter.query.queryText!));
|
filterRules.add(FilterRule(extendedRule, filter.query.queryText!));
|
||||||
@@ -304,8 +298,8 @@ class FilterRule with EquatableMixin {
|
|||||||
}
|
}
|
||||||
} else if (created is RelativeDateRangeQuery) {
|
} else if (created is RelativeDateRangeQuery) {
|
||||||
filterRules.add(
|
filterRules.add(
|
||||||
FilterRule(extendedRule,
|
FilterRule(
|
||||||
created.toQueryParameter(DateRangeQueryField.created).values.first),
|
extendedRule, created.toQueryParameter(DateRangeQueryField.created).values.first),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,8 +318,7 @@ class FilterRule with EquatableMixin {
|
|||||||
}
|
}
|
||||||
} else if (added is RelativeDateRangeQuery) {
|
} else if (added is RelativeDateRangeQuery) {
|
||||||
filterRules.add(
|
filterRules.add(
|
||||||
FilterRule(extendedRule,
|
FilterRule(extendedRule, added.toQueryParameter(DateRangeQueryField.added).values.first),
|
||||||
added.toQueryParameter(DateRangeQueryField.added).values.first),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -339,25 +332,19 @@ class FilterRule with EquatableMixin {
|
|||||||
}
|
}
|
||||||
if (modified.before != null) {
|
if (modified.before != null) {
|
||||||
filterRules.add(
|
filterRules.add(
|
||||||
FilterRule(
|
FilterRule(modifiedBeforeRule, apiDateFormat.format(modified.before!)),
|
||||||
modifiedBeforeRule, apiDateFormat.format(modified.before!)),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else if (modified is RelativeDateRangeQuery) {
|
} else if (modified is RelativeDateRangeQuery) {
|
||||||
filterRules.add(
|
filterRules.add(
|
||||||
FilterRule(
|
FilterRule(
|
||||||
extendedRule,
|
extendedRule, modified.toQueryParameter(DateRangeQueryField.modified).values.first),
|
||||||
modified
|
|
||||||
.toQueryParameter(DateRangeQueryField.modified)
|
|
||||||
.values
|
|
||||||
.first),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Join values of all extended filter rules if exist
|
//Join values of all extended filter rules if exist
|
||||||
if (filterRules.isNotEmpty &&
|
if (filterRules.isNotEmpty &&
|
||||||
filterRules.where((e) => e.ruleType == FilterRule.extendedRule).length >
|
filterRules.where((e) => e.ruleType == FilterRule.extendedRule).length > 1) {
|
||||||
1) {
|
|
||||||
final mergedExtendedRule = filterRules
|
final mergedExtendedRule = filterRules
|
||||||
.where((r) => r.ruleType == FilterRule.extendedRule)
|
.where((r) => r.ruleType == FilterRule.extendedRule)
|
||||||
.map((e) => e.value)
|
.map((e) => e.value)
|
||||||
@@ -381,6 +368,5 @@ class FilterRule with EquatableMixin {
|
|||||||
|
|
||||||
Map<String, dynamic> toJson() => _$FilterRuleToJson(this);
|
Map<String, dynamic> toJson() => _$FilterRuleToJson(this);
|
||||||
|
|
||||||
factory FilterRule.fromJson(Map<String, dynamic> json) =>
|
factory FilterRule.fromJson(Map<String, dynamic> json) => _$FilterRuleFromJson(json);
|
||||||
_$FilterRuleFromJson(json);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ export 'query_parameters/id_query_parameter.dart';
|
|||||||
export 'query_parameters/query_type.dart';
|
export 'query_parameters/query_type.dart';
|
||||||
export 'query_parameters/sort_field.dart';
|
export 'query_parameters/sort_field.dart';
|
||||||
export 'query_parameters/sort_order.dart';
|
export 'query_parameters/sort_order.dart';
|
||||||
export 'query_parameters/tags_query/tags_queries.dart';
|
|
||||||
export 'query_parameters/date_range_queries/date_range_queries.dart';
|
export 'query_parameters/date_range_queries/date_range_queries.dart';
|
||||||
|
export 'query_parameters/tags_query/tags_query.dart';
|
||||||
export 'query_parameters/text_query.dart';
|
export 'query_parameters/text_query.dart';
|
||||||
export 'bulk_edit_model.dart';
|
export 'bulk_edit_model.dart';
|
||||||
export 'document_filter.dart';
|
export 'document_filter.dart';
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
|
import 'package:hive/hive.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
import 'package:paperless_api/src/constants.dart';
|
import 'package:paperless_api/src/constants.dart';
|
||||||
import 'package:paperless_api/src/converters/local_date_time_json_converter.dart';
|
import 'package:paperless_api/src/converters/local_date_time_json_converter.dart';
|
||||||
|
|
||||||
@@ -8,11 +10,14 @@ import 'date_range_query_field.dart';
|
|||||||
part 'absolute_date_range_query.g.dart';
|
part 'absolute_date_range_query.g.dart';
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.absoluteDateRangeQuery)
|
||||||
class AbsoluteDateRangeQuery extends DateRangeQuery {
|
class AbsoluteDateRangeQuery extends DateRangeQuery {
|
||||||
@LocalDateTimeJsonConverter()
|
@LocalDateTimeJsonConverter()
|
||||||
|
@HiveField(0)
|
||||||
final DateTime? after;
|
final DateTime? after;
|
||||||
|
|
||||||
@LocalDateTimeJsonConverter()
|
@LocalDateTimeJsonConverter()
|
||||||
|
@HiveField(1)
|
||||||
final DateTime? before;
|
final DateTime? before;
|
||||||
|
|
||||||
const AbsoluteDateRangeQuery({this.after, this.before});
|
const AbsoluteDateRangeQuery({this.after, this.before});
|
||||||
@@ -47,8 +52,7 @@ class AbsoluteDateRangeQuery extends DateRangeQuery {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
factory AbsoluteDateRangeQuery.fromJson(json) =>
|
factory AbsoluteDateRangeQuery.fromJson(json) => _$AbsoluteDateRangeQueryFromJson(json);
|
||||||
_$AbsoluteDateRangeQueryFromJson(json);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() => _$AbsoluteDateRangeQueryToJson(this);
|
Map<String, dynamic> toJson() => _$AbsoluteDateRangeQueryToJson(this);
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import 'date_range_query_field.dart';
|
|||||||
|
|
||||||
abstract class DateRangeQuery extends Equatable {
|
abstract class DateRangeQuery extends Equatable {
|
||||||
const DateRangeQuery();
|
const DateRangeQuery();
|
||||||
|
|
||||||
Map<String, String> toQueryParameter(DateRangeQueryField field);
|
Map<String, String> toQueryParameter(DateRangeQueryField field);
|
||||||
|
|
||||||
Map<String, dynamic> toJson();
|
Map<String, dynamic> toJson();
|
||||||
|
|||||||
@@ -1,6 +1,15 @@
|
|||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
|
part 'date_range_unit.g.dart';
|
||||||
|
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.dateRangeUnit)
|
||||||
enum DateRangeUnit {
|
enum DateRangeUnit {
|
||||||
|
@HiveField(0)
|
||||||
day,
|
day,
|
||||||
|
@HiveField(1)
|
||||||
week,
|
week,
|
||||||
|
@HiveField(2)
|
||||||
month,
|
month,
|
||||||
|
@HiveField(3)
|
||||||
year;
|
year;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
|
import 'package:hive/hive.dart';
|
||||||
import 'package:jiffy/jiffy.dart';
|
import 'package:jiffy/jiffy.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
|
|
||||||
import 'date_range_query.dart';
|
import 'date_range_query.dart';
|
||||||
import 'date_range_query_field.dart';
|
import 'date_range_query_field.dart';
|
||||||
@@ -7,8 +9,11 @@ import 'date_range_unit.dart';
|
|||||||
part 'relative_date_range_query.g.dart';
|
part 'relative_date_range_query.g.dart';
|
||||||
|
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.relativeDateRangeQuery)
|
||||||
class RelativeDateRangeQuery extends DateRangeQuery {
|
class RelativeDateRangeQuery extends DateRangeQuery {
|
||||||
|
@HiveField(0)
|
||||||
final int offset;
|
final int offset;
|
||||||
|
@HiveField(1)
|
||||||
final DateRangeUnit unit;
|
final DateRangeUnit unit;
|
||||||
|
|
||||||
const RelativeDateRangeQuery([
|
const RelativeDateRangeQuery([
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
import 'package:paperless_api/src/models/query_parameters/date_range_queries/date_range_query_field.dart';
|
import 'package:paperless_api/src/models/query_parameters/date_range_queries/date_range_query_field.dart';
|
||||||
|
|
||||||
import 'date_range_query.dart';
|
import 'date_range_query.dart';
|
||||||
|
part 'unset_date_range_query.g.dart';
|
||||||
|
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.unsetDateRangeQuery)
|
||||||
class UnsetDateRangeQuery extends DateRangeQuery {
|
class UnsetDateRangeQuery extends DateRangeQuery {
|
||||||
const UnsetDateRangeQuery();
|
const UnsetDateRangeQuery();
|
||||||
@override
|
@override
|
||||||
@@ -11,9 +15,7 @@ class UnsetDateRangeQuery extends DateRangeQuery {
|
|||||||
Map<String, String> toQueryParameter(DateRangeQueryField field) => const {};
|
Map<String, String> toQueryParameter(DateRangeQueryField field) => const {};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() => const {};
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool matches(DateTime dt) => true;
|
bool matches(DateTime dt) => true;
|
||||||
|
|||||||
@@ -1,101 +1,113 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
part 'id_query_parameter.freezed.dart';
|
||||||
part 'id_query_parameter.g.dart';
|
part 'id_query_parameter.g.dart';
|
||||||
|
|
||||||
@JsonSerializable()
|
@freezed
|
||||||
class IdQueryParameter extends Equatable {
|
class IdQueryParameter with _$IdQueryParameter {
|
||||||
final int? assignmentStatus;
|
const IdQueryParameter._();
|
||||||
final int? id;
|
@HiveType(typeId: PaperlessApiHiveTypeIds.unsetIdQueryParameter)
|
||||||
|
const factory IdQueryParameter.unset() = UnsetIdQueryParameter;
|
||||||
@Deprecated("Use named constructors, this is only meant for code generation")
|
@HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedIdQueryParameter)
|
||||||
const IdQueryParameter(this.assignmentStatus, this.id);
|
const factory IdQueryParameter.notAssigned() = NotAssignedIdQueryParameter;
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedIdQueryParameter)
|
||||||
const IdQueryParameter.notAssigned()
|
const factory IdQueryParameter.anyAssigned() = AnyAssignedIdQueryParameter;
|
||||||
: assignmentStatus = 1,
|
@HiveType(typeId: PaperlessApiHiveTypeIds.setIdQueryParameter)
|
||||||
id = null;
|
const factory IdQueryParameter.fromId(@HiveField(0) int? id) = SetIdQueryParameter;
|
||||||
|
|
||||||
const IdQueryParameter.anyAssigned()
|
|
||||||
: assignmentStatus = 0,
|
|
||||||
id = null;
|
|
||||||
|
|
||||||
const IdQueryParameter.fromId(this.id) : assignmentStatus = null;
|
|
||||||
|
|
||||||
const IdQueryParameter.unset() : this.fromId(null);
|
|
||||||
|
|
||||||
bool get isUnset => id == null && assignmentStatus == null;
|
|
||||||
|
|
||||||
bool get isSet => id != null && assignmentStatus == null;
|
|
||||||
|
|
||||||
bool get onlyNotAssigned => assignmentStatus == 1;
|
|
||||||
|
|
||||||
bool get onlyAssigned => assignmentStatus == 0;
|
|
||||||
|
|
||||||
Map<String, String> toQueryParameter(String field) {
|
Map<String, String> toQueryParameter(String field) {
|
||||||
final Map<String, String> params = {};
|
return when(
|
||||||
if (onlyNotAssigned || onlyAssigned) {
|
unset: () => {},
|
||||||
params.putIfAbsent(
|
notAssigned: () => {
|
||||||
'${field}__isnull', () => assignmentStatus!.toString());
|
'${field}__isnull': '1',
|
||||||
|
},
|
||||||
|
anyAssigned: () => {
|
||||||
|
'${field}__isnull': '0',
|
||||||
|
},
|
||||||
|
fromId: (id) {
|
||||||
|
if (id == null) {
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
if (isSet) {
|
return {'${field}_id': '$id'};
|
||||||
params.putIfAbsent("${field}__id", () => id!.toString());
|
},
|
||||||
}
|
);
|
||||||
return params;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isOnlyNotAssigned() => this is NotAssignedIdQueryParameter;
|
||||||
|
|
||||||
|
bool isOnlyAssigned() => this is AnyAssignedIdQueryParameter;
|
||||||
|
|
||||||
|
bool isSet() => this is SetIdQueryParameter;
|
||||||
|
|
||||||
|
bool isUnset() => this is UnsetIdQueryParameter;
|
||||||
|
|
||||||
bool matches(int? id) {
|
bool matches(int? id) {
|
||||||
return onlyAssigned && id != null ||
|
return when(
|
||||||
onlyNotAssigned && id == null ||
|
unset: () => true,
|
||||||
isSet && id == this.id ||
|
notAssigned: () => id == null,
|
||||||
isUnset;
|
anyAssigned: () => id != null,
|
||||||
|
fromId: (id_) => id == id_,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
factory IdQueryParameter.fromJson(Map<String, dynamic> json) => _$IdQueryParameterFromJson(json);
|
||||||
List<Object?> get props => [assignmentStatus, id];
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$IdQueryParameterToJson(this);
|
|
||||||
|
|
||||||
factory IdQueryParameter.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$IdQueryParameterFromJson(json);
|
|
||||||
}
|
}
|
||||||
// @freezed
|
|
||||||
// class IdQueryParameter with _$IdQueryParameter {
|
// @JsonSerializable()
|
||||||
// const IdQueryParameter._();
|
// @HiveType(typeId: PaperlessApiHiveTypeIds.idQueryParameter)
|
||||||
// const factory IdQueryParameter.unset() = _UnsetIdQueryParameter;
|
// class IdQueryParameter extends Equatable {
|
||||||
// const factory IdQueryParameter.notAssigned() = _NotAssignedIdQueryParameter;
|
// @HiveField(0)
|
||||||
// const factory IdQueryParameter.anyAssigned() = _AnyAssignedIdQueryParameter;
|
// final int? assignmentStatus;
|
||||||
// const factory IdQueryParameter.id(int id) = _SetIdQueryParameter;
|
// @HiveField(1)
|
||||||
|
// final int? id;
|
||||||
|
|
||||||
|
// @Deprecated("Use named constructors, this is only meant for code generation")
|
||||||
|
// const IdQueryParameter(this.assignmentStatus, this.id);
|
||||||
|
|
||||||
|
// const IdQueryParameter.notAssigned()
|
||||||
|
// : assignmentStatus = 1,
|
||||||
|
// id = null;
|
||||||
|
|
||||||
|
// const IdQueryParameter.anyAssigned()
|
||||||
|
// : assignmentStatus = 0,
|
||||||
|
// id = null;
|
||||||
|
|
||||||
|
// const IdQueryParameter.fromId(this.id) : assignmentStatus = null;
|
||||||
|
|
||||||
|
// const IdQueryParameter.unset() : this.fromId(null);
|
||||||
|
|
||||||
|
// bool get isUnset => id == null && assignmentStatus == null;
|
||||||
|
|
||||||
|
// bool get isSet => id != null && assignmentStatus == null;
|
||||||
|
|
||||||
|
// bool get onlyNotAssigned => assignmentStatus == 1;
|
||||||
|
|
||||||
|
// bool get onlyAssigned => assignmentStatus == 0;
|
||||||
|
|
||||||
// Map<String, String> toQueryParameter(String field) {
|
// Map<String, String> toQueryParameter(String field) {
|
||||||
// return when(
|
// final Map<String, String> params = {};
|
||||||
// unset: () => {},
|
// if (onlyNotAssigned || onlyAssigned) {
|
||||||
// notAssigned: () => {
|
// params.putIfAbsent('${field}__isnull', () => assignmentStatus!.toString());
|
||||||
// '${field}__isnull': '1',
|
// }
|
||||||
// },
|
// if (isSet) {
|
||||||
// anyAssigned: () => {
|
// params.putIfAbsent("${field}__id", () => id!.toString());
|
||||||
// '${field}__isnull': '0',
|
// }
|
||||||
// },
|
// return params;
|
||||||
// id: (id) => {
|
|
||||||
// '${field}_id': '$id',
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// bool get onlyNotAssigned => this is _NotAssignedIdQueryParameter;
|
|
||||||
|
|
||||||
// bool get onlyAssigned => this is _AnyAssignedIdQueryParameter;
|
|
||||||
|
|
||||||
// bool get isSet => this is _SetIdQueryParameter;
|
|
||||||
|
|
||||||
// bool get isUnset => this is _UnsetIdQueryParameter;
|
|
||||||
// bool matches(int? id) {
|
// bool matches(int? id) {
|
||||||
// return when(
|
// return onlyAssigned && id != null ||
|
||||||
// unset: () => true,
|
// onlyNotAssigned && id == null ||
|
||||||
// notAssigned: () => id == null,
|
// isSet && id == this.id ||
|
||||||
// anyAssigned: () => id != null,
|
// isUnset;
|
||||||
// id: (id_) => id == id_,
|
|
||||||
// );
|
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// factory IdQueryParameter.fromJson(Map<String, dynamic> json) =>
|
// @override
|
||||||
// _$IdQueryParameterFromJson(json);
|
// List<Object?> get props => [assignmentStatus, id];
|
||||||
|
|
||||||
|
// Map<String, dynamic> toJson() => _$IdQueryParameterToJson(this);
|
||||||
|
|
||||||
|
// factory IdQueryParameter.fromJson(Map<String, dynamic> json) => _$IdQueryParameterFromJson(json);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,686 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'id_query_parameter.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
||||||
|
|
||||||
|
IdQueryParameter _$IdQueryParameterFromJson(Map<String, dynamic> json) {
|
||||||
|
switch (json['runtimeType']) {
|
||||||
|
case 'unset':
|
||||||
|
return UnsetIdQueryParameter.fromJson(json);
|
||||||
|
case 'notAssigned':
|
||||||
|
return NotAssignedIdQueryParameter.fromJson(json);
|
||||||
|
case 'anyAssigned':
|
||||||
|
return AnyAssignedIdQueryParameter.fromJson(json);
|
||||||
|
case 'fromId':
|
||||||
|
return SetIdQueryParameter.fromJson(json);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw CheckedFromJsonException(json, 'runtimeType', 'IdQueryParameter',
|
||||||
|
'Invalid union type "${json['runtimeType']}"!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$IdQueryParameter {
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() unset,
|
||||||
|
required TResult Function() notAssigned,
|
||||||
|
required TResult Function() anyAssigned,
|
||||||
|
required TResult Function(@HiveField(0) int? id) fromId,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? unset,
|
||||||
|
TResult? Function()? notAssigned,
|
||||||
|
TResult? Function()? anyAssigned,
|
||||||
|
TResult? Function(@HiveField(0) int? id)? fromId,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? unset,
|
||||||
|
TResult Function()? notAssigned,
|
||||||
|
TResult Function()? anyAssigned,
|
||||||
|
TResult Function(@HiveField(0) int? id)? fromId,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(UnsetIdQueryParameter value) unset,
|
||||||
|
required TResult Function(NotAssignedIdQueryParameter value) notAssigned,
|
||||||
|
required TResult Function(AnyAssignedIdQueryParameter value) anyAssigned,
|
||||||
|
required TResult Function(SetIdQueryParameter value) fromId,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(UnsetIdQueryParameter value)? unset,
|
||||||
|
TResult? Function(NotAssignedIdQueryParameter value)? notAssigned,
|
||||||
|
TResult? Function(AnyAssignedIdQueryParameter value)? anyAssigned,
|
||||||
|
TResult? Function(SetIdQueryParameter value)? fromId,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(UnsetIdQueryParameter value)? unset,
|
||||||
|
TResult Function(NotAssignedIdQueryParameter value)? notAssigned,
|
||||||
|
TResult Function(AnyAssignedIdQueryParameter value)? anyAssigned,
|
||||||
|
TResult Function(SetIdQueryParameter value)? fromId,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $IdQueryParameterCopyWith<$Res> {
|
||||||
|
factory $IdQueryParameterCopyWith(
|
||||||
|
IdQueryParameter value, $Res Function(IdQueryParameter) then) =
|
||||||
|
_$IdQueryParameterCopyWithImpl<$Res, IdQueryParameter>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$IdQueryParameterCopyWithImpl<$Res, $Val extends IdQueryParameter>
|
||||||
|
implements $IdQueryParameterCopyWith<$Res> {
|
||||||
|
_$IdQueryParameterCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$UnsetIdQueryParameterCopyWith<$Res> {
|
||||||
|
factory _$$UnsetIdQueryParameterCopyWith(_$UnsetIdQueryParameter value,
|
||||||
|
$Res Function(_$UnsetIdQueryParameter) then) =
|
||||||
|
__$$UnsetIdQueryParameterCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$UnsetIdQueryParameterCopyWithImpl<$Res>
|
||||||
|
extends _$IdQueryParameterCopyWithImpl<$Res, _$UnsetIdQueryParameter>
|
||||||
|
implements _$$UnsetIdQueryParameterCopyWith<$Res> {
|
||||||
|
__$$UnsetIdQueryParameterCopyWithImpl(_$UnsetIdQueryParameter _value,
|
||||||
|
$Res Function(_$UnsetIdQueryParameter) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.unsetIdQueryParameter)
|
||||||
|
class _$UnsetIdQueryParameter extends UnsetIdQueryParameter {
|
||||||
|
const _$UnsetIdQueryParameter({final String? $type})
|
||||||
|
: $type = $type ?? 'unset',
|
||||||
|
super._();
|
||||||
|
|
||||||
|
factory _$UnsetIdQueryParameter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$UnsetIdQueryParameterFromJson(json);
|
||||||
|
|
||||||
|
@JsonKey(name: 'runtimeType')
|
||||||
|
final String $type;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'IdQueryParameter.unset()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType && other is _$UnsetIdQueryParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() unset,
|
||||||
|
required TResult Function() notAssigned,
|
||||||
|
required TResult Function() anyAssigned,
|
||||||
|
required TResult Function(@HiveField(0) int? id) fromId,
|
||||||
|
}) {
|
||||||
|
return unset();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? unset,
|
||||||
|
TResult? Function()? notAssigned,
|
||||||
|
TResult? Function()? anyAssigned,
|
||||||
|
TResult? Function(@HiveField(0) int? id)? fromId,
|
||||||
|
}) {
|
||||||
|
return unset?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? unset,
|
||||||
|
TResult Function()? notAssigned,
|
||||||
|
TResult Function()? anyAssigned,
|
||||||
|
TResult Function(@HiveField(0) int? id)? fromId,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (unset != null) {
|
||||||
|
return unset();
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(UnsetIdQueryParameter value) unset,
|
||||||
|
required TResult Function(NotAssignedIdQueryParameter value) notAssigned,
|
||||||
|
required TResult Function(AnyAssignedIdQueryParameter value) anyAssigned,
|
||||||
|
required TResult Function(SetIdQueryParameter value) fromId,
|
||||||
|
}) {
|
||||||
|
return unset(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(UnsetIdQueryParameter value)? unset,
|
||||||
|
TResult? Function(NotAssignedIdQueryParameter value)? notAssigned,
|
||||||
|
TResult? Function(AnyAssignedIdQueryParameter value)? anyAssigned,
|
||||||
|
TResult? Function(SetIdQueryParameter value)? fromId,
|
||||||
|
}) {
|
||||||
|
return unset?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(UnsetIdQueryParameter value)? unset,
|
||||||
|
TResult Function(NotAssignedIdQueryParameter value)? notAssigned,
|
||||||
|
TResult Function(AnyAssignedIdQueryParameter value)? anyAssigned,
|
||||||
|
TResult Function(SetIdQueryParameter value)? fromId,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (unset != null) {
|
||||||
|
return unset(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$UnsetIdQueryParameterToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class UnsetIdQueryParameter extends IdQueryParameter {
|
||||||
|
const factory UnsetIdQueryParameter() = _$UnsetIdQueryParameter;
|
||||||
|
const UnsetIdQueryParameter._() : super._();
|
||||||
|
|
||||||
|
factory UnsetIdQueryParameter.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$UnsetIdQueryParameter.fromJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$NotAssignedIdQueryParameterCopyWith<$Res> {
|
||||||
|
factory _$$NotAssignedIdQueryParameterCopyWith(
|
||||||
|
_$NotAssignedIdQueryParameter value,
|
||||||
|
$Res Function(_$NotAssignedIdQueryParameter) then) =
|
||||||
|
__$$NotAssignedIdQueryParameterCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$NotAssignedIdQueryParameterCopyWithImpl<$Res>
|
||||||
|
extends _$IdQueryParameterCopyWithImpl<$Res, _$NotAssignedIdQueryParameter>
|
||||||
|
implements _$$NotAssignedIdQueryParameterCopyWith<$Res> {
|
||||||
|
__$$NotAssignedIdQueryParameterCopyWithImpl(
|
||||||
|
_$NotAssignedIdQueryParameter _value,
|
||||||
|
$Res Function(_$NotAssignedIdQueryParameter) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedIdQueryParameter)
|
||||||
|
class _$NotAssignedIdQueryParameter extends NotAssignedIdQueryParameter {
|
||||||
|
const _$NotAssignedIdQueryParameter({final String? $type})
|
||||||
|
: $type = $type ?? 'notAssigned',
|
||||||
|
super._();
|
||||||
|
|
||||||
|
factory _$NotAssignedIdQueryParameter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$NotAssignedIdQueryParameterFromJson(json);
|
||||||
|
|
||||||
|
@JsonKey(name: 'runtimeType')
|
||||||
|
final String $type;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'IdQueryParameter.notAssigned()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$NotAssignedIdQueryParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() unset,
|
||||||
|
required TResult Function() notAssigned,
|
||||||
|
required TResult Function() anyAssigned,
|
||||||
|
required TResult Function(@HiveField(0) int? id) fromId,
|
||||||
|
}) {
|
||||||
|
return notAssigned();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? unset,
|
||||||
|
TResult? Function()? notAssigned,
|
||||||
|
TResult? Function()? anyAssigned,
|
||||||
|
TResult? Function(@HiveField(0) int? id)? fromId,
|
||||||
|
}) {
|
||||||
|
return notAssigned?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? unset,
|
||||||
|
TResult Function()? notAssigned,
|
||||||
|
TResult Function()? anyAssigned,
|
||||||
|
TResult Function(@HiveField(0) int? id)? fromId,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (notAssigned != null) {
|
||||||
|
return notAssigned();
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(UnsetIdQueryParameter value) unset,
|
||||||
|
required TResult Function(NotAssignedIdQueryParameter value) notAssigned,
|
||||||
|
required TResult Function(AnyAssignedIdQueryParameter value) anyAssigned,
|
||||||
|
required TResult Function(SetIdQueryParameter value) fromId,
|
||||||
|
}) {
|
||||||
|
return notAssigned(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(UnsetIdQueryParameter value)? unset,
|
||||||
|
TResult? Function(NotAssignedIdQueryParameter value)? notAssigned,
|
||||||
|
TResult? Function(AnyAssignedIdQueryParameter value)? anyAssigned,
|
||||||
|
TResult? Function(SetIdQueryParameter value)? fromId,
|
||||||
|
}) {
|
||||||
|
return notAssigned?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(UnsetIdQueryParameter value)? unset,
|
||||||
|
TResult Function(NotAssignedIdQueryParameter value)? notAssigned,
|
||||||
|
TResult Function(AnyAssignedIdQueryParameter value)? anyAssigned,
|
||||||
|
TResult Function(SetIdQueryParameter value)? fromId,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (notAssigned != null) {
|
||||||
|
return notAssigned(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$NotAssignedIdQueryParameterToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class NotAssignedIdQueryParameter extends IdQueryParameter {
|
||||||
|
const factory NotAssignedIdQueryParameter() = _$NotAssignedIdQueryParameter;
|
||||||
|
const NotAssignedIdQueryParameter._() : super._();
|
||||||
|
|
||||||
|
factory NotAssignedIdQueryParameter.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$NotAssignedIdQueryParameter.fromJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$AnyAssignedIdQueryParameterCopyWith<$Res> {
|
||||||
|
factory _$$AnyAssignedIdQueryParameterCopyWith(
|
||||||
|
_$AnyAssignedIdQueryParameter value,
|
||||||
|
$Res Function(_$AnyAssignedIdQueryParameter) then) =
|
||||||
|
__$$AnyAssignedIdQueryParameterCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$AnyAssignedIdQueryParameterCopyWithImpl<$Res>
|
||||||
|
extends _$IdQueryParameterCopyWithImpl<$Res, _$AnyAssignedIdQueryParameter>
|
||||||
|
implements _$$AnyAssignedIdQueryParameterCopyWith<$Res> {
|
||||||
|
__$$AnyAssignedIdQueryParameterCopyWithImpl(
|
||||||
|
_$AnyAssignedIdQueryParameter _value,
|
||||||
|
$Res Function(_$AnyAssignedIdQueryParameter) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedIdQueryParameter)
|
||||||
|
class _$AnyAssignedIdQueryParameter extends AnyAssignedIdQueryParameter {
|
||||||
|
const _$AnyAssignedIdQueryParameter({final String? $type})
|
||||||
|
: $type = $type ?? 'anyAssigned',
|
||||||
|
super._();
|
||||||
|
|
||||||
|
factory _$AnyAssignedIdQueryParameter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$AnyAssignedIdQueryParameterFromJson(json);
|
||||||
|
|
||||||
|
@JsonKey(name: 'runtimeType')
|
||||||
|
final String $type;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'IdQueryParameter.anyAssigned()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$AnyAssignedIdQueryParameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() unset,
|
||||||
|
required TResult Function() notAssigned,
|
||||||
|
required TResult Function() anyAssigned,
|
||||||
|
required TResult Function(@HiveField(0) int? id) fromId,
|
||||||
|
}) {
|
||||||
|
return anyAssigned();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? unset,
|
||||||
|
TResult? Function()? notAssigned,
|
||||||
|
TResult? Function()? anyAssigned,
|
||||||
|
TResult? Function(@HiveField(0) int? id)? fromId,
|
||||||
|
}) {
|
||||||
|
return anyAssigned?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? unset,
|
||||||
|
TResult Function()? notAssigned,
|
||||||
|
TResult Function()? anyAssigned,
|
||||||
|
TResult Function(@HiveField(0) int? id)? fromId,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (anyAssigned != null) {
|
||||||
|
return anyAssigned();
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(UnsetIdQueryParameter value) unset,
|
||||||
|
required TResult Function(NotAssignedIdQueryParameter value) notAssigned,
|
||||||
|
required TResult Function(AnyAssignedIdQueryParameter value) anyAssigned,
|
||||||
|
required TResult Function(SetIdQueryParameter value) fromId,
|
||||||
|
}) {
|
||||||
|
return anyAssigned(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(UnsetIdQueryParameter value)? unset,
|
||||||
|
TResult? Function(NotAssignedIdQueryParameter value)? notAssigned,
|
||||||
|
TResult? Function(AnyAssignedIdQueryParameter value)? anyAssigned,
|
||||||
|
TResult? Function(SetIdQueryParameter value)? fromId,
|
||||||
|
}) {
|
||||||
|
return anyAssigned?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(UnsetIdQueryParameter value)? unset,
|
||||||
|
TResult Function(NotAssignedIdQueryParameter value)? notAssigned,
|
||||||
|
TResult Function(AnyAssignedIdQueryParameter value)? anyAssigned,
|
||||||
|
TResult Function(SetIdQueryParameter value)? fromId,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (anyAssigned != null) {
|
||||||
|
return anyAssigned(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$AnyAssignedIdQueryParameterToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AnyAssignedIdQueryParameter extends IdQueryParameter {
|
||||||
|
const factory AnyAssignedIdQueryParameter() = _$AnyAssignedIdQueryParameter;
|
||||||
|
const AnyAssignedIdQueryParameter._() : super._();
|
||||||
|
|
||||||
|
factory AnyAssignedIdQueryParameter.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$AnyAssignedIdQueryParameter.fromJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$SetIdQueryParameterCopyWith<$Res> {
|
||||||
|
factory _$$SetIdQueryParameterCopyWith(_$SetIdQueryParameter value,
|
||||||
|
$Res Function(_$SetIdQueryParameter) then) =
|
||||||
|
__$$SetIdQueryParameterCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({@HiveField(0) int? id});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$SetIdQueryParameterCopyWithImpl<$Res>
|
||||||
|
extends _$IdQueryParameterCopyWithImpl<$Res, _$SetIdQueryParameter>
|
||||||
|
implements _$$SetIdQueryParameterCopyWith<$Res> {
|
||||||
|
__$$SetIdQueryParameterCopyWithImpl(
|
||||||
|
_$SetIdQueryParameter _value, $Res Function(_$SetIdQueryParameter) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? id = freezed,
|
||||||
|
}) {
|
||||||
|
return _then(_$SetIdQueryParameter(
|
||||||
|
freezed == id
|
||||||
|
? _value.id
|
||||||
|
: id // ignore: cast_nullable_to_non_nullable
|
||||||
|
as int?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.setIdQueryParameter)
|
||||||
|
class _$SetIdQueryParameter extends SetIdQueryParameter {
|
||||||
|
const _$SetIdQueryParameter(@HiveField(0) this.id, {final String? $type})
|
||||||
|
: $type = $type ?? 'fromId',
|
||||||
|
super._();
|
||||||
|
|
||||||
|
factory _$SetIdQueryParameter.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$SetIdQueryParameterFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@HiveField(0)
|
||||||
|
final int? id;
|
||||||
|
|
||||||
|
@JsonKey(name: 'runtimeType')
|
||||||
|
final String $type;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'IdQueryParameter.fromId(id: $id)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$SetIdQueryParameter &&
|
||||||
|
(identical(other.id, id) || other.id == id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType, id);
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$SetIdQueryParameterCopyWith<_$SetIdQueryParameter> get copyWith =>
|
||||||
|
__$$SetIdQueryParameterCopyWithImpl<_$SetIdQueryParameter>(
|
||||||
|
this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() unset,
|
||||||
|
required TResult Function() notAssigned,
|
||||||
|
required TResult Function() anyAssigned,
|
||||||
|
required TResult Function(@HiveField(0) int? id) fromId,
|
||||||
|
}) {
|
||||||
|
return fromId(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? unset,
|
||||||
|
TResult? Function()? notAssigned,
|
||||||
|
TResult? Function()? anyAssigned,
|
||||||
|
TResult? Function(@HiveField(0) int? id)? fromId,
|
||||||
|
}) {
|
||||||
|
return fromId?.call(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? unset,
|
||||||
|
TResult Function()? notAssigned,
|
||||||
|
TResult Function()? anyAssigned,
|
||||||
|
TResult Function(@HiveField(0) int? id)? fromId,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (fromId != null) {
|
||||||
|
return fromId(id);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(UnsetIdQueryParameter value) unset,
|
||||||
|
required TResult Function(NotAssignedIdQueryParameter value) notAssigned,
|
||||||
|
required TResult Function(AnyAssignedIdQueryParameter value) anyAssigned,
|
||||||
|
required TResult Function(SetIdQueryParameter value) fromId,
|
||||||
|
}) {
|
||||||
|
return fromId(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(UnsetIdQueryParameter value)? unset,
|
||||||
|
TResult? Function(NotAssignedIdQueryParameter value)? notAssigned,
|
||||||
|
TResult? Function(AnyAssignedIdQueryParameter value)? anyAssigned,
|
||||||
|
TResult? Function(SetIdQueryParameter value)? fromId,
|
||||||
|
}) {
|
||||||
|
return fromId?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(UnsetIdQueryParameter value)? unset,
|
||||||
|
TResult Function(NotAssignedIdQueryParameter value)? notAssigned,
|
||||||
|
TResult Function(AnyAssignedIdQueryParameter value)? anyAssigned,
|
||||||
|
TResult Function(SetIdQueryParameter value)? fromId,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (fromId != null) {
|
||||||
|
return fromId(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$SetIdQueryParameterToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class SetIdQueryParameter extends IdQueryParameter {
|
||||||
|
const factory SetIdQueryParameter(@HiveField(0) final int? id) =
|
||||||
|
_$SetIdQueryParameter;
|
||||||
|
const SetIdQueryParameter._() : super._();
|
||||||
|
|
||||||
|
factory SetIdQueryParameter.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$SetIdQueryParameter.fromJson;
|
||||||
|
|
||||||
|
@HiveField(0)
|
||||||
|
int? get id;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$SetIdQueryParameterCopyWith<_$SetIdQueryParameter> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
|
||||||
|
|
||||||
@JsonEnum()
|
|
||||||
enum TagsQueryType {
|
|
||||||
notAssigned,
|
|
||||||
anyAssigned,
|
|
||||||
ids,
|
|
||||||
id,
|
|
||||||
include,
|
|
||||||
exclude;
|
|
||||||
}
|
|
||||||
@@ -1,7 +1,17 @@
|
|||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
|
|
||||||
|
part 'query_type.g.dart';
|
||||||
|
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.queryType)
|
||||||
enum QueryType {
|
enum QueryType {
|
||||||
|
@HiveField(0)
|
||||||
title('title__icontains'),
|
title('title__icontains'),
|
||||||
|
@HiveField(1)
|
||||||
titleAndContent('title_content'),
|
titleAndContent('title_content'),
|
||||||
|
@HiveField(2)
|
||||||
extended('query'),
|
extended('query'),
|
||||||
|
@HiveField(3)
|
||||||
asn('asn');
|
asn('asn');
|
||||||
|
|
||||||
final String queryParam;
|
final String queryParam;
|
||||||
|
|||||||
@@ -1,14 +1,27 @@
|
|||||||
|
import 'package:hive/hive.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
|
|
||||||
|
part 'sort_field.g.dart';
|
||||||
|
|
||||||
@JsonEnum(valueField: 'queryString')
|
@JsonEnum(valueField: 'queryString')
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.sortField)
|
||||||
enum SortField {
|
enum SortField {
|
||||||
|
@HiveField(0)
|
||||||
archiveSerialNumber("archive_serial_number"),
|
archiveSerialNumber("archive_serial_number"),
|
||||||
|
@HiveField(1)
|
||||||
correspondentName("correspondent__name"),
|
correspondentName("correspondent__name"),
|
||||||
|
@HiveField(2)
|
||||||
title("title"),
|
title("title"),
|
||||||
|
@HiveField(3)
|
||||||
documentType("document_type__name"),
|
documentType("document_type__name"),
|
||||||
|
@HiveField(4)
|
||||||
created("created"),
|
created("created"),
|
||||||
|
@HiveField(5)
|
||||||
added("added"),
|
added("added"),
|
||||||
|
@HiveField(6)
|
||||||
modified("modified"),
|
modified("modified"),
|
||||||
|
@HiveField(7)
|
||||||
score("score");
|
score("score");
|
||||||
|
|
||||||
final String queryString;
|
final String queryString;
|
||||||
|
|||||||
@@ -1,8 +1,15 @@
|
|||||||
|
import 'package:hive/hive.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
|
|
||||||
|
part 'sort_order.g.dart';
|
||||||
|
|
||||||
@JsonEnum()
|
@JsonEnum()
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.sortOrder)
|
||||||
enum SortOrder {
|
enum SortOrder {
|
||||||
|
@HiveField(0)
|
||||||
ascending(""),
|
ascending(""),
|
||||||
|
@HiveField(1)
|
||||||
descending("-");
|
descending("-");
|
||||||
|
|
||||||
final String queryString;
|
final String queryString;
|
||||||
|
|||||||
@@ -1,46 +0,0 @@
|
|||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
|
||||||
|
|
||||||
import 'tags_query.dart';
|
|
||||||
part 'any_assigned_tags_query.g.dart';
|
|
||||||
|
|
||||||
@JsonSerializable(explicitToJson: true)
|
|
||||||
class AnyAssignedTagsQuery extends TagsQuery {
|
|
||||||
final Iterable<int> tagIds;
|
|
||||||
|
|
||||||
const AnyAssignedTagsQuery({
|
|
||||||
this.tagIds = const [],
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, String> toQueryParameter() {
|
|
||||||
if (tagIds.isEmpty) {
|
|
||||||
return {'is_tagged': '1'};
|
|
||||||
}
|
|
||||||
return {'tags__id__in': tagIds.join(',')};
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object?> get props => [tagIds];
|
|
||||||
|
|
||||||
AnyAssignedTagsQuery withRemoved(Iterable<int> ids) {
|
|
||||||
return AnyAssignedTagsQuery(
|
|
||||||
tagIds: tagIds.toSet().difference(ids.toSet()).toList(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
AnyAssignedTagsQuery withAdded(Iterable<int> ids) {
|
|
||||||
return AnyAssignedTagsQuery(tagIds: [...tagIds, ...ids]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> toJson() => _$AnyAssignedTagsQueryToJson(this);
|
|
||||||
|
|
||||||
factory AnyAssignedTagsQuery.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$AnyAssignedTagsQueryFromJson(json);
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool matches(Iterable<int> ids) {
|
|
||||||
return ids.isNotEmpty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import 'package:paperless_api/src/models/query_parameters/tags_query/tag_id_query.dart';
|
|
||||||
|
|
||||||
import 'include_tag_id_query.dart';
|
|
||||||
|
|
||||||
class ExcludeTagIdQuery extends TagIdQuery {
|
|
||||||
const ExcludeTagIdQuery(super.id);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get methodName => 'exclude';
|
|
||||||
|
|
||||||
@override
|
|
||||||
TagIdQuery toggle() {
|
|
||||||
return IncludeTagIdQuery(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'exclude_tag_id_query.dart';
|
|
||||||
import 'include_tag_id_query.dart';
|
|
||||||
import 'tag_id_query.dart';
|
|
||||||
import 'tags_query.dart';
|
|
||||||
|
|
||||||
class IdsTagsQuery extends TagsQuery {
|
|
||||||
final Iterable<TagIdQuery> _idQueries;
|
|
||||||
|
|
||||||
const IdsTagsQuery([this._idQueries = const []]);
|
|
||||||
|
|
||||||
IdsTagsQuery.included(Iterable<int> ids)
|
|
||||||
: _idQueries = ids.map((id) => IncludeTagIdQuery(id));
|
|
||||||
|
|
||||||
IdsTagsQuery.fromIds(Iterable<int> ids) : this.included(ids);
|
|
||||||
|
|
||||||
IdsTagsQuery.excluded(Iterable<int> ids)
|
|
||||||
: _idQueries = ids.map((id) => ExcludeTagIdQuery(id));
|
|
||||||
|
|
||||||
IdsTagsQuery withIdQueriesAdded(Iterable<TagIdQuery> idQueries) {
|
|
||||||
final intersection = idQueries
|
|
||||||
.map((idQ) => idQ.id)
|
|
||||||
.toSet()
|
|
||||||
.intersection(_idQueries.map((idQ) => idQ.id).toSet());
|
|
||||||
final res = IdsTagsQuery(
|
|
||||||
[...withIdsRemoved(intersection).queries, ...idQueries],
|
|
||||||
);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
IdsTagsQuery withIdsRemoved(Iterable<int> ids) {
|
|
||||||
return IdsTagsQuery(
|
|
||||||
_idQueries.where((idQuery) => !ids.contains(idQuery.id)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterable<TagIdQuery> get queries => _idQueries;
|
|
||||||
|
|
||||||
Iterable<int> get includedIds {
|
|
||||||
return _idQueries.whereType<IncludeTagIdQuery>().map((e) => e.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterable<int> get excludedIds {
|
|
||||||
return _idQueries.whereType<ExcludeTagIdQuery>().map((e) => e.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns a new instance with the type of the given [id] toggled.
|
|
||||||
/// E.g. if the provided [id] is currently registered as a [IncludeTagIdQuery],
|
|
||||||
/// then the new isntance will contain a [ExcludeTagIdQuery] with given id.
|
|
||||||
///
|
|
||||||
IdsTagsQuery withIdQueryToggled(int id) {
|
|
||||||
return IdsTagsQuery(
|
|
||||||
_idQueries.map((idQ) => idQ.id == id ? idQ.toggle() : idQ),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Iterable<int> get ids => [...includedIds, ...excludedIds];
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, String> toQueryParameter() {
|
|
||||||
final Map<String, String> params = {};
|
|
||||||
if (includedIds.isNotEmpty) {
|
|
||||||
params.putIfAbsent('tags__id__all', () => includedIds.join(','));
|
|
||||||
}
|
|
||||||
if (excludedIds.isNotEmpty) {
|
|
||||||
params.putIfAbsent('tags__id__none', () => excludedIds.join(','));
|
|
||||||
}
|
|
||||||
return params;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object?> get props => [_idQueries];
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return {
|
|
||||||
'queries': _idQueries.map((e) => e.toJson()).toList(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
factory IdsTagsQuery.fromJson(Map<String, dynamic> json) {
|
|
||||||
return IdsTagsQuery(
|
|
||||||
(json['queries'] as List).map((e) => TagIdQuery.fromJson(e)),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool matches(Iterable<int> ids) {
|
|
||||||
return includedIds.toSet().difference(ids.toSet()).isEmpty &&
|
|
||||||
excludedIds.toSet().intersection(ids.toSet()).isEmpty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import 'package:paperless_api/src/models/query_parameters/tags_query/tag_id_query.dart';
|
|
||||||
|
|
||||||
import 'exclude_tag_id_query.dart';
|
|
||||||
|
|
||||||
class IncludeTagIdQuery extends TagIdQuery {
|
|
||||||
const IncludeTagIdQuery(super.id);
|
|
||||||
|
|
||||||
@override
|
|
||||||
String get methodName => 'include';
|
|
||||||
|
|
||||||
@override
|
|
||||||
TagIdQuery toggle() {
|
|
||||||
return ExcludeTagIdQuery(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
import 'tags_query.dart';
|
|
||||||
|
|
||||||
class OnlyNotAssignedTagsQuery extends TagsQuery {
|
|
||||||
const OnlyNotAssignedTagsQuery();
|
|
||||||
@override
|
|
||||||
Map<String, String> toQueryParameter() {
|
|
||||||
return {'is_tagged': '0'};
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object?> get props => [];
|
|
||||||
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
bool matches(Iterable<int> ids) {
|
|
||||||
return ids.isEmpty;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,35 +0,0 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
|
||||||
|
|
||||||
abstract class TagIdQuery extends Equatable {
|
|
||||||
final int id;
|
|
||||||
|
|
||||||
const TagIdQuery(this.id);
|
|
||||||
|
|
||||||
String get methodName;
|
|
||||||
|
|
||||||
@override
|
|
||||||
List<Object?> get props => [id, methodName];
|
|
||||||
|
|
||||||
TagIdQuery toggle();
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
|
||||||
return {
|
|
||||||
'type': methodName,
|
|
||||||
'id': id,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
factory TagIdQuery.fromJson(Map<String, dynamic> json) {
|
|
||||||
final type = json['type'] as String;
|
|
||||||
var id = json['id'];
|
|
||||||
switch (type) {
|
|
||||||
case 'include':
|
|
||||||
return IncludeTagIdQuery(id);
|
|
||||||
case 'exclude':
|
|
||||||
return ExcludeTagIdQuery(id);
|
|
||||||
default:
|
|
||||||
throw Exception('Error parsing TagIdQuery: Unknown type $type');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
export 'any_assigned_tags_query.dart';
|
|
||||||
export 'ids_tags_query.dart';
|
|
||||||
export 'tags_query.dart';
|
|
||||||
export 'exclude_tag_id_query.dart';
|
|
||||||
export 'include_tag_id_query.dart';
|
|
||||||
export 'only_not_assigned_tags_query.dart';
|
|
||||||
export 'tag_id_query.dart';
|
|
||||||
@@ -1,9 +1,64 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
|
part 'tags_query.freezed.dart';
|
||||||
|
part 'tags_query.g.dart';
|
||||||
|
|
||||||
abstract class TagsQuery extends Equatable {
|
@freezed
|
||||||
const TagsQuery();
|
class TagsQuery with _$TagsQuery {
|
||||||
Map<String, String> toQueryParameter();
|
const TagsQuery._();
|
||||||
Map<String, dynamic> toJson();
|
@HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedTagsQuery)
|
||||||
|
const factory TagsQuery.notAssigned() = NotAssignedTagsQuery;
|
||||||
|
|
||||||
bool matches(Iterable<int> ids);
|
@HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedTagsQuery)
|
||||||
|
const factory TagsQuery.anyAssigned({
|
||||||
|
@Default([]) Iterable<int> tagIds,
|
||||||
|
}) = AnyAssignedTagsQuery;
|
||||||
|
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.idsTagsQuery)
|
||||||
|
const factory TagsQuery.ids({
|
||||||
|
@Default([]) Iterable<int> include,
|
||||||
|
@Default([]) Iterable<int> exclude,
|
||||||
|
}) = IdsTagsQuery;
|
||||||
|
|
||||||
|
Map<String, String> toQueryParameter() {
|
||||||
|
return when(
|
||||||
|
anyAssigned: (tagIds) {
|
||||||
|
if (tagIds.isEmpty) {
|
||||||
|
return {'is_tagged': '1'};
|
||||||
|
}
|
||||||
|
return {'tags__id__in': tagIds.join(',')};
|
||||||
|
},
|
||||||
|
ids: (include, exclude) {
|
||||||
|
final Map<String, String> params = {};
|
||||||
|
if (include.isNotEmpty) {
|
||||||
|
params.putIfAbsent('tags__id__all', () => include.join(','));
|
||||||
|
}
|
||||||
|
if (exclude.isNotEmpty) {
|
||||||
|
params.putIfAbsent('tags__id__none', () => exclude.join(','));
|
||||||
|
}
|
||||||
|
return params;
|
||||||
|
},
|
||||||
|
notAssigned: () {
|
||||||
|
return {'is_tagged': '0'};
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matches(Iterable<int> ids) {
|
||||||
|
return when(
|
||||||
|
anyAssigned: (_) => ids.isNotEmpty,
|
||||||
|
ids: (include, exclude) =>
|
||||||
|
include.toSet().difference(ids.toSet()).isEmpty &&
|
||||||
|
exclude.toSet().intersection(ids.toSet()).isEmpty,
|
||||||
|
notAssigned: () => ids.isEmpty,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
factory TagsQuery.fromJson(Map<String, dynamic> json) => _$TagsQueryFromJson(json);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,566 @@
|
|||||||
|
// coverage:ignore-file
|
||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'tags_query.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
|
||||||
|
final _privateConstructorUsedError = UnsupportedError(
|
||||||
|
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
||||||
|
|
||||||
|
TagsQuery _$TagsQueryFromJson(Map<String, dynamic> json) {
|
||||||
|
switch (json['runtimeType']) {
|
||||||
|
case 'notAssigned':
|
||||||
|
return NotAssignedTagsQuery.fromJson(json);
|
||||||
|
case 'anyAssigned':
|
||||||
|
return AnyAssignedTagsQuery.fromJson(json);
|
||||||
|
case 'ids':
|
||||||
|
return IdsTagsQuery.fromJson(json);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw CheckedFromJsonException(json, 'runtimeType', 'TagsQuery',
|
||||||
|
'Invalid union type "${json['runtimeType']}"!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$TagsQuery {
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() notAssigned,
|
||||||
|
required TResult Function(Iterable<int> tagIds) anyAssigned,
|
||||||
|
required TResult Function(Iterable<int> include, Iterable<int> exclude) ids,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? notAssigned,
|
||||||
|
TResult? Function(Iterable<int> tagIds)? anyAssigned,
|
||||||
|
TResult? Function(Iterable<int> include, Iterable<int> exclude)? ids,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? notAssigned,
|
||||||
|
TResult Function(Iterable<int> tagIds)? anyAssigned,
|
||||||
|
TResult Function(Iterable<int> include, Iterable<int> exclude)? ids,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(NotAssignedTagsQuery value) notAssigned,
|
||||||
|
required TResult Function(AnyAssignedTagsQuery value) anyAssigned,
|
||||||
|
required TResult Function(IdsTagsQuery value) ids,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(NotAssignedTagsQuery value)? notAssigned,
|
||||||
|
TResult? Function(AnyAssignedTagsQuery value)? anyAssigned,
|
||||||
|
TResult? Function(IdsTagsQuery value)? ids,
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(NotAssignedTagsQuery value)? notAssigned,
|
||||||
|
TResult Function(AnyAssignedTagsQuery value)? anyAssigned,
|
||||||
|
TResult Function(IdsTagsQuery value)? ids,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class $TagsQueryCopyWith<$Res> {
|
||||||
|
factory $TagsQueryCopyWith(TagsQuery value, $Res Function(TagsQuery) then) =
|
||||||
|
_$TagsQueryCopyWithImpl<$Res, TagsQuery>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class _$TagsQueryCopyWithImpl<$Res, $Val extends TagsQuery>
|
||||||
|
implements $TagsQueryCopyWith<$Res> {
|
||||||
|
_$TagsQueryCopyWithImpl(this._value, this._then);
|
||||||
|
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Val _value;
|
||||||
|
// ignore: unused_field
|
||||||
|
final $Res Function($Val) _then;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$NotAssignedTagsQueryCopyWith<$Res> {
|
||||||
|
factory _$$NotAssignedTagsQueryCopyWith(_$NotAssignedTagsQuery value,
|
||||||
|
$Res Function(_$NotAssignedTagsQuery) then) =
|
||||||
|
__$$NotAssignedTagsQueryCopyWithImpl<$Res>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$NotAssignedTagsQueryCopyWithImpl<$Res>
|
||||||
|
extends _$TagsQueryCopyWithImpl<$Res, _$NotAssignedTagsQuery>
|
||||||
|
implements _$$NotAssignedTagsQueryCopyWith<$Res> {
|
||||||
|
__$$NotAssignedTagsQueryCopyWithImpl(_$NotAssignedTagsQuery _value,
|
||||||
|
$Res Function(_$NotAssignedTagsQuery) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.notAssignedTagsQuery)
|
||||||
|
class _$NotAssignedTagsQuery extends NotAssignedTagsQuery {
|
||||||
|
const _$NotAssignedTagsQuery({final String? $type})
|
||||||
|
: $type = $type ?? 'notAssigned',
|
||||||
|
super._();
|
||||||
|
|
||||||
|
factory _$NotAssignedTagsQuery.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$NotAssignedTagsQueryFromJson(json);
|
||||||
|
|
||||||
|
@JsonKey(name: 'runtimeType')
|
||||||
|
final String $type;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TagsQuery.notAssigned()';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType && other is _$NotAssignedTagsQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => runtimeType.hashCode;
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() notAssigned,
|
||||||
|
required TResult Function(Iterable<int> tagIds) anyAssigned,
|
||||||
|
required TResult Function(Iterable<int> include, Iterable<int> exclude) ids,
|
||||||
|
}) {
|
||||||
|
return notAssigned();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? notAssigned,
|
||||||
|
TResult? Function(Iterable<int> tagIds)? anyAssigned,
|
||||||
|
TResult? Function(Iterable<int> include, Iterable<int> exclude)? ids,
|
||||||
|
}) {
|
||||||
|
return notAssigned?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? notAssigned,
|
||||||
|
TResult Function(Iterable<int> tagIds)? anyAssigned,
|
||||||
|
TResult Function(Iterable<int> include, Iterable<int> exclude)? ids,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (notAssigned != null) {
|
||||||
|
return notAssigned();
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(NotAssignedTagsQuery value) notAssigned,
|
||||||
|
required TResult Function(AnyAssignedTagsQuery value) anyAssigned,
|
||||||
|
required TResult Function(IdsTagsQuery value) ids,
|
||||||
|
}) {
|
||||||
|
return notAssigned(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(NotAssignedTagsQuery value)? notAssigned,
|
||||||
|
TResult? Function(AnyAssignedTagsQuery value)? anyAssigned,
|
||||||
|
TResult? Function(IdsTagsQuery value)? ids,
|
||||||
|
}) {
|
||||||
|
return notAssigned?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(NotAssignedTagsQuery value)? notAssigned,
|
||||||
|
TResult Function(AnyAssignedTagsQuery value)? anyAssigned,
|
||||||
|
TResult Function(IdsTagsQuery value)? ids,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (notAssigned != null) {
|
||||||
|
return notAssigned(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$NotAssignedTagsQueryToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class NotAssignedTagsQuery extends TagsQuery {
|
||||||
|
const factory NotAssignedTagsQuery() = _$NotAssignedTagsQuery;
|
||||||
|
const NotAssignedTagsQuery._() : super._();
|
||||||
|
|
||||||
|
factory NotAssignedTagsQuery.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$NotAssignedTagsQuery.fromJson;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$AnyAssignedTagsQueryCopyWith<$Res> {
|
||||||
|
factory _$$AnyAssignedTagsQueryCopyWith(_$AnyAssignedTagsQuery value,
|
||||||
|
$Res Function(_$AnyAssignedTagsQuery) then) =
|
||||||
|
__$$AnyAssignedTagsQueryCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({Iterable<int> tagIds});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$AnyAssignedTagsQueryCopyWithImpl<$Res>
|
||||||
|
extends _$TagsQueryCopyWithImpl<$Res, _$AnyAssignedTagsQuery>
|
||||||
|
implements _$$AnyAssignedTagsQueryCopyWith<$Res> {
|
||||||
|
__$$AnyAssignedTagsQueryCopyWithImpl(_$AnyAssignedTagsQuery _value,
|
||||||
|
$Res Function(_$AnyAssignedTagsQuery) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? tagIds = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$AnyAssignedTagsQuery(
|
||||||
|
tagIds: null == tagIds
|
||||||
|
? _value.tagIds
|
||||||
|
: tagIds // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Iterable<int>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.anyAssignedTagsQuery)
|
||||||
|
class _$AnyAssignedTagsQuery extends AnyAssignedTagsQuery {
|
||||||
|
const _$AnyAssignedTagsQuery({this.tagIds = const [], final String? $type})
|
||||||
|
: $type = $type ?? 'anyAssigned',
|
||||||
|
super._();
|
||||||
|
|
||||||
|
factory _$AnyAssignedTagsQuery.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$AnyAssignedTagsQueryFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final Iterable<int> tagIds;
|
||||||
|
|
||||||
|
@JsonKey(name: 'runtimeType')
|
||||||
|
final String $type;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TagsQuery.anyAssigned(tagIds: $tagIds)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$AnyAssignedTagsQuery &&
|
||||||
|
const DeepCollectionEquality().equals(other.tagIds, tagIds));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode =>
|
||||||
|
Object.hash(runtimeType, const DeepCollectionEquality().hash(tagIds));
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$AnyAssignedTagsQueryCopyWith<_$AnyAssignedTagsQuery> get copyWith =>
|
||||||
|
__$$AnyAssignedTagsQueryCopyWithImpl<_$AnyAssignedTagsQuery>(
|
||||||
|
this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() notAssigned,
|
||||||
|
required TResult Function(Iterable<int> tagIds) anyAssigned,
|
||||||
|
required TResult Function(Iterable<int> include, Iterable<int> exclude) ids,
|
||||||
|
}) {
|
||||||
|
return anyAssigned(tagIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? notAssigned,
|
||||||
|
TResult? Function(Iterable<int> tagIds)? anyAssigned,
|
||||||
|
TResult? Function(Iterable<int> include, Iterable<int> exclude)? ids,
|
||||||
|
}) {
|
||||||
|
return anyAssigned?.call(tagIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? notAssigned,
|
||||||
|
TResult Function(Iterable<int> tagIds)? anyAssigned,
|
||||||
|
TResult Function(Iterable<int> include, Iterable<int> exclude)? ids,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (anyAssigned != null) {
|
||||||
|
return anyAssigned(tagIds);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(NotAssignedTagsQuery value) notAssigned,
|
||||||
|
required TResult Function(AnyAssignedTagsQuery value) anyAssigned,
|
||||||
|
required TResult Function(IdsTagsQuery value) ids,
|
||||||
|
}) {
|
||||||
|
return anyAssigned(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(NotAssignedTagsQuery value)? notAssigned,
|
||||||
|
TResult? Function(AnyAssignedTagsQuery value)? anyAssigned,
|
||||||
|
TResult? Function(IdsTagsQuery value)? ids,
|
||||||
|
}) {
|
||||||
|
return anyAssigned?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(NotAssignedTagsQuery value)? notAssigned,
|
||||||
|
TResult Function(AnyAssignedTagsQuery value)? anyAssigned,
|
||||||
|
TResult Function(IdsTagsQuery value)? ids,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (anyAssigned != null) {
|
||||||
|
return anyAssigned(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$AnyAssignedTagsQueryToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class AnyAssignedTagsQuery extends TagsQuery {
|
||||||
|
const factory AnyAssignedTagsQuery({final Iterable<int> tagIds}) =
|
||||||
|
_$AnyAssignedTagsQuery;
|
||||||
|
const AnyAssignedTagsQuery._() : super._();
|
||||||
|
|
||||||
|
factory AnyAssignedTagsQuery.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$AnyAssignedTagsQuery.fromJson;
|
||||||
|
|
||||||
|
Iterable<int> get tagIds;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$AnyAssignedTagsQueryCopyWith<_$AnyAssignedTagsQuery> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract class _$$IdsTagsQueryCopyWith<$Res> {
|
||||||
|
factory _$$IdsTagsQueryCopyWith(
|
||||||
|
_$IdsTagsQuery value, $Res Function(_$IdsTagsQuery) then) =
|
||||||
|
__$$IdsTagsQueryCopyWithImpl<$Res>;
|
||||||
|
@useResult
|
||||||
|
$Res call({Iterable<int> include, Iterable<int> exclude});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
class __$$IdsTagsQueryCopyWithImpl<$Res>
|
||||||
|
extends _$TagsQueryCopyWithImpl<$Res, _$IdsTagsQuery>
|
||||||
|
implements _$$IdsTagsQueryCopyWith<$Res> {
|
||||||
|
__$$IdsTagsQueryCopyWithImpl(
|
||||||
|
_$IdsTagsQuery _value, $Res Function(_$IdsTagsQuery) _then)
|
||||||
|
: super(_value, _then);
|
||||||
|
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
@override
|
||||||
|
$Res call({
|
||||||
|
Object? include = null,
|
||||||
|
Object? exclude = null,
|
||||||
|
}) {
|
||||||
|
return _then(_$IdsTagsQuery(
|
||||||
|
include: null == include
|
||||||
|
? _value.include
|
||||||
|
: include // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Iterable<int>,
|
||||||
|
exclude: null == exclude
|
||||||
|
? _value.exclude
|
||||||
|
: exclude // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Iterable<int>,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
@JsonSerializable()
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.idsTagsQuery)
|
||||||
|
class _$IdsTagsQuery extends IdsTagsQuery {
|
||||||
|
const _$IdsTagsQuery(
|
||||||
|
{this.include = const [], this.exclude = const [], final String? $type})
|
||||||
|
: $type = $type ?? 'ids',
|
||||||
|
super._();
|
||||||
|
|
||||||
|
factory _$IdsTagsQuery.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$$IdsTagsQueryFromJson(json);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final Iterable<int> include;
|
||||||
|
@override
|
||||||
|
@JsonKey()
|
||||||
|
final Iterable<int> exclude;
|
||||||
|
|
||||||
|
@JsonKey(name: 'runtimeType')
|
||||||
|
final String $type;
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'TagsQuery.ids(include: $include, exclude: $exclude)';
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(dynamic other) {
|
||||||
|
return identical(this, other) ||
|
||||||
|
(other.runtimeType == runtimeType &&
|
||||||
|
other is _$IdsTagsQuery &&
|
||||||
|
const DeepCollectionEquality().equals(other.include, include) &&
|
||||||
|
const DeepCollectionEquality().equals(other.exclude, exclude));
|
||||||
|
}
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(
|
||||||
|
runtimeType,
|
||||||
|
const DeepCollectionEquality().hash(include),
|
||||||
|
const DeepCollectionEquality().hash(exclude));
|
||||||
|
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
@override
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$$IdsTagsQueryCopyWith<_$IdsTagsQuery> get copyWith =>
|
||||||
|
__$$IdsTagsQueryCopyWithImpl<_$IdsTagsQuery>(this, _$identity);
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult when<TResult extends Object?>({
|
||||||
|
required TResult Function() notAssigned,
|
||||||
|
required TResult Function(Iterable<int> tagIds) anyAssigned,
|
||||||
|
required TResult Function(Iterable<int> include, Iterable<int> exclude) ids,
|
||||||
|
}) {
|
||||||
|
return ids(include, exclude);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? whenOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function()? notAssigned,
|
||||||
|
TResult? Function(Iterable<int> tagIds)? anyAssigned,
|
||||||
|
TResult? Function(Iterable<int> include, Iterable<int> exclude)? ids,
|
||||||
|
}) {
|
||||||
|
return ids?.call(include, exclude);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeWhen<TResult extends Object?>({
|
||||||
|
TResult Function()? notAssigned,
|
||||||
|
TResult Function(Iterable<int> tagIds)? anyAssigned,
|
||||||
|
TResult Function(Iterable<int> include, Iterable<int> exclude)? ids,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (ids != null) {
|
||||||
|
return ids(include, exclude);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult map<TResult extends Object?>({
|
||||||
|
required TResult Function(NotAssignedTagsQuery value) notAssigned,
|
||||||
|
required TResult Function(AnyAssignedTagsQuery value) anyAssigned,
|
||||||
|
required TResult Function(IdsTagsQuery value) ids,
|
||||||
|
}) {
|
||||||
|
return ids(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult? mapOrNull<TResult extends Object?>({
|
||||||
|
TResult? Function(NotAssignedTagsQuery value)? notAssigned,
|
||||||
|
TResult? Function(AnyAssignedTagsQuery value)? anyAssigned,
|
||||||
|
TResult? Function(IdsTagsQuery value)? ids,
|
||||||
|
}) {
|
||||||
|
return ids?.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
@optionalTypeArgs
|
||||||
|
TResult maybeMap<TResult extends Object?>({
|
||||||
|
TResult Function(NotAssignedTagsQuery value)? notAssigned,
|
||||||
|
TResult Function(AnyAssignedTagsQuery value)? anyAssigned,
|
||||||
|
TResult Function(IdsTagsQuery value)? ids,
|
||||||
|
required TResult orElse(),
|
||||||
|
}) {
|
||||||
|
if (ids != null) {
|
||||||
|
return ids(this);
|
||||||
|
}
|
||||||
|
return orElse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
|
return _$$IdsTagsQueryToJson(
|
||||||
|
this,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class IdsTagsQuery extends TagsQuery {
|
||||||
|
const factory IdsTagsQuery(
|
||||||
|
{final Iterable<int> include,
|
||||||
|
final Iterable<int> exclude}) = _$IdsTagsQuery;
|
||||||
|
const IdsTagsQuery._() : super._();
|
||||||
|
|
||||||
|
factory IdsTagsQuery.fromJson(Map<String, dynamic> json) =
|
||||||
|
_$IdsTagsQuery.fromJson;
|
||||||
|
|
||||||
|
Iterable<int> get include;
|
||||||
|
Iterable<int> get exclude;
|
||||||
|
@JsonKey(ignore: true)
|
||||||
|
_$$IdsTagsQueryCopyWith<_$IdsTagsQuery> get copyWith =>
|
||||||
|
throw _privateConstructorUsedError;
|
||||||
|
}
|
||||||
@@ -1,13 +1,18 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
|
import 'package:hive/hive.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:paperless_api/config/hive/hive_type_ids.dart';
|
||||||
|
|
||||||
import 'query_type.dart';
|
import 'query_type.dart';
|
||||||
|
|
||||||
part 'text_query.g.dart';
|
part 'text_query.g.dart';
|
||||||
|
|
||||||
|
@HiveType(typeId: PaperlessApiHiveTypeIds.textQuery)
|
||||||
@JsonSerializable()
|
@JsonSerializable()
|
||||||
class TextQuery extends Equatable {
|
class TextQuery extends Equatable {
|
||||||
|
@HiveField(0)
|
||||||
final QueryType queryType;
|
final QueryType queryType;
|
||||||
|
@HiveField(1)
|
||||||
final String? queryText;
|
final String? queryText;
|
||||||
|
|
||||||
const TextQuery({
|
const TextQuery({
|
||||||
@@ -17,8 +22,7 @@ class TextQuery extends Equatable {
|
|||||||
|
|
||||||
const TextQuery.title(this.queryText) : queryType = QueryType.title;
|
const TextQuery.title(this.queryText) : queryType = QueryType.title;
|
||||||
|
|
||||||
const TextQuery.titleAndContent(this.queryText)
|
const TextQuery.titleAndContent(this.queryText) : queryType = QueryType.titleAndContent;
|
||||||
: queryType = QueryType.titleAndContent;
|
|
||||||
|
|
||||||
const TextQuery.extended(this.queryText) : queryType = QueryType.extended;
|
const TextQuery.extended(this.queryText) : queryType = QueryType.extended;
|
||||||
|
|
||||||
@@ -68,8 +72,7 @@ class TextQuery extends Equatable {
|
|||||||
case QueryType.title:
|
case QueryType.title:
|
||||||
return title.contains(queryText!);
|
return title.contains(queryText!);
|
||||||
case QueryType.titleAndContent:
|
case QueryType.titleAndContent:
|
||||||
return title.contains(queryText!) ||
|
return title.contains(queryText!) || (content?.contains(queryText!) ?? false);
|
||||||
(content?.contains(queryText!) ?? false);
|
|
||||||
case QueryType.extended:
|
case QueryType.extended:
|
||||||
//TODO: Implement. Might be too complex...
|
//TODO: Implement. Might be too complex...
|
||||||
return true;
|
return true;
|
||||||
@@ -80,8 +83,7 @@ class TextQuery extends Equatable {
|
|||||||
|
|
||||||
Map<String, dynamic> toJson() => _$TextQueryToJson(this);
|
Map<String, dynamic> toJson() => _$TextQueryToJson(this);
|
||||||
|
|
||||||
factory TextQuery.fromJson(Map<String, dynamic> json) =>
|
factory TextQuery.fromJson(Map<String, dynamic> json) => _$TextQueryFromJson(json);
|
||||||
_$TextQueryFromJson(json);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<Object?> get props => [queryType, queryText];
|
List<Object?> get props => [queryType, queryText];
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_api/src/models/query_parameters/tags_query/include_tag_id_query.dart';
|
|
||||||
import 'package:paperless_api/src/models/query_parameters/text_query.dart';
|
import 'package:paperless_api/src/models/query_parameters/text_query.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@@ -70,13 +69,9 @@ void main() {
|
|||||||
correspondent: const IdQueryParameter.fromId(42),
|
correspondent: const IdQueryParameter.fromId(42),
|
||||||
documentType: const IdQueryParameter.fromId(69),
|
documentType: const IdQueryParameter.fromId(69),
|
||||||
storagePath: const IdQueryParameter.fromId(14),
|
storagePath: const IdQueryParameter.fromId(14),
|
||||||
tags: const IdsTagsQuery(
|
tags: const TagsQuery.ids(
|
||||||
[
|
include: [1, 2],
|
||||||
IncludeTagIdQuery(1),
|
exclude: [3, 4],
|
||||||
IncludeTagIdQuery(2),
|
|
||||||
ExcludeTagIdQuery(3),
|
|
||||||
ExcludeTagIdQuery(4),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
created: AbsoluteDateRangeQuery(
|
created: AbsoluteDateRangeQuery(
|
||||||
before: DateTime.parse("2022-10-27"),
|
before: DateTime.parse("2022-10-27"),
|
||||||
@@ -140,7 +135,7 @@ void main() {
|
|||||||
correspondent: const IdQueryParameter.notAssigned(),
|
correspondent: const IdQueryParameter.notAssigned(),
|
||||||
documentType: const IdQueryParameter.notAssigned(),
|
documentType: const IdQueryParameter.notAssigned(),
|
||||||
storagePath: const IdQueryParameter.notAssigned(),
|
storagePath: const IdQueryParameter.notAssigned(),
|
||||||
tags: const OnlyNotAssignedTagsQuery(),
|
tags: const TagsQuery.notAssigned(),
|
||||||
);
|
);
|
||||||
expect(
|
expect(
|
||||||
actual,
|
actual,
|
||||||
@@ -157,13 +152,10 @@ void main() {
|
|||||||
correspondent: const IdQueryParameter.fromId(1),
|
correspondent: const IdQueryParameter.fromId(1),
|
||||||
documentType: const IdQueryParameter.fromId(2),
|
documentType: const IdQueryParameter.fromId(2),
|
||||||
storagePath: const IdQueryParameter.fromId(3),
|
storagePath: const IdQueryParameter.fromId(3),
|
||||||
tags: const IdsTagsQuery([
|
tags: const TagsQuery.ids(
|
||||||
IncludeTagIdQuery(4),
|
include: [4, 5],
|
||||||
IncludeTagIdQuery(5),
|
exclude: [6, 7, 8],
|
||||||
ExcludeTagIdQuery(6),
|
),
|
||||||
ExcludeTagIdQuery(7),
|
|
||||||
ExcludeTagIdQuery(8),
|
|
||||||
]),
|
|
||||||
sortField: SortField.added,
|
sortField: SortField.added,
|
||||||
sortOrder: SortOrder.ascending,
|
sortOrder: SortOrder.ascending,
|
||||||
created: AbsoluteDateRangeQuery(
|
created: AbsoluteDateRangeQuery(
|
||||||
@@ -241,11 +233,11 @@ void main() {
|
|||||||
test('Values are correctly parsed if not assigned.', () {
|
test('Values are correctly parsed if not assigned.', () {
|
||||||
expect(
|
expect(
|
||||||
SavedView.fromDocumentFilter(
|
SavedView.fromDocumentFilter(
|
||||||
DocumentFilter(
|
const DocumentFilter(
|
||||||
correspondent: const IdQueryParameter.notAssigned(),
|
correspondent: IdQueryParameter.notAssigned(),
|
||||||
documentType: const IdQueryParameter.notAssigned(),
|
documentType: IdQueryParameter.notAssigned(),
|
||||||
storagePath: const IdQueryParameter.notAssigned(),
|
storagePath: IdQueryParameter.notAssigned(),
|
||||||
tags: const OnlyNotAssignedTagsQuery(),
|
tags: TagsQuery.notAssigned(),
|
||||||
sortField: SortField.created,
|
sortField: SortField.created,
|
||||||
sortOrder: SortOrder.ascending,
|
sortOrder: SortOrder.ascending,
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user