Fixed FABs stacking on form fields, some other minor improvements

This commit is contained in:
Anton Stubenbord
2022-11-01 23:29:16 +01:00
parent f522991059
commit b4e5bf06b2
14 changed files with 313 additions and 279 deletions

View File

@@ -43,15 +43,14 @@ class CorrespondentWidget extends StatelessWidget {
}
void _addCorrespondentToFilter(BuildContext context) {
final cubit = getIt<DocumentsCubit>();
final cubit = BlocProvider.of<DocumentsCubit>(context);
if (cubit.state.filter.correspondent.id == correspondentId) {
cubit.updateFilter(
filter: cubit.state.filter.copyWith(correspondent: const CorrespondentQuery.unset()));
cubit.updateCurrentFilter(
(filter) => filter.copyWith(correspondent: const CorrespondentQuery.unset()),
);
} else {
cubit.updateFilter(
filter: cubit.state.filter.copyWith(
correspondent: CorrespondentQuery.fromId(correspondentId),
),
cubit.updateCurrentFilter(
(filter) => filter.copyWith(correspondent: CorrespondentQuery.fromId(correspondentId)),
);
}
afterSelected?.call();

View File

@@ -1,52 +1,53 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_paperless_mobile/di_initializer.dart';
import 'package:flutter_paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:flutter_paperless_mobile/features/documents/model/query_parameters/document_type_query.dart';
import 'package:flutter_paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart';
import 'package:flutter_paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:flutter_paperless_mobile/features/labels/document_type/model/document_type.model.dart';
class DocumentTypeWidget extends StatelessWidget {
final int? documentTypeId;
final void Function()? afterSelected;
final bool isSelectable;
const DocumentTypeWidget({
Key? key,
required this.documentTypeId,
this.afterSelected,
this.isSelectable = true,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: _addDocumentTypeToFilter,
child: BlocBuilder<DocumentTypeCubit, Map<int, DocumentType>>(
builder: (context, state) {
return Text(
state[documentTypeId]?.toString() ?? "-",
style: Theme.of(context)
.textTheme
.bodyText2!
.copyWith(color: Theme.of(context).colorScheme.primary),
);
},
return AbsorbPointer(
absorbing: !isSelectable,
child: GestureDetector(
onTap: () => _addDocumentTypeToFilter(context),
child: BlocBuilder<DocumentTypeCubit, Map<int, DocumentType>>(
builder: (context, state) {
return Text(
state[documentTypeId]?.toString() ?? "-",
style: Theme.of(context)
.textTheme
.bodyText2!
.copyWith(color: Theme.of(context).colorScheme.tertiary),
);
},
),
),
);
}
void _addDocumentTypeToFilter() {
final cubit = getIt<DocumentsCubit>();
void _addDocumentTypeToFilter(BuildContext context) {
final cubit = BlocProvider.of<DocumentsCubit>(context);
if (cubit.state.filter.documentType.id == documentTypeId) {
cubit.updateFilter(
filter: cubit.state.filter.copyWith(documentType: const DocumentTypeQuery.unset()));
cubit.updateCurrentFilter(
(filter) => filter.copyWith(documentType: const DocumentTypeQuery.unset()),
);
} else {
cubit.updateFilter(
filter: cubit.state.filter.copyWith(
documentType: DocumentTypeQuery.fromId(documentTypeId),
),
cubit.updateCurrentFilter(
(filter) => filter.copyWith(documentType: DocumentTypeQuery.fromId(documentTypeId)),
);
}
if (afterSelected != null) {
afterSelected?.call();
}
afterSelected?.call();
}
}

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_paperless_mobile/di_initializer.dart';
import 'package:flutter_paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:flutter_paperless_mobile/features/documents/model/query_parameters/storage_path_query.dart';
import 'package:flutter_paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart';
@@ -43,15 +42,14 @@ class StoragePathWidget extends StatelessWidget {
}
void _addStoragePathToFilter(BuildContext context) {
final cubit = getIt<DocumentsCubit>();
final cubit = BlocProvider.of<DocumentsCubit>(context);
if (cubit.state.filter.correspondent.id == pathId) {
cubit.updateFilter(
filter: cubit.state.filter.copyWith(storagePath: const StoragePathQuery.unset()));
cubit.updateCurrentFilter(
(filter) => filter.copyWith(storagePath: const StoragePathQuery.unset()),
);
} else {
cubit.updateFilter(
filter: cubit.state.filter.copyWith(
storagePath: StoragePathQuery.fromId(pathId),
),
cubit.updateCurrentFilter(
(filter) => filter.copyWith(storagePath: StoragePathQuery.fromId(pathId)),
);
}
afterSelected?.call();

View File

@@ -50,12 +50,16 @@ class EditTagPage extends StatelessWidget {
late DocumentFilter updatedFilter = currentFilter;
if (currentFilter.tags.ids.contains(tag.id)) {
updatedFilter = currentFilter.copyWith(
tags: TagsQuery.fromIds(
currentFilter.tags.ids.where((tagId) => tagId != tag.id).toList()));
tags: TagsQuery.fromIds(
currentFilter.tags.ids.where((tagId) => tagId != tag.id).toList(),
),
);
}
cubit.updateFilter(filter: updatedFilter);
} on ErrorMessage catch (error) {
showError(context, error);
} finally {
Navigator.pop(context);
}
}
}

View File

@@ -5,7 +5,6 @@ import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_paperless_mobile/core/bloc/label_cubit.dart';
import 'package:flutter_paperless_mobile/core/logic/error_code_localization_mapper.dart';
import 'package:flutter_paperless_mobile/core/model/error_message.dart';
import 'package:flutter_paperless_mobile/core/type/json.dart';
import 'package:flutter_paperless_mobile/extensions/flutter_extensions.dart';
import 'package:flutter_paperless_mobile/features/labels/document_type/model/matching_algorithm.dart';
import 'package:flutter_paperless_mobile/features/labels/model/label.model.dart';
@@ -40,14 +39,17 @@ class _AddLabelPageState<T extends Label> extends State<AddLabelPage<T>> {
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Text(widget.addLabelStr),
),
floatingActionButton: FloatingActionButton.extended(
icon: const Icon(Icons.add),
label: Text(S.of(context).genericActionCreateLabel),
onPressed: _onSubmit,
floatingActionButton: Visibility(
visible: MediaQuery.of(context).viewInsets.bottom == 0,
child: FloatingActionButton.extended(
icon: const Icon(Icons.add),
label: Text(S.of(context).genericActionCreateLabel),
onPressed: _onSubmit,
),
),
body: FormBuilder(
key: _formKey,
@@ -99,7 +101,6 @@ class _AddLabelPageState<T extends Label> extends State<AddLabelPage<T>> {
}
void _onSubmit() async {
log("IsValid? ${_formKey.currentState?.isValid}");
if (_formKey.currentState?.saveAndValidate() ?? false) {
try {
final label = await widget.cubit.add(widget.fromJson(_formKey.currentState!.value));

View File

@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:flutter_paperless_mobile/features/documents/model/query_parameters/correspondent_query.dart';
import 'package:flutter_paperless_mobile/features/documents/model/query_parameters/id_query_parameter.dart';
import 'package:flutter_paperless_mobile/features/labels/correspondent/model/correspondent.model.dart';
import 'package:flutter_paperless_mobile/features/labels/document_type/model/document_type.model.dart';
@@ -9,7 +10,7 @@ import 'package:form_builder_extra_fields/form_builder_extra_fields.dart';
///
/// Form field allowing to select labels (i.e. correspondent, documentType)
/// [T] is the label (model) type, [R] is the return type.
/// [T] is the label type (e.g. [DocumentType], [Correspondent], ...), [R] is the return type (e.g. [CorrespondentQuery], ...).
///
class LabelFormField<T extends Label, R extends IdQueryParameter> extends StatefulWidget {
final Widget prefixIcon;
@@ -23,6 +24,7 @@ class LabelFormField<T extends Label, R extends IdQueryParameter> extends Statef
final R Function() queryParameterNotAssignedBuilder;
final R Function(int? id) queryParameterIdBuilder;
final bool notAssignedSelectable;
final void Function(R?)? onChanged;
const LabelFormField({
Key? key,
@@ -37,6 +39,7 @@ class LabelFormField<T extends Label, R extends IdQueryParameter> extends Statef
required this.formBuilderState,
required this.prefixIcon,
this.notAssignedSelectable = true,
this.onChanged,
}) : super(key: key);
@override
@@ -71,6 +74,14 @@ class _LabelFormFieldState<T extends Label, R extends IdQueryParameter>
@override
Widget build(BuildContext context) {
return FormBuilderTypeAhead<IdQueryParameter>(
noItemsFoundBuilder: (context) => Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Text(
S.of(context).labelFormFieldNoItemsFoundText,
textAlign: TextAlign.center,
style: TextStyle(color: Theme.of(context).disabledColor, fontSize: 18.0),
),
),
initialValue: widget.initialValue ?? widget.queryParameterIdBuilder(null),
name: widget.name,
itemBuilder: (context, suggestion) => ListTile(
@@ -90,6 +101,7 @@ class _LabelFormFieldState<T extends Label, R extends IdQueryParameter>
},
onChanged: (value) {
setState(() => _showClearSuffixIcon = value?.isSet ?? false);
widget.onChanged?.call(value as R);
},
controller: _textEditingController,
decoration: InputDecoration(