diff --git a/lib/core/widgets/form_builder_fields/extended_date_range_dialog.dart b/lib/core/widgets/form_builder_fields/extended_date_range_form_field/extended_date_range_dialog.dart similarity index 69% rename from lib/core/widgets/form_builder_fields/extended_date_range_dialog.dart rename to lib/core/widgets/form_builder_fields/extended_date_range_form_field/extended_date_range_dialog.dart index 49abee3..d6e4f8e 100644 --- a/lib/core/widgets/form_builder_fields/extended_date_range_dialog.dart +++ b/lib/core/widgets/form_builder_fields/extended_date_range_form_field/extended_date_range_dialog.dart @@ -1,19 +1,22 @@ +import 'dart:developer'; +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:intl/intl.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/widgets/form_builder_fields/form_builder_relative_date_range_field.dart'; +import 'package:paperless_mobile/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_relative_date_range_field.dart'; import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart'; class ExtendedDateRangeDialog extends StatefulWidget { final DateRangeQuery initialValue; - final String Function(DateRangeQuery query) stringTransformer; + const ExtendedDateRangeDialog({ super.key, required this.initialValue, - required this.stringTransformer, }); @override @@ -26,12 +29,21 @@ class _ExtendedDateRangeDialogState extends State { static const String _fkAbsoluteAfter = 'absoluteAfter'; static const String _fkRelative = 'relative'; + DateTime? _before; + DateTime? _after; + final _formKey = GlobalKey(); late DateRangeType _selectedDateRangeType; + @override void initState() { super.initState(); - _selectedDateRangeType = (widget.initialValue is RelativeDateRangeQuery) + final initialQuery = widget.initialValue; + if (initialQuery is AbsoluteDateRangeQuery) { + _before = initialQuery.before; + _after = initialQuery.after; + } + _selectedDateRangeType = (initialQuery is RelativeDateRangeQuery) ? DateRangeType.relative : DateRangeType.absolute; } @@ -40,13 +52,13 @@ class _ExtendedDateRangeDialogState extends State { Widget build(BuildContext context) { return AlertDialog( title: Text("Select date range"), - content: Form( + content: FormBuilder( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( - "Hint: You can either specify absolute values by selecting concrete dates, or you can specify a time range relative to today.", + "Hint: You can either specify absolute values by selecting concrete dates, or you can specify a time range relative to the current date.", style: Theme.of(context).textTheme.caption, ), _buildDateRangeQueryTypeSelection(), @@ -58,6 +70,7 @@ class _ExtendedDateRangeDialogState extends State { return _buildAbsoluteDateRangeForm(); case DateRangeType.relative: return FormBuilderRelativeDateRangePicker( + name: _fkRelative, initialValue: widget.initialValue is RelativeDateRangeQuery ? widget.initialValue as RelativeDateRangeQuery @@ -65,7 +78,6 @@ class _ExtendedDateRangeDialogState extends State { 1, DateRangeUnit.month, ), - name: _fkRelative, ); } }, @@ -118,23 +130,58 @@ class _ExtendedDateRangeDialogState extends State { children: [ FormBuilderDateTimePicker( name: _fkAbsoluteAfter, - initialDate: widget.initialValue is AbsoluteDateRangeQuery + initialValue: widget.initialValue is AbsoluteDateRangeQuery ? (widget.initialValue as AbsoluteDateRangeQuery).after : null, + initialDate: _before?.subtract(const Duration(days: 1)), decoration: InputDecoration( labelText: S.of(context).extendedDateRangePickerAfterLabel, + prefixIcon: const Icon(Icons.date_range), + suffixIcon: _after != null + ? IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + _formKey.currentState?.fields[_fkAbsoluteAfter] + ?.didChange(null); + setState(() => _after = null); + }, + ) + : null, ), + format: DateFormat.yMd(), + lastDate: _dateTimeMax(_before, DateTime.now()), inputType: InputType.date, + onChanged: (after) { + setState(() => _after = after); + }, ), + const SizedBox(height: 16), FormBuilderDateTimePicker( name: _fkAbsoluteBefore, - initialDate: widget.initialValue is AbsoluteDateRangeQuery + initialValue: widget.initialValue is AbsoluteDateRangeQuery ? (widget.initialValue as AbsoluteDateRangeQuery).before : null, inputType: InputType.date, decoration: InputDecoration( labelText: S.of(context).extendedDateRangePickerBeforeLabel, + prefixIcon: const Icon(Icons.date_range), + suffixIcon: _before != null + ? IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + _formKey.currentState?.fields[_fkAbsoluteBefore] + ?.didChange(null); + setState(() => _before = null); + }, + ) + : null, ), + format: DateFormat.yMd(), + firstDate: _after, + lastDate: DateTime.now(), + onChanged: (before) { + setState(() => _before = before); + }, ), ], ); @@ -150,6 +197,12 @@ class _ExtendedDateRangeDialogState extends State { return values[_fkRelative] as RelativeDateRangeQuery; } } + + DateTime? _dateTimeMax(DateTime? dt1, DateTime? dt2) { + if (dt1 == null) return dt2; + if (dt2 == null) return dt1; + return dt1.compareTo(dt2) >= 0 ? dt1 : dt2; + } } enum DateRangeType { diff --git a/lib/core/widgets/form_builder_fields/form_builder_extended_date_range_picker.dart b/lib/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_extended_date_range_picker.dart similarity index 57% rename from lib/core/widgets/form_builder_fields/form_builder_extended_date_range_picker.dart rename to lib/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_extended_date_range_picker.dart index f3a3201..690e615 100644 --- a/lib/core/widgets/form_builder_fields/form_builder_extended_date_range_picker.dart +++ b/lib/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_extended_date_range_picker.dart @@ -2,7 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:intl/intl.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/widgets/form_builder_fields/extended_date_range_dialog.dart'; +import 'package:paperless_mobile/core/widgets/form_builder_fields/extended_date_range_form_field/extended_date_range_dialog.dart'; +import 'package:paperless_mobile/core/widgets/form_builder_fields/extended_date_range_form_field/relative_date_range_picker_helper.dart'; import 'package:paperless_mobile/generated/l10n.dart'; class FormBuilderExtendedDateRangePicker extends StatefulWidget { @@ -24,13 +25,13 @@ class FormBuilderExtendedDateRangePicker extends StatefulWidget { class _FormBuilderExtendedDateRangePickerState extends State { - late final TextEditingController _textEditingController; + final TextEditingController _textEditingController = TextEditingController(); @override - void initState() { - super.initState(); - _textEditingController = TextEditingController( - text: _dateRangeQueryToString(widget.initialValue)); + void didChangeDependencies() { + super.didChangeDependencies(); + // This has to be initialized here and not in initState because it has to be waited until dependencies for localization have been loaded. + _textEditingController.text = _dateRangeQueryToString(widget.initialValue); } @override @@ -52,67 +53,39 @@ class _FormBuilderExtendedDateRangePickerState decoration: InputDecoration( prefixIcon: const Icon(Icons.date_range), labelText: widget.labelText, + suffixIcon: _textEditingController.text.isNotEmpty + ? IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + field.didChange(const UnsetDateRangeQuery()); + }, + ) + : null, ), ), - _buildExtendedQueryOptions(field), + RelativeDateRangePickerHelper(field: field), ], ); }, ); } - Widget _buildExtendedQueryOptions(FormFieldState field) { - return SizedBox( - height: 64, - child: ListView.separated( - itemCount: _options.length, - separatorBuilder: (context, index) => const SizedBox(width: 8.0), - itemBuilder: (context, index) { - final option = _options[index]; - return FilterChip( - label: Text(option.title), - onSelected: (isSelected) => isSelected - ? field.didChange(option.value) - : field.didChange(const UnsetDateRangeQuery()), - selected: field.value == option.value, - ); - }, - scrollDirection: Axis.horizontal, - ), - ); - } - - List<_ExtendedDateRangeQueryOption> get _options => [ - _ExtendedDateRangeQueryOption( - S.of(context).extendedDateRangePickerLastWeeksLabel(1), - const RelativeDateRangeQuery(1, DateRangeUnit.week), - ), - _ExtendedDateRangeQueryOption( - S.of(context).extendedDateRangePickerLastMonthsLabel(1), - const RelativeDateRangeQuery(1, DateRangeUnit.month), - ), - _ExtendedDateRangeQueryOption( - S.of(context).extendedDateRangePickerLastMonthsLabel(3), - const RelativeDateRangeQuery(3, DateRangeUnit.month), - ), - _ExtendedDateRangeQueryOption( - S.of(context).extendedDateRangePickerLastYearsLabel(1), - const RelativeDateRangeQuery(1, DateRangeUnit.year), - ), - ]; - String _dateRangeQueryToString(DateRangeQuery query) { + final df = DateFormat.yMd(); if (query is UnsetDateRangeQuery) { return ''; } else if (query is AbsoluteDateRangeQuery) { if (query.before != null && query.after != null) { - return '${DateFormat.yMd(query.after)} – ${DateFormat.yMd(query.before)}'; + if (query.before!.isAtSameMomentAs(query.after!)) { + return df.format(query.before!); + } + return '${df.format(query.after!)} – ${df.format(query.before!)}'; } if (query.before != null) { - return '${S.of(context).extendedDateRangePickerBeforeLabel} ${DateFormat.yMd(query.before)}'; + return '${S.of(context).extendedDateRangePickerBeforeLabel} ${df.format(query.before!)}'; } if (query.after != null) { - return '${S.of(context).extendedDateRangePickerAfterLabel} ${DateFormat.yMd(query.after)}'; + return '${S.of(context).extendedDateRangePickerAfterLabel} ${df.format(query.after!)}'; } } else if (query is RelativeDateRangeQuery) { switch (query.unit) { @@ -143,20 +116,10 @@ class _FormBuilderExtendedDateRangePickerState ) async { final query = await showDialog( context: context, - builder: (context) => ExtendedDateRangeDialog( - initialValue: field.value!, - stringTransformer: _dateRangeQueryToString, - ), + builder: (context) => ExtendedDateRangeDialog(initialValue: field.value!), ); if (query != null) { field.didChange(query); } } } - -class _ExtendedDateRangeQueryOption { - final String title; - final RelativeDateRangeQuery value; - - _ExtendedDateRangeQueryOption(this.title, this.value); -} diff --git a/lib/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_relative_date_range_field.dart b/lib/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_relative_date_range_field.dart new file mode 100644 index 0000000..7fa235e --- /dev/null +++ b/lib/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_relative_date_range_field.dart @@ -0,0 +1,126 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:form_builder_validators/form_builder_validators.dart'; +import 'package:paperless_api/paperless_api.dart'; +import 'package:paperless_mobile/core/widgets/form_builder_fields/extended_date_range_form_field/relative_date_range_picker_helper.dart'; +import 'package:paperless_mobile/generated/l10n.dart'; + +class FormBuilderRelativeDateRangePicker extends StatefulWidget { + final String name; + final RelativeDateRangeQuery initialValue; + final void Function(RelativeDateRangeQuery? query)? onChanged; + const FormBuilderRelativeDateRangePicker({ + super.key, + required this.name, + required this.initialValue, + this.onChanged, + }); + + @override + State createState() => + _FormBuilderRelativeDateRangePickerState(); +} + +class _FormBuilderRelativeDateRangePickerState + extends State { + late int _offset; + late final TextEditingController _offsetTextEditingController; + + @override + void initState() { + super.initState(); + _offset = widget.initialValue.offset; + _offsetTextEditingController = TextEditingController( + text: widget.initialValue.offset.toString(), + ); + } + + @override + Widget build(BuildContext context) { + return FormBuilderField( + name: widget.name, + initialValue: widget.initialValue, + onChanged: widget.onChanged?.call, + builder: (field) => Column( + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text("Last"), + SizedBox( + width: 70, + child: TextFormField( + decoration: InputDecoration( + labelText: "Offset", + ), + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly, + ], + validator: FormBuilderValidators.numeric(), + keyboardType: TextInputType.number, + onChanged: (value) { + final parsed = int.tryParse(value); + if (parsed != null) { + setState(() { + _offset = parsed; + }); + field.didChange((field.value)?.copyWith(offset: parsed)); + } + }, + controller: _offsetTextEditingController, + ), + ), + SizedBox( + width: 120, + child: DropdownButtonFormField( + value: field.value?.unit, + items: DateRangeUnit.values + .map( + (unit) => DropdownMenuItem( + child: Text( + _dateRangeUnitToLocalizedString( + unit, + _offset, + ), + ), + value: unit, + ), + ) + .toList(), + onChanged: (value) => + field.didChange(field.value!.copyWith(unit: value)), + decoration: InputDecoration( + labelText: "Amount", + ), + ), + ), + ], + ), + RelativeDateRangePickerHelper( + field: field, + onChanged: (value) { + if (value is RelativeDateRangeQuery) { + setState(() => _offset = value.offset); + _offsetTextEditingController.text = _offset.toString(); + } + }, + ), + ], + ), + ); + } + + String _dateRangeUnitToLocalizedString(DateRangeUnit unit, int? count) { + switch (unit) { + case DateRangeUnit.day: + return S.of(context).extendedDateRangePickerDayText(count ?? 1); + case DateRangeUnit.week: + return S.of(context).extendedDateRangePickerWeekText(count ?? 1); + case DateRangeUnit.month: + return S.of(context).extendedDateRangePickerMonthText(count ?? 1); + case DateRangeUnit.year: + return S.of(context).extendedDateRangePickerYearText(count ?? 1); + } + } +} diff --git a/lib/core/widgets/form_builder_fields/extended_date_range_form_field/relative_date_range_picker_helper.dart b/lib/core/widgets/form_builder_fields/extended_date_range_form_field/relative_date_range_picker_helper.dart new file mode 100644 index 0000000..2c5c536 --- /dev/null +++ b/lib/core/widgets/form_builder_fields/extended_date_range_form_field/relative_date_range_picker_helper.dart @@ -0,0 +1,72 @@ +import 'package:flutter/material.dart'; +import 'package:paperless_api/paperless_api.dart'; +import 'package:paperless_mobile/generated/l10n.dart'; + +class RelativeDateRangePickerHelper extends StatefulWidget { + final FormFieldState field; + final void Function(DateRangeQuery value)? onChanged; + + const RelativeDateRangePickerHelper({ + super.key, + required this.field, + this.onChanged, + }); + + @override + State createState() => + _RelativeDateRangePickerHelperState(); +} + +class _RelativeDateRangePickerHelperState + extends State { + @override + Widget build(BuildContext context) { + return SizedBox( + height: 64, + child: ListView.separated( + itemCount: _options.length, + separatorBuilder: (context, index) => const SizedBox(width: 8.0), + itemBuilder: (context, index) { + final option = _options[index]; + return FilterChip( + label: Text(option.title), + onSelected: (isSelected) { + final value = + isSelected ? option.value : const RelativeDateRangeQuery(); + widget.field.didChange(value); + widget.onChanged?.call(value); + }, + selected: widget.field.value == option.value, + ); + }, + scrollDirection: Axis.horizontal, + ), + ); + } + + List<_ExtendedDateRangeQueryOption> get _options => [ + _ExtendedDateRangeQueryOption( + S.of(context).extendedDateRangePickerLastWeeksLabel(1), + const RelativeDateRangeQuery(1, DateRangeUnit.week), + ), + _ExtendedDateRangeQueryOption( + S.of(context).extendedDateRangePickerLastMonthsLabel(1), + const RelativeDateRangeQuery(1, DateRangeUnit.month), + ), + _ExtendedDateRangeQueryOption( + S.of(context).extendedDateRangePickerLastMonthsLabel(3), + const RelativeDateRangeQuery(3, DateRangeUnit.month), + ), + _ExtendedDateRangeQueryOption( + S.of(context).extendedDateRangePickerLastYearsLabel(1), + const RelativeDateRangeQuery(1, DateRangeUnit.year), + ), + ]; +} + +class _ExtendedDateRangeQueryOption { + final String title; + final RelativeDateRangeQuery value; + + _ExtendedDateRangeQueryOption(this.title, this.value); +} diff --git a/lib/core/widgets/form_builder_fields/form_builder_color_picker.dart b/lib/core/widgets/form_builder_fields/form_builder_color_picker.dart new file mode 100644 index 0000000..8ca98dd --- /dev/null +++ b/lib/core/widgets/form_builder_fields/form_builder_color_picker.dart @@ -0,0 +1,285 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_colorpicker/flutter_colorpicker.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; + +extension on Color { + /// String is in the format "aabbcc" or "ffaabbcc" with an optional leading "#". + /*static Color fromHex(String hexString) { + final buffer = StringBuffer(); + if (hexString.length == 6 || hexString.length == 7) buffer.write('ff'); + buffer.write(hexString.replaceFirst('#', '')); + return Color(int.parse(buffer.toString(), radix: 16)); + }*/ + + /// Prefixes a hash sign if [leadingHashSign] is set to `true` (default is `true`). + String toHex({bool leadingHashSign = true}) { + /// Converts an rgba value (0-255) into a 2-digit Hex code. + String hexValue(int rgbaVal) { + assert(rgbaVal == rgbaVal & 0xFF); + return rgbaVal.toRadixString(16).padLeft(2, '0').toUpperCase(); + } + + return '${leadingHashSign ? '#' : ''}' + '${hexValue(alpha)}${hexValue(red)}${hexValue(green)}${hexValue(blue)}'; + } +} + +enum ColorPickerType { colorPicker, materialPicker, blockPicker } + +/// Creates a field for `Color` input selection +class FormBuilderColorPickerField extends FormBuilderField { + //TODO: Add documentation + final TextEditingController? controller; + final ColorPickerType colorPickerType; + final TextCapitalization textCapitalization; + + final TextAlign textAlign; + + final TextInputType? keyboardType; + final TextInputAction? textInputAction; + final TextStyle? style; + final StrutStyle? strutStyle; + final TextDirection? textDirection; + final bool autofocus; + + final bool obscureText; + final bool autocorrect; + final MaxLengthEnforcement? maxLengthEnforcement; + + final int maxLines; + final bool expands; + + final bool showCursor; + final int? minLines; + final int? maxLength; + final VoidCallback? onEditingComplete; + final ValueChanged? onFieldSubmitted; + final List? inputFormatters; + final double cursorWidth; + final Radius? cursorRadius; + final Color? cursorColor; + final Brightness? keyboardAppearance; + final EdgeInsets scrollPadding; + final bool enableInteractiveSelection; + final InputCounterWidgetBuilder? buildCounter; + + final Widget Function(Color?)? colorPreviewBuilder; + + FormBuilderColorPickerField({ + Key? key, + //From Super + required String name, + FormFieldValidator? validator, + Color? initialValue, + InputDecoration decoration = const InputDecoration(), + ValueChanged? onChanged, + ValueTransformer? valueTransformer, + bool enabled = true, + FormFieldSetter? onSaved, + AutovalidateMode autovalidateMode = AutovalidateMode.disabled, + VoidCallback? onReset, + FocusNode? focusNode, + bool readOnly = false, + this.colorPickerType = ColorPickerType.colorPicker, + this.textCapitalization = TextCapitalization.none, + this.textAlign = TextAlign.start, + this.keyboardType, + this.textInputAction, + this.style, + this.strutStyle, + this.textDirection, + this.autofocus = false, + this.obscureText = false, + this.autocorrect = true, + this.maxLengthEnforcement, + this.maxLines = 1, + this.expands = false, + this.showCursor = false, + this.minLines, + this.maxLength, + this.onEditingComplete, + this.onFieldSubmitted, + this.inputFormatters, + this.cursorWidth = 2.0, + this.cursorRadius, + this.cursorColor, + this.keyboardAppearance, + this.scrollPadding = const EdgeInsets.all(20.0), + this.enableInteractiveSelection = true, + this.buildCounter, + this.controller, + this.colorPreviewBuilder, + }) : super( + key: key, + initialValue: initialValue, + name: name, + validator: validator, + valueTransformer: valueTransformer, + onChanged: onChanged, + autovalidateMode: autovalidateMode, + onSaved: onSaved, + enabled: enabled, + onReset: onReset, + decoration: decoration, + focusNode: focusNode, + builder: (FormFieldState field) { + final state = field as FormBuilderColorPickerFieldState; + return TextField( + style: style, + decoration: state.decoration.copyWith( + suffixIcon: colorPreviewBuilder != null + ? colorPreviewBuilder(field.value) + : LayoutBuilder( + key: ObjectKey(state.value), + builder: (context, constraints) { + return Icon( + Icons.circle, + key: ObjectKey(state.value), + size: constraints.minHeight, + color: state.value, + ); + }, + ), + ), + enabled: state.enabled, + readOnly: readOnly, + controller: state._effectiveController, + focusNode: state.effectiveFocusNode, + textAlign: textAlign, + autofocus: autofocus, + expands: expands, + scrollPadding: scrollPadding, + autocorrect: autocorrect, + textCapitalization: textCapitalization, + keyboardType: keyboardType, + obscureText: obscureText, + buildCounter: buildCounter, + cursorColor: cursorColor, + cursorRadius: cursorRadius, + cursorWidth: cursorWidth, + enableInteractiveSelection: enableInteractiveSelection, + inputFormatters: inputFormatters, + keyboardAppearance: keyboardAppearance, + maxLength: maxLength, + maxLengthEnforcement: maxLengthEnforcement, + maxLines: maxLines, + minLines: minLines, + onEditingComplete: onEditingComplete, + showCursor: showCursor, + strutStyle: strutStyle, + textDirection: textDirection, + textInputAction: textInputAction, + ); + }, + ); + + @override + FormBuilderColorPickerFieldState createState() => + FormBuilderColorPickerFieldState(); +} + +class FormBuilderColorPickerFieldState + extends FormBuilderFieldState { + late TextEditingController _effectiveController; + + String? get valueString => value?.toHex(); + + Color? _selectedColor; + + @override + void initState() { + super.initState(); + _effectiveController = widget.controller ?? TextEditingController(); + _effectiveController.text = valueString ?? ''; + effectiveFocusNode.addListener(_handleFocus); + } + + @override + void dispose() { + effectiveFocusNode.removeListener(_handleFocus); + // Dispose the _effectiveController when initState created it + if (null == widget.controller) { + _effectiveController.dispose(); + } + super.dispose(); + } + + Future _handleFocus() async { + if (effectiveFocusNode.hasFocus && enabled) { + effectiveFocusNode.unfocus(); + final selected = await showDialog( + context: context, + builder: (BuildContext context) { + final materialLocalizations = MaterialLocalizations.of(context); + + return AlertDialog( + // title: null, //const Text('Pick a color!'), + content: SingleChildScrollView( + child: _buildColorPicker(), + ), + actions: [ + TextButton( + onPressed: () => Navigator.pop(context, false), + child: Text(materialLocalizations.cancelButtonLabel), + ), + TextButton( + onPressed: () => Navigator.pop(context, true), + child: Text(materialLocalizations.okButtonLabel), + ), + ], + ); + }, + ); + if (true == selected) { + didChange(_selectedColor); + } + } + } + + Widget _buildColorPicker() { + switch (widget.colorPickerType) { + case ColorPickerType.colorPicker: + return ColorPicker( + pickerColor: value ?? Colors.transparent, + onColorChanged: _colorChanged, + colorPickerWidth: 300, + displayThumbColor: true, + enableAlpha: true, + paletteType: PaletteType.hsl, + pickerAreaHeightPercent: 1.0, + ); + case ColorPickerType.materialPicker: + return MaterialPicker( + pickerColor: value ?? Colors.transparent, + onColorChanged: _colorChanged, + enableLabel: true, // only on portrait mode + ); + case ColorPickerType.blockPicker: + return BlockPicker( + pickerColor: value ?? Colors.transparent, + onColorChanged: _colorChanged, + ); + default: + throw 'Unknown ColorPickerType'; + } + } + + void _colorChanged(Color color) => _selectedColor = color; + + void _setTextFieldString() => _effectiveController.text = valueString ?? ''; + + @override + void didChange(Color? value) { + super.didChange(value); + _setTextFieldString(); + } + + @override + void reset() { + super.reset(); + _setTextFieldString(); + } +} diff --git a/lib/core/widgets/form_builder_fields/form_builder_relative_date_range_field.dart b/lib/core/widgets/form_builder_fields/form_builder_relative_date_range_field.dart deleted file mode 100644 index 24cd009..0000000 --- a/lib/core/widgets/form_builder_fields/form_builder_relative_date_range_field.dart +++ /dev/null @@ -1,102 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_form_builder/flutter_form_builder.dart'; -import 'package:form_builder_validators/form_builder_validators.dart'; -import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/generated/l10n.dart'; - -class FormBuilderRelativeDateRangePicker extends StatefulWidget { - final String name; - final RelativeDateRangeQuery initialValue; - const FormBuilderRelativeDateRangePicker({ - super.key, - required this.name, - required this.initialValue, - }); - - @override - State createState() => - _FormBuilderRelativeDateRangePickerState(); -} - -class _FormBuilderRelativeDateRangePickerState - extends State { - late int _offset; - @override - void initState() { - super.initState(); - _offset = widget.initialValue.offset; - } - - @override - Widget build(BuildContext context) { - return FormBuilderField( - name: widget.name, - initialValue: widget.initialValue, - builder: (field) => Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text("Last"), - SizedBox( - width: 70, - child: TextFormField( - decoration: InputDecoration( - labelText: "Offset", - ), - initialValue: widget.initialValue.offset.toString(), - inputFormatters: [ - FilteringTextInputFormatter.allow(RegExp(r"[1-9][0-9]*")) - ], - validator: FormBuilderValidators.numeric(), - keyboardType: TextInputType.number, - onChanged: (value) { - final parsed = int.parse(value); - setState(() { - _offset = parsed; - }); - field.didChange(field.value!.copyWith(offset: parsed)); - }, - ), - ), - SizedBox( - width: 120, - child: DropdownButtonFormField( - value: field.value?.unit, - items: DateRangeUnit.values - .map( - (unit) => DropdownMenuItem( - child: Text( - _dateRangeUnitToLocalizedString( - unit, - _offset, - ), - ), - value: unit, - ), - ) - .toList(), - onChanged: (value) => - field.didChange(field.value!.copyWith(unit: value)), - decoration: InputDecoration( - labelText: "Amount", - ), - ), - ) - ], - ), - ); - } - - String _dateRangeUnitToLocalizedString(DateRangeUnit unit, int? count) { - switch (unit) { - case DateRangeUnit.day: - return S.of(context).extendedDateRangePickerDayText(count ?? 1); - case DateRangeUnit.week: - return S.of(context).extendedDateRangePickerWeekText(count ?? 1); - case DateRangeUnit.month: - return S.of(context).extendedDateRangePickerMonthText(count ?? 1); - case DateRangeUnit.year: - return S.of(context).extendedDateRangePickerYearText(count ?? 1); - } - } -} diff --git a/lib/core/widgets/form_builder_fields/form_builder_type_ahead.dart b/lib/core/widgets/form_builder_fields/form_builder_type_ahead.dart new file mode 100644 index 0000000..bbd8480 --- /dev/null +++ b/lib/core/widgets/form_builder_fields/form_builder_type_ahead.dart @@ -0,0 +1,430 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_form_builder/flutter_form_builder.dart'; +import 'package:flutter_typeahead/flutter_typeahead.dart'; + +typedef SelectionToTextTransformer = String Function(T suggestion); + +/// Text field that auto-completes user input from a list of items +class FormBuilderTypeAhead extends FormBuilderField { + /// Called with the search pattern to get the search suggestions. + /// + /// This callback must not be null. It is be called by the TypeAhead widget + /// and provided with the search pattern. It should return a [List](https://api.dartlang.org/stable/2.0.0/dart-core/List-class.html) + /// of suggestions either synchronously, or asynchronously (as the result of a + /// [Future](https://api.dartlang.org/stable/dart-async/Future-class.html)). + /// Typically, the list of suggestions should not contain more than 4 or 5 + /// entries. These entries will then be provided to [itemBuilder] to display + /// the suggestions. + /// + /// Example: + /// ```dart + /// suggestionsCallback: (pattern) async { + /// return await _getSuggestions(pattern); + /// } + /// ``` + final SuggestionsCallback suggestionsCallback; + + /// Called when a suggestion is tapped. + /// + /// This callback must not be null. It is called by the TypeAhead widget and + /// provided with the value of the tapped suggestion. + /// + /// For example, you might want to navigate to a specific view when the user + /// tabs a suggestion: + /// ```dart + /// onSuggestionSelected: (suggestion) { + /// Navigator.of(context).push(MaterialPageRoute( + /// builder: (context) => SearchResult( + /// searchItem: suggestion + /// ) + /// )); + /// } + /// ``` + /// + /// Or to set the value of the text field: + /// ```dart + /// onSuggestionSelected: (suggestion) { + /// _controller.text = suggestion['name']; + /// } + /// ``` + final SuggestionSelectionCallback? onSuggestionSelected; + + /// Called for each suggestion returned by [suggestionsCallback] to build the + /// corresponding widget. + /// + /// This callback must not be null. It is called by the TypeAhead widget for + /// each suggestion, and expected to build a widget to display this + /// suggestion's info. For example: + /// + /// ```dart + /// itemBuilder: (context, suggestion) { + /// return ListTile( + /// title: Text(suggestion['name']), + /// subtitle: Text('USD' + suggestion['price'].toString()) + /// ); + /// } + /// ``` + final ItemBuilder itemBuilder; + + /// The decoration of the material sheet that contains the suggestions. + /// + /// If null, default decoration with an elevation of 4.0 is used + final SuggestionsBoxDecoration suggestionsBoxDecoration; + + /// Used to control the `_SuggestionsBox`. Allows manual control to + /// open, close, toggle, or resize the `_SuggestionsBox`. + final SuggestionsBoxController? suggestionsBoxController; + + /// The duration to wait after the user stops typing before calling + /// [suggestionsCallback] + /// + /// This is useful, because, if not set, a request for suggestions will be + /// sent for every character that the user types. + /// + /// This duration is set by default to 300 milliseconds + final Duration debounceDuration; + + /// Called when waiting for [suggestionsCallback] to return. + /// + /// It is expected to return a widget to display while waiting. + /// For example: + /// ```dart + /// (BuildContext context) { + /// return Text('Loading...'); + /// } + /// ``` + /// + /// If not specified, a [CircularProgressIndicator](https://docs.flutter.io/flutter/material/CircularProgressIndicator-class.html) is shown + final WidgetBuilder? loadingBuilder; + + /// Called when [suggestionsCallback] returns an empty array. + /// + /// It is expected to return a widget to display when no suggestions are + /// available. + /// For example: + /// ```dart + /// (BuildContext context) { + /// return Text('No Items Found!'); + /// } + /// ``` + /// + /// If not specified, a simple text is shown + final WidgetBuilder? noItemsFoundBuilder; + + /// Called when [suggestionsCallback] throws an exception. + /// + /// It is called with the error object, and expected to return a widget to + /// display when an exception is thrown + /// For example: + /// ```dart + /// (BuildContext context, error) { + /// return Text('$error'); + /// } + /// ``` + /// + /// If not specified, the error is shown in [ThemeData.errorColor](https://docs.flutter.io/flutter/material/ThemeData/errorColor.html) + final ErrorBuilder? errorBuilder; + + /// Called to display animations when [suggestionsCallback] returns suggestions + /// + /// It is provided with the suggestions box instance and the animation + /// controller, and expected to return some animation that uses the controller + /// to display the suggestion box. + /// + /// For example: + /// ```dart + /// transitionBuilder: (context, suggestionsBox, animationController) { + /// return FadeTransition( + /// child: suggestionsBox, + /// opacity: CurvedAnimation( + /// parent: animationController, + /// curve: Curves.fastOutSlowIn + /// ), + /// ); + /// } + /// ``` + /// This argument is best used with [animationDuration] and [animationStart] + /// to fully control the animation. + /// + /// To fully remove the animation, just return `suggestionsBox` + /// + /// If not specified, a [SizeTransition](https://docs.flutter.io/flutter/widgets/SizeTransition-class.html) is shown. + final AnimationTransitionBuilder? transitionBuilder; + + /// The duration that [transitionBuilder] animation takes. + /// + /// This argument is best used with [transitionBuilder] and [animationStart] + /// to fully control the animation. + /// + /// Defaults to 500 milliseconds. + final Duration animationDuration; + + /// Determine the [SuggestionBox]'s direction. + /// + /// If [AxisDirection.down], the [SuggestionBox] will be below the [TextField] + /// and the [_SuggestionsList] will grow **down**. + /// + /// If [AxisDirection.up], the [SuggestionBox] will be above the [TextField] + /// and the [_SuggestionsList] will grow **up**. + /// + /// [AxisDirection.left] and [AxisDirection.right] are not allowed. + final AxisDirection direction; + + /// The value at which the [transitionBuilder] animation starts. + /// + /// This argument is best used with [transitionBuilder] and [animationDuration] + /// to fully control the animation. + /// + /// Defaults to 0.25. + final double animationStart; + + /// The configuration of the [TextField](https://docs.flutter.io/flutter/material/TextField-class.html) + /// that the TypeAhead widget displays + final TextFieldConfiguration textFieldConfiguration; + + /// How far below the text field should the suggestions box be + /// + /// Defaults to 5.0 + final double suggestionsBoxVerticalOffset; + + /// If set to true, suggestions will be fetched immediately when the field is + /// added to the view. + /// + /// But the suggestions box will only be shown when the field receives focus. + /// To make the field receive focus immediately, you can set the `autofocus` + /// property in the [textFieldConfiguration] to true + /// + /// Defaults to false + final bool getImmediateSuggestions; + + /// If set to true, no loading box will be shown while suggestions are + /// being fetched. [loadingBuilder] will also be ignored. + /// + /// Defaults to false. + final bool hideOnLoading; + + /// If set to true, nothing will be shown if there are no results. + /// [noItemsFoundBuilder] will also be ignored. + /// + /// Defaults to false. + final bool hideOnEmpty; + + /// If set to true, nothing will be shown if there is an error. + /// [errorBuilder] will also be ignored. + /// + /// Defaults to false. + final bool hideOnError; + + /// If set to false, the suggestions box will stay opened after + /// the keyboard is closed. + /// + /// Defaults to true. + final bool hideSuggestionsOnKeyboardHide; + + /// If set to false, the suggestions box will show a circular + /// progress indicator when retrieving suggestions. + /// + /// Defaults to true. + final bool keepSuggestionsOnLoading; + + /// If set to true, the suggestions box will remain opened even after + /// selecting a suggestion. + /// + /// Note that if this is enabled, the only way + /// to close the suggestions box is either manually via the + /// `SuggestionsBoxController` or when the user closes the software + /// keyboard if `hideSuggestionsOnKeyboardHide` is set to true. Users + /// with a physical keyboard will be unable to close the + /// box without a manual way via `SuggestionsBoxController`. + /// + /// Defaults to false. + final bool keepSuggestionsOnSuggestionSelected; + + /// If set to true, in the case where the suggestions box has less than + /// _SuggestionsBoxController.minOverlaySpace to grow in the desired [direction], the direction axis + /// will be temporarily flipped if there's more room available in the opposite + /// direction. + /// + /// Defaults to false + final bool autoFlipDirection; + + final SelectionToTextTransformer? selectionToTextTransformer; + + /// Controls the text being edited. + /// + /// If null, this widget will create its own [TextEditingController]. + final TextEditingController? controller; + + final bool hideKeyboard; + + final ScrollController? scrollController; + + /// Creates text field that auto-completes user input from a list of items + FormBuilderTypeAhead({ + Key? key, + //From Super + AutovalidateMode autovalidateMode = AutovalidateMode.disabled, + bool enabled = true, + FocusNode? focusNode, + FormFieldSetter? onSaved, + FormFieldValidator? validator, + InputDecoration decoration = const InputDecoration(), + required String name, + required this.itemBuilder, + required this.suggestionsCallback, + T? initialValue, + ValueChanged? onChanged, + ValueTransformer? valueTransformer, + VoidCallback? onReset, + this.animationDuration = const Duration(milliseconds: 500), + this.animationStart = 0.25, + this.autoFlipDirection = false, + this.controller, + this.debounceDuration = const Duration(milliseconds: 300), + this.direction = AxisDirection.down, + this.errorBuilder, + this.getImmediateSuggestions = false, + this.hideKeyboard = false, + this.hideOnEmpty = false, + this.hideOnError = false, + this.hideOnLoading = false, + this.hideSuggestionsOnKeyboardHide = true, + this.keepSuggestionsOnLoading = true, + this.keepSuggestionsOnSuggestionSelected = false, + this.loadingBuilder, + this.noItemsFoundBuilder, + this.onSuggestionSelected, + this.scrollController, + this.selectionToTextTransformer, + this.suggestionsBoxController, + this.suggestionsBoxDecoration = const SuggestionsBoxDecoration(), + this.suggestionsBoxVerticalOffset = 5.0, + this.textFieldConfiguration = const TextFieldConfiguration(), + this.transitionBuilder, + }) : assert(T == String || selectionToTextTransformer != null), + super( + key: key, + initialValue: initialValue, + name: name, + validator: validator, + valueTransformer: valueTransformer, + onChanged: onChanged, + autovalidateMode: autovalidateMode, + onSaved: onSaved, + enabled: enabled, + onReset: onReset, + decoration: decoration, + focusNode: focusNode, + builder: (FormFieldState field) { + final state = field as FormBuilderTypeAheadState; + final theme = Theme.of(state.context); + + return TypeAheadField( + textFieldConfiguration: textFieldConfiguration.copyWith( + enabled: state.enabled, + controller: state._typeAheadController, + style: state.enabled + ? textFieldConfiguration.style + : theme.textTheme.titleMedium!.copyWith( + color: theme.disabledColor, + ), + focusNode: state.effectiveFocusNode, + decoration: state.decoration, + ), + // TODO HACK to satisfy strictness + suggestionsCallback: suggestionsCallback, + itemBuilder: itemBuilder, + transitionBuilder: (context, suggestionsBox, controller) => + suggestionsBox, + onSuggestionSelected: (T suggestion) { + state.didChange(suggestion); + onSuggestionSelected?.call(suggestion); + }, + getImmediateSuggestions: getImmediateSuggestions, + errorBuilder: errorBuilder, + noItemsFoundBuilder: noItemsFoundBuilder, + loadingBuilder: loadingBuilder, + debounceDuration: debounceDuration, + suggestionsBoxDecoration: suggestionsBoxDecoration, + suggestionsBoxVerticalOffset: suggestionsBoxVerticalOffset, + animationDuration: animationDuration, + animationStart: animationStart, + direction: direction, + hideOnLoading: hideOnLoading, + hideOnEmpty: hideOnEmpty, + hideOnError: hideOnError, + hideSuggestionsOnKeyboardHide: hideSuggestionsOnKeyboardHide, + keepSuggestionsOnLoading: keepSuggestionsOnLoading, + autoFlipDirection: autoFlipDirection, + suggestionsBoxController: suggestionsBoxController, + keepSuggestionsOnSuggestionSelected: + keepSuggestionsOnSuggestionSelected, + hideKeyboard: hideKeyboard, + scrollController: scrollController, + ); + }, + ); + + @override + FormBuilderTypeAheadState createState() => FormBuilderTypeAheadState(); +} + +class FormBuilderTypeAheadState + extends FormBuilderFieldState, T> { + late TextEditingController _typeAheadController; + + @override + void initState() { + super.initState(); + _typeAheadController = widget.controller ?? + TextEditingController(text: _getTextString(initialValue)); + // _typeAheadController.addListener(_handleControllerChanged); + } + + // void _handleControllerChanged() { + // Suppress changes that originated from within this class. + // + // In the case where a controller has been passed in to this widget, we + // register this change listener. In these cases, we'll also receive change + // notifications for changes originating from within this class -- for + // example, the reset() method. In such cases, the FormField value will + // already have been set. + // if (_typeAheadController.text != value) { + // didChange(_typeAheadController.text as T); + // } + // } + + @override + void didChange(T? value) { + super.didChange(value); + var text = _getTextString(value); + + if (_typeAheadController.text != text) { + _typeAheadController.text = text; + } + } + + @override + void dispose() { + // Dispose the _typeAheadController when initState created it + super.dispose(); + _typeAheadController.dispose(); + } + + @override + void reset() { + super.reset(); + + _typeAheadController.text = _getTextString(initialValue); + } + + String _getTextString(T? value) { + var text = value == null + ? '' + : widget.selectionToTextTransformer != null + ? widget.selectionToTextTransformer!(value) + : value.toString(); + + return text; + } +} diff --git a/lib/features/documents/view/pages/documents_page.dart b/lib/features/documents/view/pages/documents_page.dart index 531c6ae..97d911d 100644 --- a/lib/features/documents/view/pages/documents_page.dart +++ b/lib/features/documents/view/pages/documents_page.dart @@ -1,4 +1,3 @@ -import 'package:badges/badges.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; @@ -83,16 +82,11 @@ class _DocumentsPageState extends State { floatingActionButton: BlocBuilder( builder: (context, state) { final appliedFiltersCount = state.filter.appliedFiltersCount; - return Badge( - toAnimate: false, - animationType: BadgeAnimationType.fade, - showBadge: appliedFiltersCount > 0, - badgeContent: appliedFiltersCount > 0 - ? Text( - state.filter.appliedFiltersCount.toString(), - style: const TextStyle(color: Colors.white), - ) - : null, + return Badge.count( + alignment: const AlignmentDirectional(44, + -4), //TODO: Wait for stable version of m3, then use AlignmentDirectional.topEnd + isLabelVisible: appliedFiltersCount > 0, + count: state.filter.appliedFiltersCount, child: FloatingActionButton( child: const Icon(Icons.filter_alt_rounded), onPressed: _openDocumentFilter, diff --git a/lib/features/documents/view/widgets/search/document_filter_panel.dart b/lib/features/documents/view/widgets/search/document_filter_panel.dart index 28d8a89..bee3381 100644 --- a/lib/features/documents/view/widgets/search/document_filter_panel.dart +++ b/lib/features/documents/view/widgets/search/document_filter_panel.dart @@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:intl/intl.dart'; import 'package:paperless_api/paperless_api.dart'; -import 'package:paperless_mobile/core/widgets/form_builder_fields/form_builder_extended_date_range_picker.dart'; +import 'package:paperless_mobile/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_extended_date_range_picker.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/features/documents/view/widgets/search/query_type_form_field.dart'; import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart'; @@ -101,8 +101,11 @@ class _DocumentFilterPanelState extends State { initialValue: widget.initialFilter.created, labelText: S.of(context).documentCreatedPropertyLabel, ).padded(), - // _buildCreatedDateRangePickerFormField(), - // _buildAddedDateRangePickerFormField(), + FormBuilderExtendedDateRangePicker( + name: DocumentModel.addedKey, + initialValue: widget.initialFilter.added, + labelText: S.of(context).documentAddedPropertyLabel, + ).padded(), _buildCorrespondentFormField().padded(), _buildDocumentTypeFormField().padded(), _buildStoragePathFormField().padded(), @@ -209,100 +212,6 @@ class _DocumentFilterPanelState extends State { ); } - // Widget _buildCreatedDateRangePickerFormField() { - // return Column( - // children: [ - // FormBuilderDateRangePicker( - // initialValue: _dateTimeRangeOfNullable( - // widget.initialFilter.createdDateAfter, - // widget.initialFilter.createdDateBefore, - // ), - // // Workaround for theme data not being correctly passed to daterangepicker, see - // // https://github.com/flutter/flutter/issues/87580 - // pickerBuilder: (context, Widget? child) => Theme( - // data: Theme.of(context).copyWith( - // dialogBackgroundColor: Theme.of(context).scaffoldBackgroundColor, - // appBarTheme: Theme.of(context).appBarTheme.copyWith( - // iconTheme: - // IconThemeData(color: Theme.of(context).primaryColor), - // ), - // colorScheme: Theme.of(context).colorScheme.copyWith( - // onPrimary: Theme.of(context).primaryColor, - // primary: Theme.of(context).colorScheme.primary, - // ), - // ), - // child: child!, - // ), - // format: DateFormat.yMMMd(Localizations.localeOf(context).toString()), - // fieldStartLabelText: - // S.of(context).documentFilterDateRangeFieldStartLabel, - // fieldEndLabelText: S.of(context).documentFilterDateRangeFieldEndLabel, - // firstDate: DateTime.fromMicrosecondsSinceEpoch(0), - // lastDate: DateTime.now(), - // name: fkCreatedAt, - // decoration: InputDecoration( - // prefixIcon: const Icon(Icons.calendar_month_outlined), - // labelText: S.of(context).documentCreatedPropertyLabel, - // suffixIcon: IconButton( - // icon: const Icon(Icons.clear), - // onPressed: () { - // _formKey.currentState?.fields[fkCreatedAt]?.didChange(null); - // }, - // ), - // ), - // ).paddedSymmetrically(horizontal: 8, vertical: 4.0), - // ], - // ); - // } - - // Widget _buildAddedDateRangePickerFormField() { - // return Column( - // children: [ - // FormBuilderDateRangePicker( - // initialValue: _dateTimeRangeOfNullable( - // widget.initialFilter.addedDateAfter, - // widget.initialFilter.addedDateBefore, - // ), - // // Workaround for theme data not being correctly passed to daterangepicker, see - // // https://github.com/flutter/flutter/issues/87580 - // pickerBuilder: (context, Widget? child) => Theme( - // data: Theme.of(context).copyWith( - // dialogBackgroundColor: Theme.of(context).scaffoldBackgroundColor, - // appBarTheme: Theme.of(context).appBarTheme.copyWith( - // iconTheme: - // IconThemeData(color: Theme.of(context).primaryColor), - // ), - // colorScheme: Theme.of(context).colorScheme.copyWith( - // onPrimary: Theme.of(context).primaryColor, - // primary: Theme.of(context).colorScheme.primary, - // ), - // ), - // child: child!, - // ), - // format: DateFormat.yMMMd(), - // fieldStartLabelText: - // S.of(context).documentFilterDateRangeFieldStartLabel, - // fieldEndLabelText: S.of(context).documentFilterDateRangeFieldEndLabel, - // firstDate: DateTime.fromMicrosecondsSinceEpoch(0), - // lastDate: DateTime.now(), - // name: fkAddedAt, - // decoration: InputDecoration( - // prefixIcon: const Icon(Icons.calendar_month_outlined), - // labelText: S.of(context).documentAddedPropertyLabel, - // suffixIcon: IconButton( - // icon: const Icon(Icons.clear), - // onPressed: () { - // _formKey.currentState?.fields[fkAddedAt]?.didChange(null); - // }, - // ), - // ), - // ).paddedSymmetrically(horizontal: 8), - // const SizedBox(height: 4.0), - // _buildDateRangePickerHelper(fkAddedAt), - // ], - // ); - // } - void _onApplyFilter() async { _formKey.currentState?.save(); if (_formKey.currentState?.validate() ?? false) { @@ -320,7 +229,6 @@ class _DocumentFilterPanelState extends State { DocumentFilter _assembleFilter() { final v = _formKey.currentState!.value; return DocumentFilter( - created: (v[fkCreatedAt] as DateRangeQuery), correspondent: v[fkCorrespondent] as IdQueryParameter? ?? DocumentFilter.initial.correspondent, documentType: v[fkDocumentType] as IdQueryParameter? ?? @@ -330,6 +238,7 @@ class _DocumentFilterPanelState extends State { tags: v[DocumentModel.tagsKey] as TagsQuery? ?? DocumentFilter.initial.tags, queryText: v[fkQuery] as String?, + created: (v[fkCreatedAt] as DateRangeQuery), added: (v[fkAddedAt] as DateRangeQuery), queryType: v[QueryTypeFormField.fkQueryType] as QueryType, asnQuery: widget.initialFilter.asnQuery, diff --git a/lib/features/edit_label/view/impl/add_tag_page.dart b/lib/features/edit_label/view/impl/add_tag_page.dart index a3d9274..55ce11c 100644 --- a/lib/features/edit_label/view/impl/add_tag_page.dart +++ b/lib/features/edit_label/view/impl/add_tag_page.dart @@ -3,9 +3,9 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; -import 'package:form_builder_extra_fields/form_builder_extra_fields.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; +import 'package:paperless_mobile/core/widgets/form_builder_fields/form_builder_color_picker.dart'; import 'package:paperless_mobile/features/edit_label/cubit/edit_label_cubit.dart'; import 'package:paperless_mobile/features/edit_label/view/add_label_page.dart'; import 'package:paperless_mobile/generated/l10n.dart'; diff --git a/lib/features/edit_label/view/impl/edit_tag_page.dart b/lib/features/edit_label/view/impl/edit_tag_page.dart index b94ceea..3c89e82 100644 --- a/lib/features/edit_label/view/impl/edit_tag_page.dart +++ b/lib/features/edit_label/view/impl/edit_tag_page.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; -import 'package:form_builder_extra_fields/form_builder_extra_fields.dart'; import 'package:paperless_api/paperless_api.dart'; import 'package:paperless_mobile/core/repository/label_repository.dart'; +import 'package:paperless_mobile/core/widgets/form_builder_fields/form_builder_color_picker.dart'; import 'package:paperless_mobile/features/edit_label/cubit/edit_label_cubit.dart'; import 'package:paperless_mobile/features/edit_label/view/edit_label_page.dart'; import 'package:paperless_mobile/generated/l10n.dart'; diff --git a/lib/features/home/view/home_page.dart b/lib/features/home/view/home_page.dart index 453ff2e..4f2fd15 100644 --- a/lib/features/home/view/home_page.dart +++ b/lib/features/home/view/home_page.dart @@ -27,6 +27,7 @@ class HomePage extends StatefulWidget { class _HomePageState extends State { int _currentIndex = 0; final DocumentScannerCubit _scannerCubit = DocumentScannerCubit(); + @override void initState() { super.initState(); diff --git a/lib/features/labels/view/widgets/label_form_field.dart b/lib/features/labels/view/widgets/label_form_field.dart index 09857cd..b80b734 100644 --- a/lib/features/labels/view/widgets/label_form_field.dart +++ b/lib/features/labels/view/widgets/label_form_field.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_typeahead/flutter_typeahead.dart'; -import 'package:form_builder_extra_fields/form_builder_extra_fields.dart'; import 'package:paperless_api/paperless_api.dart'; +import 'package:paperless_mobile/core/widgets/form_builder_fields/form_builder_type_ahead.dart'; import 'package:paperless_mobile/generated/l10n.dart'; /// diff --git a/packages/paperless_api/lib/src/models/query_parameters/date_range_query.dart b/packages/paperless_api/lib/src/models/query_parameters/date_range_query.dart index b0c997d..7d6d12c 100644 --- a/packages/paperless_api/lib/src/models/query_parameters/date_range_query.dart +++ b/packages/paperless_api/lib/src/models/query_parameters/date_range_query.dart @@ -56,10 +56,10 @@ class RelativeDateRangeQuery extends DateRangeQuery { final int offset; final DateRangeUnit unit; - const RelativeDateRangeQuery( - this.offset, - this.unit, - ); + const RelativeDateRangeQuery([ + this.offset = 1, + this.unit = DateRangeUnit.day, + ]); @override List get props => [offset, unit]; @@ -67,7 +67,7 @@ class RelativeDateRangeQuery extends DateRangeQuery { @override Map toQueryParameter(DateRangeQueryField field) { return { - 'query': '[${field.name}:$offset ${unit.name} to now]', + 'query': '${field.name}:[-$offset ${unit.name} to now]', }; } diff --git a/pubspec.lock b/pubspec.lock index b87081e..ad1aedb 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,352 +5,394 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - url: "https://pub.dartlang.org" + sha256: "8c7478991c7bbde2c1e18034ac697723176a5d3e7e0ca06c7f9aed69b6f388d7" + url: "https://pub.dev" source: hosted - version: "47.0.0" + version: "51.0.0" analyzer: dependency: transitive description: name: analyzer - url: "https://pub.dartlang.org" + sha256: "120fe7ce25377ba616bb210e7584983b163861f45d6ec446744d507e3943881b" + url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "5.3.1" archive: dependency: transitive description: name: archive - url: "https://pub.dartlang.org" + sha256: "80e5141fafcb3361653ce308776cfd7d45e6e9fbb429e14eec571382c0c5fecb" + url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.2" args: dependency: transitive description: name: args - url: "https://pub.dartlang.org" + sha256: b003c3098049a51720352d219b0bb5f219b60fbfb68e7a4748139a06a5676515 + url: "https://pub.dev" source: hosted version: "2.3.1" asn1lib: dependency: transitive description: name: asn1lib - url: "https://pub.dartlang.org" + sha256: ab96a1cb3beeccf8145c52e449233fe68364c9641623acd3adad66f8184f1039 + url: "https://pub.dev" source: hosted version: "1.4.0" async: dependency: transitive description: name: async - url: "https://pub.dartlang.org" + sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + url: "https://pub.dev" source: hosted - version: "2.9.0" + version: "2.10.0" badges: dependency: "direct main" description: name: badges - url: "https://pub.dartlang.org" + sha256: "727580d938b7a1ff47ea42df730d581415606b4224cfa708671c10287f8d3fe6" + url: "https://pub.dev" source: hosted version: "2.0.3" barcode: dependency: transitive description: name: barcode - url: "https://pub.dartlang.org" + sha256: "52570564684bbb0240a9f1fdb6bad12adc5e0540103c1c96d6dd550bd928b1c9" + url: "https://pub.dev" source: hosted version: "2.2.3" bloc: dependency: transitive description: name: bloc - url: "https://pub.dartlang.org" + sha256: bd4f8027bfa60d96c8046dec5ce74c463b2c918dce1b0d36593575995344534a + url: "https://pub.dev" source: hosted version: "8.1.0" bloc_test: dependency: "direct dev" description: name: bloc_test - url: "https://pub.dartlang.org" + sha256: "622b97678bf8c06a94f4c26a89ee9ebf7319bf775383dee2233e86e1f94ee28d" + url: "https://pub.dev" source: hosted version: "9.1.0" boolean_selector: dependency: transitive description: name: boolean_selector - url: "https://pub.dartlang.org" + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" build: dependency: transitive description: name: build - url: "https://pub.dartlang.org" + sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" + url: "https://pub.dev" source: hosted version: "2.3.1" build_config: dependency: transitive description: name: build_config - url: "https://pub.dartlang.org" + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 + url: "https://pub.dev" source: hosted version: "1.1.1" build_daemon: dependency: transitive description: name: build_daemon - url: "https://pub.dartlang.org" + sha256: "6bc5544ea6ce4428266e7ea680e945c68806c4aae2da0eb5e9ccf38df8d6acbf" + url: "https://pub.dev" source: hosted version: "3.1.0" build_resolvers: dependency: transitive description: name: build_resolvers - url: "https://pub.dartlang.org" + sha256: "7c35a3a7868626257d8aee47b51c26b9dba11eaddf3431117ed2744951416aab" + url: "https://pub.dev" source: hosted - version: "2.0.10" + version: "2.1.0" build_runner: dependency: "direct dev" description: name: build_runner - url: "https://pub.dartlang.org" + sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727 + url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.3" build_runner_core: dependency: transitive description: name: build_runner_core - url: "https://pub.dartlang.org" + sha256: "14febe0f5bac5ae474117a36099b4de6f1dbc52df6c5e55534b3da9591bf4292" + url: "https://pub.dev" source: hosted version: "7.2.7" built_collection: dependency: transitive description: name: built_collection - url: "https://pub.dartlang.org" + sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" + url: "https://pub.dev" source: hosted version: "5.1.1" built_value: dependency: transitive description: name: built_value - url: "https://pub.dartlang.org" + sha256: "59e08b0079bb75f7e27392498e26339387c1089c6bd58525a14eb8508637277b" + url: "https://pub.dev" source: hosted version: "8.4.2" cached_network_image: dependency: "direct main" description: name: cached_network_image - url: "https://pub.dartlang.org" + sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15 + url: "https://pub.dev" source: hosted version: "3.2.3" cached_network_image_platform_interface: dependency: transitive description: name: cached_network_image_platform_interface - url: "https://pub.dartlang.org" + sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7 + url: "https://pub.dev" source: hosted version: "2.0.0" cached_network_image_web: dependency: transitive description: name: cached_network_image_web - url: "https://pub.dartlang.org" + sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0 + url: "https://pub.dev" source: hosted version: "1.0.2" characters: dependency: transitive description: name: characters - url: "https://pub.dartlang.org" + sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + url: "https://pub.dev" source: hosted version: "1.2.1" checked_yaml: dependency: transitive description: name: checked_yaml - url: "https://pub.dartlang.org" + sha256: dd007e4fb8270916820a0d66e24f619266b60773cddd082c6439341645af2659 + url: "https://pub.dev" source: hosted version: "2.0.1" clock: dependency: transitive description: name: clock - url: "https://pub.dartlang.org" + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" source: hosted version: "1.1.1" code_builder: dependency: transitive description: name: code_builder - url: "https://pub.dartlang.org" + sha256: "02ce3596b459c666530f045ad6f96209474e8fee6e4855940a3cee65fb872ec5" + url: "https://pub.dev" source: hosted version: "4.3.0" collection: dependency: transitive description: name: collection - url: "https://pub.dartlang.org" + sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" connectivity_plus: dependency: "direct main" description: name: connectivity_plus - url: "https://pub.dartlang.org" + sha256: "3f8fe4e504c2d33696dac671a54909743bc6a902a9bb0902306f7a2aed7e528e" + url: "https://pub.dev" source: hosted version: "2.3.9" connectivity_plus_linux: dependency: transitive description: name: connectivity_plus_linux - url: "https://pub.dartlang.org" + sha256: "3caf859d001f10407b8e48134c761483e4495ae38094ffcca97193f6c271f5e2" + url: "https://pub.dev" source: hosted version: "1.3.1" connectivity_plus_macos: dependency: transitive description: name: connectivity_plus_macos - url: "https://pub.dartlang.org" + sha256: "488d2de1e47e1224ad486e501b20b088686ba1f4ee9c4420ecbc3b9824f0b920" + url: "https://pub.dev" source: hosted version: "1.2.6" connectivity_plus_platform_interface: dependency: transitive description: name: connectivity_plus_platform_interface - url: "https://pub.dartlang.org" + sha256: b8795b9238bf83b64375f63492034cb3d8e222af4d9ce59dda085edf038fa06f + url: "https://pub.dev" source: hosted version: "1.2.3" connectivity_plus_web: dependency: transitive description: name: connectivity_plus_web - url: "https://pub.dartlang.org" + sha256: "81332be1b4baf8898fed17bb4fdef27abb7c6fd990bf98c54fd978478adf2f1a" + url: "https://pub.dev" source: hosted version: "1.2.5" connectivity_plus_windows: dependency: transitive description: name: connectivity_plus_windows - url: "https://pub.dartlang.org" + sha256: "535b0404b4d5605c4dd8453d67e5d6d2ea0dd36e3b477f50f31af51b0aeab9dd" + url: "https://pub.dev" source: hosted version: "1.2.2" convert: dependency: transitive description: name: convert - url: "https://pub.dartlang.org" + sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" + url: "https://pub.dev" source: hosted version: "3.1.1" coverage: dependency: transitive description: name: coverage - url: "https://pub.dartlang.org" + sha256: d2494157c32b303f47dedee955b1479f2979c4ff66934eb7c0def44fd9e0267a + url: "https://pub.dev" source: hosted - version: "1.5.0" + version: "1.6.1" cross_file: dependency: transitive description: name: cross_file - url: "https://pub.dartlang.org" + sha256: f71079978789bc2fe78d79227f1f8cfe195b31bbd8db2399b0d15a4b96fb843b + url: "https://pub.dev" source: hosted version: "0.3.3+2" crypto: dependency: transitive description: name: crypto - url: "https://pub.dartlang.org" + sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + url: "https://pub.dev" source: hosted version: "3.0.2" csslib: dependency: transitive description: name: csslib - url: "https://pub.dartlang.org" + sha256: b36c7f7e24c0bdf1bf9a3da461c837d1de64b9f8beb190c9011d8c72a3dfd745 + url: "https://pub.dev" source: hosted version: "0.17.2" dart_style: dependency: transitive description: name: dart_style - url: "https://pub.dartlang.org" + sha256: "7a03456c3490394c8e7665890333e91ae8a49be43542b616e414449ac358acd4" + url: "https://pub.dev" source: hosted version: "2.2.4" dbus: dependency: transitive description: name: dbus - url: "https://pub.dartlang.org" + sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + url: "https://pub.dev" source: hosted version: "0.7.8" dependency_validator: dependency: "direct dev" description: name: dependency_validator - url: "https://pub.dartlang.org" + sha256: "08349175533ed0bd06eb9b6043cde66c45b2bfc7ebc222a7542cdb1324f1bf03" + url: "https://pub.dev" source: hosted version: "3.2.2" device_info_plus: dependency: transitive description: name: device_info_plus - url: "https://pub.dartlang.org" + sha256: b809c4ed5f7fcdb325ccc70b80ad934677dc4e2aa414bf46859a42bfdfafcbb6 + url: "https://pub.dev" source: hosted version: "4.1.3" device_info_plus_linux: dependency: transitive description: name: device_info_plus_linux - url: "https://pub.dartlang.org" + sha256: "77a8b3c4af06bc46507f89304d9f49dfc64b4ae004b994532ed23b34adeae4b3" + url: "https://pub.dev" source: hosted version: "3.0.0" device_info_plus_macos: dependency: transitive description: name: device_info_plus_macos - url: "https://pub.dartlang.org" + sha256: "37961762fbd46d3620c7b69ca606671014db55fc1b7a11e696fd90ed2e8fe03d" + url: "https://pub.dev" source: hosted version: "3.0.0" device_info_plus_platform_interface: dependency: transitive description: name: device_info_plus_platform_interface - url: "https://pub.dartlang.org" + sha256: "83fdba24fcf6846d3b10f10dfdc8b6c6d7ada5f8ed21d62ea2909c2dfa043773" + url: "https://pub.dev" source: hosted version: "3.0.0" device_info_plus_web: dependency: transitive description: name: device_info_plus_web - url: "https://pub.dartlang.org" + sha256: "5890f6094df108181c7a29720bc23d0fd6159f17d82787fac093d1fefcaf6325" + url: "https://pub.dev" source: hosted version: "3.0.0" device_info_plus_windows: dependency: transitive description: name: device_info_plus_windows - url: "https://pub.dartlang.org" + sha256: "23a2874af0e23ee6e3a2a0ebcecec3a9da13241f2cb93a93a44c8764df123dd7" + url: "https://pub.dev" source: hosted version: "4.1.0" diff_match_patch: dependency: transitive description: name: diff_match_patch - url: "https://pub.dartlang.org" + sha256: "2efc9e6e8f449d0abe15be240e2c2a3bcd977c8d126cfd70598aee60af35c0a4" + url: "https://pub.dev" source: hosted version: "0.4.1" dots_indicator: dependency: transitive description: name: dots_indicator - url: "https://pub.dartlang.org" + sha256: e59dfc90030ee5a4fd4c53144a8ce97cc7a823c2067b8fb9814960cd1ae63f89 + url: "https://pub.dev" source: hosted version: "2.1.0" - dropdown_search: - dependency: transitive - description: - name: dropdown_search - url: "https://pub.dartlang.org" - source: hosted - version: "5.0.5" edge_detection: dependency: "direct main" description: @@ -364,63 +406,72 @@ packages: dependency: transitive description: name: encrypt - url: "https://pub.dartlang.org" + sha256: "4fd4e4fdc21b9d7d4141823e1e6515cd94e7b8d84749504c232999fba25d9bbb" + url: "https://pub.dev" source: hosted version: "5.0.1" encrypted_shared_preferences: dependency: "direct main" description: name: encrypted_shared_preferences - url: "https://pub.dartlang.org" + sha256: f4109e4d176a81b203ee120b79b30c1ab93dfd9eee03cac5b8c10a888c231639 + url: "https://pub.dev" source: hosted version: "3.0.1" equatable: dependency: "direct main" description: name: equatable - url: "https://pub.dartlang.org" + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" source: hosted version: "2.0.5" extension: dependency: transitive description: name: extension - url: "https://pub.dartlang.org" + sha256: "7df1ee2de6ccd05fd3e4d63acb194ae97e6525a2e8da067161c0cccb6a0a5305" + url: "https://pub.dev" source: hosted version: "0.5.0" fake_async: dependency: transitive description: name: fake_async - url: "https://pub.dartlang.org" + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" source: hosted version: "1.3.1" ffi: dependency: transitive description: name: ffi - url: "https://pub.dartlang.org" + sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + url: "https://pub.dev" source: hosted version: "2.0.1" file: dependency: transitive description: name: file - url: "https://pub.dartlang.org" + sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + url: "https://pub.dev" source: hosted - version: "6.1.2" + version: "6.1.4" file_picker: dependency: "direct main" description: name: file_picker - url: "https://pub.dartlang.org" + sha256: f9245fc33aeba9e0b938d7f3785f10b7a7230e05b8fc40f5a6a8342d7899e391 + url: "https://pub.dev" source: hosted version: "3.0.4" fixnum: dependency: transitive description: name: fixnum - url: "https://pub.dartlang.org" + sha256: "04be3e934c52e082558cc9ee21f42f5c1cd7a1262f4c63cd0357c08d5bba81ec" + url: "https://pub.dev" source: hosted version: "1.0.1" flutter: @@ -432,44 +483,34 @@ packages: dependency: "direct main" description: name: flutter_bloc - url: "https://pub.dartlang.org" + sha256: "890c51c8007f0182360e523518a0c732efb89876cb4669307af7efada5b55557" + url: "https://pub.dev" source: hosted version: "8.1.1" flutter_blurhash: dependency: transitive description: name: flutter_blurhash - url: "https://pub.dartlang.org" + sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6" + url: "https://pub.dev" source: hosted version: "0.7.0" flutter_cache_manager: dependency: "direct main" description: name: flutter_cache_manager - url: "https://pub.dartlang.org" + sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3" + url: "https://pub.dev" source: hosted version: "3.3.0" - flutter_chips_input: - dependency: transitive - description: - name: flutter_chips_input - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" flutter_colorpicker: - dependency: transitive + dependency: "direct main" description: name: flutter_colorpicker - url: "https://pub.dartlang.org" + sha256: "458a6ed8ea480eb16ff892aedb4b7092b2804affd7e046591fb03127e8d8ef8b" + url: "https://pub.dev" source: hosted version: "1.0.3" - flutter_datetime_picker_bdaya: - dependency: transitive - description: - name: flutter_datetime_picker_bdaya - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" flutter_driver: dependency: transitive description: flutter @@ -479,56 +520,64 @@ packages: dependency: "direct main" description: name: flutter_form_builder - url: "https://pub.dartlang.org" + sha256: "768b11307e71c60cb66351a87984815bd438b50aa58b5de02c9256a8f2964bee" + url: "https://pub.dev" source: hosted version: "7.7.0" flutter_keyboard_visibility: dependency: transitive description: name: flutter_keyboard_visibility - url: "https://pub.dartlang.org" + sha256: "86b71bbaffa38e885f5c21b1182408b9be6951fd125432cf6652c636254cef2d" + url: "https://pub.dev" source: hosted version: "5.4.0" flutter_keyboard_visibility_linux: dependency: transitive description: name: flutter_keyboard_visibility_linux - url: "https://pub.dartlang.org" + sha256: "6fba7cd9bb033b6ddd8c2beb4c99ad02d728f1e6e6d9b9446667398b2ac39f08" + url: "https://pub.dev" source: hosted version: "1.0.0" flutter_keyboard_visibility_macos: dependency: transitive description: name: flutter_keyboard_visibility_macos - url: "https://pub.dartlang.org" + sha256: c5c49b16fff453dfdafdc16f26bdd8fb8d55812a1d50b0ce25fc8d9f2e53d086 + url: "https://pub.dev" source: hosted version: "1.0.0" flutter_keyboard_visibility_platform_interface: dependency: transitive description: name: flutter_keyboard_visibility_platform_interface - url: "https://pub.dartlang.org" + sha256: e43a89845873f7be10cb3884345ceb9aebf00a659f479d1c8f4293fcb37022a4 + url: "https://pub.dev" source: hosted version: "2.0.0" flutter_keyboard_visibility_web: dependency: transitive description: name: flutter_keyboard_visibility_web - url: "https://pub.dartlang.org" + sha256: d3771a2e752880c79203f8d80658401d0c998e4183edca05a149f5098ce6e3d1 + url: "https://pub.dev" source: hosted version: "2.0.0" flutter_keyboard_visibility_windows: dependency: transitive description: name: flutter_keyboard_visibility_windows - url: "https://pub.dartlang.org" + sha256: fc4b0f0b6be9b93ae527f3d527fb56ee2d918cd88bbca438c478af7bcfd0ef73 + url: "https://pub.dev" source: hosted version: "1.0.0" flutter_lints: dependency: "direct dev" description: name: flutter_lints - url: "https://pub.dartlang.org" + sha256: b543301ad291598523947dc534aaddc5aaad597b709d2426d3a0e0d44c5cb493 + url: "https://pub.dev" source: hosted version: "1.0.4" flutter_localizations: @@ -540,28 +589,24 @@ packages: dependency: "direct main" description: name: flutter_native_splash - url: "https://pub.dartlang.org" + sha256: "6777a3abb974021a39b5fdd2d46a03ca390e03903b6351f21d10e7ecc969f12d" + url: "https://pub.dev" source: hosted version: "2.2.16" flutter_plugin_android_lifecycle: dependency: transitive description: name: flutter_plugin_android_lifecycle - url: "https://pub.dartlang.org" + sha256: "60fc7b78455b94e6de2333d2f95196d32cf5c22f4b0b0520a628804cb463503b" + url: "https://pub.dev" source: hosted version: "2.0.7" - flutter_rating_bar: - dependency: transitive - description: - name: flutter_rating_bar - url: "https://pub.dartlang.org" - source: hosted - version: "4.0.1" flutter_svg: dependency: "direct main" description: name: flutter_svg - url: "https://pub.dartlang.org" + sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2" + url: "https://pub.dev" source: hosted version: "1.1.6" flutter_test: @@ -569,18 +614,12 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_touch_spin: - dependency: transitive - description: - name: flutter_touch_spin - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" flutter_typeahead: dependency: "direct main" description: name: flutter_typeahead - url: "https://pub.dartlang.org" + sha256: "0ec56e1deac7556f3616f3cd53c9a25bf225dc8b72e9f44b5a7717e42bb467b5" + url: "https://pub.dev" source: hosted version: "4.1.1" flutter_web_plugins: @@ -592,39 +631,34 @@ packages: dependency: "direct main" description: name: fluttertoast - url: "https://pub.dartlang.org" + sha256: "7cc92eabe01e3f1babe1571c5560b135dfc762a34e41e9056881e2196b178ec1" + url: "https://pub.dev" source: hosted version: "8.1.2" font_awesome_flutter: dependency: "direct main" description: name: font_awesome_flutter - url: "https://pub.dartlang.org" + sha256: "875dbb9ec1ad30d68102019ceb682760d06c72747c1c5b7885781b95f88569cc" + url: "https://pub.dev" source: hosted version: "10.3.0" - form_builder_extra_fields: - dependency: "direct main" - description: - path: "." - ref: main - resolved-ref: b02de7dad9c00ece575ad4b8dfba73a3e1239e9c - url: "https://github.com/flutter-form-builder-ecosystem/form_builder_extra_fields.git" - source: git - version: "8.4.0" form_builder_validators: dependency: "direct main" description: name: form_builder_validators - url: "https://pub.dartlang.org" + sha256: e4d54c0c513e3e36ae4e4905994873a0a907585407212effeef39a68e759670c + url: "https://pub.dev" source: hosted version: "8.4.0" frontend_server_client: dependency: transitive description: name: frontend_server_client - url: "https://pub.dartlang.org" + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" + url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "3.2.0" fuchsia_remote_debug_protocol: dependency: transitive description: flutter @@ -634,91 +668,104 @@ packages: dependency: "direct main" description: name: get_it - url: "https://pub.dartlang.org" + sha256: "290fde3a86072e4b37dbb03c07bec6126f0ecc28dad403c12ffe2e5a2d751ab7" + url: "https://pub.dev" source: hosted version: "7.2.0" glob: dependency: transitive description: name: glob - url: "https://pub.dartlang.org" + sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" graphs: dependency: transitive description: name: graphs - url: "https://pub.dartlang.org" + sha256: f9e130f3259f52d26f0cfc0e964513796dafed572fa52e45d2f8d6ca14db39b2 + url: "https://pub.dev" source: hosted version: "2.2.0" hive: dependency: "direct main" description: name: hive - url: "https://pub.dartlang.org" + sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941" + url: "https://pub.dev" source: hosted version: "2.2.3" html: dependency: transitive description: name: html - url: "https://pub.dartlang.org" + sha256: d9793e10dbe0e6c364f4c59bf3e01fb33a9b2a674bc7a1081693dba0614b6269 + url: "https://pub.dev" source: hosted version: "0.15.1" http: dependency: "direct main" description: name: http - url: "https://pub.dartlang.org" + sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + url: "https://pub.dev" source: hosted version: "0.13.5" http_interceptor: dependency: "direct main" description: name: http_interceptor - url: "https://pub.dartlang.org" + sha256: "94b5b191abb2d18a76780a2c5feffb900e54cad16f61ffcfc16997785e21d383" + url: "https://pub.dev" source: hosted version: "2.0.0-beta.6" http_multi_server: dependency: transitive description: name: http_multi_server - url: "https://pub.dartlang.org" + sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" + url: "https://pub.dev" source: hosted version: "3.2.1" http_parser: dependency: transitive description: name: http_parser - url: "https://pub.dartlang.org" + sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" + url: "https://pub.dev" source: hosted version: "4.0.2" image: dependency: "direct main" description: name: image - url: "https://pub.dartlang.org" + sha256: f6ffe2895e3c86c6ad5a27e6302cf807403463e397cb2f0c580f619ac2fa588b + url: "https://pub.dev" source: hosted version: "3.2.2" infinite_scroll_pagination: dependency: "direct main" description: name: infinite_scroll_pagination - url: "https://pub.dartlang.org" + sha256: "9517328f4e373f08f57dbb11c5aac5b05554142024d6b60c903f3b73476d52db" + url: "https://pub.dev" source: hosted version: "3.2.0" injectable: dependency: "direct main" description: name: injectable - url: "https://pub.dartlang.org" + sha256: "7dab7d341feb40a0590d9ff6261aea9495522005e2c6763f9161a4face916f7b" + url: "https://pub.dev" source: hosted version: "2.1.0" injectable_generator: dependency: "direct dev" description: name: injectable_generator - url: "https://pub.dartlang.org" + sha256: "9a3bbd2c3ba821e31ef6cea3fc535c17e3a25c74e173b6cefa05f466c8338bc8" + url: "https://pub.dev" source: hosted version: "2.1.3" integration_test: @@ -730,210 +777,240 @@ packages: dependency: "direct main" description: name: intl - url: "https://pub.dartlang.org" + sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" + url: "https://pub.dev" source: hosted version: "0.17.0" intl_utils: dependency: "direct dev" description: name: intl_utils - url: "https://pub.dartlang.org" + sha256: "413699c0f7a1123a9306c1f2f5ea8662677d25bdebf22ba4f3960e0069be3be2" + url: "https://pub.dev" source: hosted - version: "2.7.0" + version: "2.8.1" introduction_screen: dependency: "direct main" description: name: introduction_screen - url: "https://pub.dartlang.org" + sha256: "307869da307a6ba291008f8d06030816e94fe0759f6e34d671f9c39c4d512937" + url: "https://pub.dev" source: hosted version: "3.1.1" io: dependency: transitive description: name: io - url: "https://pub.dartlang.org" + sha256: "0d4c73c3653ab85bf696d51a9657604c900a370549196a91f33e4c39af760852" + url: "https://pub.dev" source: hosted version: "1.0.3" js: dependency: transitive description: name: js - url: "https://pub.dartlang.org" + sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + url: "https://pub.dev" source: hosted - version: "0.6.4" + version: "0.6.5" json_annotation: dependency: transitive description: name: json_annotation - url: "https://pub.dartlang.org" + sha256: "3520fa844009431b5d4491a5a778603520cdc399ab3406332dcc50f93547258c" + url: "https://pub.dev" source: hosted version: "4.7.0" lints: dependency: transitive description: name: lints - url: "https://pub.dartlang.org" + sha256: a2c3d198cb5ea2e179926622d433331d8b58374ab8f29cdda6e863bd62fd369c + url: "https://pub.dev" source: hosted version: "1.0.1" local_auth: dependency: "direct main" description: name: local_auth - url: "https://pub.dartlang.org" + sha256: "792b06b9e7deb52f1f55b5de678a319261c395e61d804e0f3f97c732cf002aef" + url: "https://pub.dev" source: hosted version: "2.1.2" local_auth_android: dependency: transitive description: name: local_auth_android - url: "https://pub.dartlang.org" + sha256: "95cfa61a43e0b4307d7b0abb94cad71fe47601292cafb54c2205b97b9f958fb8" + url: "https://pub.dev" source: hosted - version: "1.0.15" + version: "1.0.16" local_auth_ios: dependency: transitive description: name: local_auth_ios - url: "https://pub.dartlang.org" + sha256: "1600673a460e60ff068af91dc80b507b2ac811645db439f757521dfced0d0ab2" + url: "https://pub.dev" source: hosted - version: "1.0.10" + version: "1.0.11" local_auth_platform_interface: dependency: transitive description: name: local_auth_platform_interface - url: "https://pub.dartlang.org" + sha256: b069647f81ed12c833d3f1f7c2880e20b86ca04429e786df76731ac2d4220c47 + url: "https://pub.dev" source: hosted version: "1.0.5" local_auth_windows: dependency: transitive description: name: local_auth_windows - url: "https://pub.dartlang.org" + sha256: "53ef7487587e1cb06755861a9a74585b3b361ba1969ad374c728c75771a14fbb" + url: "https://pub.dev" source: hosted version: "1.0.4" logging: dependency: transitive description: name: logging - url: "https://pub.dartlang.org" + sha256: c0bbfe94d46aedf9b8b3e695cf3bd48c8e14b35e3b2c639e0aa7755d589ba946 + url: "https://pub.dev" source: hosted version: "1.1.0" matcher: dependency: transitive description: name: matcher - url: "https://pub.dartlang.org" + sha256: c94db23593b89766cda57aab9ac311e3616cf87c6fa4e9749df032f66f30dcb8 + url: "https://pub.dev" source: hosted - version: "0.12.12" + version: "0.12.14" material_color_utilities: dependency: transitive description: name: material_color_utilities - url: "https://pub.dartlang.org" + sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + url: "https://pub.dev" source: hosted - version: "0.1.5" + version: "0.2.0" meta: dependency: transitive description: name: meta - url: "https://pub.dartlang.org" + sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + url: "https://pub.dev" source: hosted version: "1.8.0" mime: dependency: "direct main" description: name: mime - url: "https://pub.dartlang.org" + sha256: "52e38f7e1143ef39daf532117d6b8f8f617bf4bcd6044ed8c29040d20d269630" + url: "https://pub.dev" source: hosted version: "1.0.3" mockito: dependency: "direct dev" description: name: mockito - url: "https://pub.dartlang.org" + sha256: "2a8a17b82b1bde04d514e75d90d634a0ac23f6cb4991f6098009dd56836aeafe" + url: "https://pub.dev" source: hosted version: "5.3.2" mocktail: dependency: transitive description: name: mocktail - url: "https://pub.dartlang.org" + sha256: "80a996cd9a69284b3dc521ce185ffe9150cde69767c2d3a0720147d93c0cef53" + url: "https://pub.dev" source: hosted version: "0.3.0" nested: dependency: transitive description: name: nested - url: "https://pub.dartlang.org" + sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" + url: "https://pub.dev" source: hosted version: "1.0.0" nm: dependency: transitive description: name: nm - url: "https://pub.dartlang.org" + sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254" + url: "https://pub.dev" source: hosted version: "0.5.0" node_preamble: dependency: transitive description: name: node_preamble - url: "https://pub.dartlang.org" + sha256: "8ebdbaa3b96d5285d068f80772390d27c21e1fa10fb2df6627b1b9415043608d" + url: "https://pub.dev" source: hosted version: "2.0.1" octo_image: dependency: transitive description: name: octo_image - url: "https://pub.dartlang.org" + sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143" + url: "https://pub.dev" source: hosted version: "1.0.2" package_config: dependency: transitive description: name: package_config - url: "https://pub.dartlang.org" + sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" + url: "https://pub.dev" source: hosted version: "2.1.0" package_info_plus: dependency: "direct main" description: name: package_info_plus - url: "https://pub.dartlang.org" + sha256: f62d7253edc197fe3c88d7c2ddab82d68f555e778d55390ccc3537eca8e8d637 + url: "https://pub.dev" source: hosted version: "1.4.3+1" package_info_plus_linux: dependency: transitive description: name: package_info_plus_linux - url: "https://pub.dartlang.org" + sha256: "04b575f44233d30edbb80a94e57cad9107aada334fc02aabb42b6becd13c43fc" + url: "https://pub.dev" source: hosted version: "1.0.5" package_info_plus_macos: dependency: transitive description: name: package_info_plus_macos - url: "https://pub.dartlang.org" + sha256: a2ad8b4acf4cd479d4a0afa5a74ea3f5b1c7563b77e52cc32b3ee6956d5482a6 + url: "https://pub.dev" source: hosted version: "1.3.0" package_info_plus_platform_interface: dependency: transitive description: name: package_info_plus_platform_interface - url: "https://pub.dartlang.org" + sha256: f7a0c8f1e7e981bc65f8b64137a53fd3c195b18d429fba960babc59a5a1c7ae8 + url: "https://pub.dev" source: hosted version: "1.0.2" package_info_plus_web: dependency: transitive description: name: package_info_plus_web - url: "https://pub.dartlang.org" + sha256: f0829327eb534789e0a16ccac8936a80beed4e2401c4d3a74f3f39094a822d3b + url: "https://pub.dev" source: hosted version: "1.0.6" package_info_plus_windows: dependency: transitive description: name: package_info_plus_windows - url: "https://pub.dartlang.org" + sha256: "79524f11c42dd9078b96d797b3cf79c0a2883a50c4920dc43da8562c115089bc" + url: "https://pub.dev" source: hosted version: "2.1.0" paperless_api: @@ -947,338 +1024,378 @@ packages: dependency: transitive description: name: path - url: "https://pub.dartlang.org" + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" path_drawing: dependency: transitive description: name: path_drawing - url: "https://pub.dartlang.org" + sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977 + url: "https://pub.dev" source: hosted version: "1.0.1" path_parsing: dependency: transitive description: name: path_parsing - url: "https://pub.dartlang.org" + sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf + url: "https://pub.dev" source: hosted version: "1.0.1" path_provider: dependency: "direct main" description: name: path_provider - url: "https://pub.dartlang.org" + sha256: "050e8e85e4b7fecdf2bb3682c1c64c4887a183720c802d323de8a5fd76d372dd" + url: "https://pub.dev" source: hosted version: "2.0.11" path_provider_android: dependency: transitive description: name: path_provider_android - url: "https://pub.dartlang.org" + sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e + url: "https://pub.dev" source: hosted version: "2.0.22" path_provider_ios: dependency: transitive description: name: path_provider_ios - url: "https://pub.dartlang.org" + sha256: "03d639406f5343478352433f00d3c4394d52dac8df3d847869c5e2333e0bbce8" + url: "https://pub.dev" source: hosted version: "2.0.11" path_provider_linux: dependency: transitive description: name: path_provider_linux - url: "https://pub.dartlang.org" + sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 + url: "https://pub.dev" source: hosted version: "2.1.7" path_provider_macos: dependency: transitive description: name: path_provider_macos - url: "https://pub.dartlang.org" + sha256: "2a97e7fbb7ae9dcd0dfc1220a78e9ec3e71da691912e617e8715ff2a13086ae8" + url: "https://pub.dev" source: hosted version: "2.0.6" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - url: "https://pub.dartlang.org" + sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 + url: "https://pub.dev" source: hosted version: "2.0.5" path_provider_windows: dependency: transitive description: name: path_provider_windows - url: "https://pub.dartlang.org" + sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c + url: "https://pub.dev" source: hosted version: "2.1.3" pdf: dependency: "direct main" description: name: pdf - url: "https://pub.dartlang.org" + sha256: "10659b915e65832b106f6d1d213e09b789cc1f24bf282ee911e49db35b96be4d" + url: "https://pub.dev" source: hosted version: "3.8.4" pdfx: dependency: "direct main" description: name: pdfx - url: "https://pub.dartlang.org" + sha256: cad7eab6358a89922c8ea592b738891b3984edab43300558d25dc9b15a94a35e + url: "https://pub.dev" source: hosted version: "2.3.0" pedantic: dependency: transitive description: name: pedantic - url: "https://pub.dartlang.org" + sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" + url: "https://pub.dev" source: hosted version: "1.11.1" permission_handler: dependency: "direct main" description: name: permission_handler - url: "https://pub.dartlang.org" + sha256: "5749ebeb7ec0c3865ea17e3eb337174b87747be816dab582c551e1aff6f6bbf3" + url: "https://pub.dev" source: hosted version: "9.2.0" permission_handler_android: dependency: transitive description: name: permission_handler_android - url: "https://pub.dartlang.org" + sha256: a512e0fa8abcb0659d938ec2df93a70eb1df1fdea5fdc6d79a866bfd858a28fc + url: "https://pub.dev" source: hosted version: "9.0.2+1" permission_handler_apple: dependency: transitive description: name: permission_handler_apple - url: "https://pub.dartlang.org" + sha256: "9c370ef6a18b1c4b2f7f35944d644a56aa23576f23abee654cf73968de93f163" + url: "https://pub.dev" source: hosted version: "9.0.7" permission_handler_platform_interface: dependency: transitive description: name: permission_handler_platform_interface - url: "https://pub.dartlang.org" + sha256: "68abbc472002b5e6dfce47fe9898c6b7d8328d58b5d2524f75e277c07a97eb84" + url: "https://pub.dev" source: hosted version: "3.9.0" permission_handler_windows: dependency: transitive description: name: permission_handler_windows - url: "https://pub.dartlang.org" + sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b + url: "https://pub.dev" source: hosted version: "0.1.2" petitparser: dependency: transitive description: name: petitparser - url: "https://pub.dartlang.org" + sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + url: "https://pub.dev" source: hosted version: "5.1.0" photo_view: dependency: "direct main" description: name: photo_view - url: "https://pub.dartlang.org" + sha256: "8036802a00bae2a78fc197af8a158e3e2f7b500561ed23b4c458107685e645bb" + url: "https://pub.dev" source: hosted version: "0.14.0" platform: dependency: transitive description: name: platform - url: "https://pub.dartlang.org" + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.dev" source: hosted version: "3.1.0" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - url: "https://pub.dartlang.org" + sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a + url: "https://pub.dev" source: hosted version: "2.1.3" pointycastle: dependency: transitive description: name: pointycastle - url: "https://pub.dartlang.org" + sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346 + url: "https://pub.dev" source: hosted version: "3.6.2" pool: dependency: transitive description: name: pool - url: "https://pub.dartlang.org" + sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + url: "https://pub.dev" source: hosted version: "1.5.1" process: dependency: transitive description: name: process - url: "https://pub.dartlang.org" + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.dev" source: hosted version: "4.2.4" provider: dependency: transitive description: name: provider - url: "https://pub.dartlang.org" + sha256: cdbe7530b12ecd9eb455bdaa2fcb8d4dad22e80b8afb4798b41479d5ce26847f + url: "https://pub.dev" source: hosted - version: "6.0.4" + version: "6.0.5" pub_semver: dependency: transitive description: name: pub_semver - url: "https://pub.dartlang.org" + sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" + url: "https://pub.dev" source: hosted version: "2.1.3" pubspec_parse: dependency: transitive description: name: pubspec_parse - url: "https://pub.dartlang.org" + sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a" + url: "https://pub.dev" source: hosted version: "1.2.1" qr: dependency: transitive description: name: qr - url: "https://pub.dartlang.org" + sha256: "64957a3930367bf97cc211a5af99551d630f2f4625e38af10edd6b19131b64b3" + url: "https://pub.dev" source: hosted version: "3.0.1" recase: dependency: transitive description: name: recase - url: "https://pub.dartlang.org" + sha256: e4eb4ec2dcdee52dcf99cb4ceabaffc631d7424ee55e56f280bc039737f89213 + url: "https://pub.dev" source: hosted version: "4.1.0" receive_sharing_intent: dependency: "direct main" description: name: receive_sharing_intent - url: "https://pub.dartlang.org" + sha256: "912bebb551bce75a14098891fd750305b30d53eba0d61cc70cd9973be9866e8d" + url: "https://pub.dev" source: hosted version: "1.4.5" rxdart: dependency: "direct main" description: name: rxdart - url: "https://pub.dartlang.org" + sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + url: "https://pub.dev" source: hosted version: "0.27.7" share_plus: dependency: "direct main" description: name: share_plus - url: "https://pub.dartlang.org" + sha256: e387077716f80609bb979cd199331033326033ecd1c8f200a90c5f57b1c9f55e + url: "https://pub.dev" source: hosted version: "6.3.0" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface - url: "https://pub.dartlang.org" + sha256: "82ddd4ab9260c295e6e39612d4ff00390b9a7a21f1bb1da771e2f232d80ab8a1" + url: "https://pub.dev" source: hosted version: "3.2.0" shared_preferences: dependency: transitive description: name: shared_preferences - url: "https://pub.dartlang.org" + sha256: "76917b7d4b9526b2ba416808a7eb9fb2863c1a09cf63ec85f1453da240fa818a" + url: "https://pub.dev" source: hosted version: "2.0.15" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - url: "https://pub.dartlang.org" + sha256: "8e251f3c986002b65fed6396bce81f379fb63c27317d49743cf289fd0fd1ab97" + url: "https://pub.dev" source: hosted version: "2.0.14" shared_preferences_ios: dependency: transitive description: name: shared_preferences_ios - url: "https://pub.dartlang.org" + sha256: "585a14cefec7da8c9c2fb8cd283a3bb726b4155c0952afe6a0caaa7b2272de34" + url: "https://pub.dev" source: hosted version: "2.1.1" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - url: "https://pub.dartlang.org" + sha256: fbc3cd6826896b66a5f576b025e4f344f780c84ea7f8203097a353370607a2c8 + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" shared_preferences_macos: dependency: transitive description: name: shared_preferences_macos - url: "https://pub.dartlang.org" + sha256: fbb94bf296576f49be37a1496d5951796211a8db0aa22cc0d68c46440dad808c + url: "https://pub.dev" source: hosted version: "2.0.4" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - url: "https://pub.dartlang.org" + sha256: da9431745ede5ece47bc26d5d73a9d3c6936ef6945c101a5aca46f62e52c1cf3 + url: "https://pub.dev" source: hosted version: "2.1.0" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - url: "https://pub.dartlang.org" + sha256: a4b5bc37fe1b368bbc81f953197d55e12f49d0296e7e412dfe2d2d77d6929958 + url: "https://pub.dev" source: hosted version: "2.0.4" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - url: "https://pub.dartlang.org" + sha256: "07c274c2115d4d5e4280622abb09f0980e2c5b1fcdc98ae9f59a3bad5bfc1f26" + url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" shelf: dependency: transitive description: name: shelf - url: "https://pub.dartlang.org" + sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c + url: "https://pub.dev" source: hosted version: "1.4.0" shelf_packages_handler: dependency: transitive description: name: shelf_packages_handler - url: "https://pub.dartlang.org" + sha256: aef74dc9195746a384843102142ab65b6a4735bb3beea791e63527b88cc83306 + url: "https://pub.dev" source: hosted version: "3.0.1" shelf_static: dependency: transitive description: name: shelf_static - url: "https://pub.dartlang.org" + sha256: e792b76b96a36d4a41b819da593aff4bdd413576b3ba6150df5d8d9996d2e74c + url: "https://pub.dev" source: hosted version: "1.1.1" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - url: "https://pub.dartlang.org" + sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 + url: "https://pub.dev" source: hosted version: "1.0.3" shimmer: dependency: "direct main" description: name: shimmer - url: "https://pub.dartlang.org" + sha256: "1f1009b5845a1f88f1c5630212279540486f97409e9fc3f63883e71070d107bf" + url: "https://pub.dev" source: hosted version: "2.0.0" - signature: - dependency: transitive - description: - name: signature - url: "https://pub.dartlang.org" - source: hosted - version: "5.3.0" sky_engine: dependency: transitive description: flutter @@ -1288,282 +1405,322 @@ packages: dependency: transitive description: name: sliver_tools - url: "https://pub.dartlang.org" + sha256: edf005f1a47c2ffa6f1e1a4f24dd99c45b8bccfff9b928d39170d36dc6fda871 + url: "https://pub.dev" source: hosted version: "0.2.8" source_gen: dependency: transitive description: name: source_gen - url: "https://pub.dartlang.org" + sha256: "2d79738b6bbf38a43920e2b8d189e9a3ce6cc201f4b8fc76be5e4fe377b1c38d" + url: "https://pub.dev" source: hosted version: "1.2.6" source_map_stack_trace: dependency: transitive description: name: source_map_stack_trace - url: "https://pub.dartlang.org" + sha256: "84cf769ad83aa6bb61e0aa5a18e53aea683395f196a6f39c4c881fb90ed4f7ae" + url: "https://pub.dev" source: hosted version: "2.1.1" source_maps: dependency: transitive description: name: source_maps - url: "https://pub.dartlang.org" + sha256: "490098075234dcedb83c5d949b4c93dad5e6b7702748de000be2b57b8e6b2427" + url: "https://pub.dev" source: hosted version: "0.10.11" source_span: dependency: transitive description: name: source_span - url: "https://pub.dartlang.org" + sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + url: "https://pub.dev" source: hosted - version: "1.9.0" + version: "1.9.1" sqflite: dependency: transitive description: name: sqflite - url: "https://pub.dartlang.org" + sha256: "2b1697c7b78576fdc722c358f16f62171bd56e92dc13422d9e44be3fc446c276" + url: "https://pub.dev" source: hosted version: "2.2.2" sqflite_common: dependency: transitive description: name: sqflite_common - url: "https://pub.dartlang.org" + sha256: "0c21a187d645aa65da5be6997c0c713eed61e049158870ae2de157e6897067ab" + url: "https://pub.dev" source: hosted version: "2.4.0+2" stack_trace: dependency: transitive description: name: stack_trace - url: "https://pub.dartlang.org" + sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 + url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" stream_channel: dependency: transitive description: name: stream_channel - url: "https://pub.dartlang.org" + sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" + url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" stream_transform: dependency: transitive description: name: stream_transform - url: "https://pub.dartlang.org" + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" source: hosted version: "2.1.0" string_scanner: dependency: transitive description: name: string_scanner - url: "https://pub.dartlang.org" + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" sync_http: dependency: transitive description: name: sync_http - url: "https://pub.dartlang.org" + sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" + url: "https://pub.dev" source: hosted version: "0.3.1" synchronized: dependency: transitive description: name: synchronized - url: "https://pub.dartlang.org" + sha256: "7b530acd9cb7c71b0019a1e7fa22c4105e675557a4400b6a401c71c5e0ade1ac" + url: "https://pub.dev" source: hosted version: "3.0.0+3" term_glyph: dependency: transitive description: name: term_glyph - url: "https://pub.dartlang.org" + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" source: hosted version: "1.2.1" test: dependency: transitive description: name: test - url: "https://pub.dartlang.org" + sha256: "98403d1090ac0aa9e33dfc8bf45cc2e0c1d5c58d7cb832cee1e50bf14f37961d" + url: "https://pub.dev" source: hosted - version: "1.21.4" + version: "1.22.1" test_api: dependency: transitive description: name: test_api - url: "https://pub.dartlang.org" + sha256: c9282698e2982b6c3817037554e52f99d4daba493e8028f8112a83d68ccd0b12 + url: "https://pub.dev" source: hosted - version: "0.4.12" + version: "0.4.17" test_core: dependency: transitive description: name: test_core - url: "https://pub.dartlang.org" + sha256: c9e4661a5e6285b795d47ba27957ed8b6f980fc020e98b218e276e88aff02168 + url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.4.21" timing: dependency: transitive description: name: timing - url: "https://pub.dartlang.org" + sha256: c386d07d7f5efc613479a7c4d9d64b03710b03cfaa7e8ad5f2bfb295a1f0dfad + url: "https://pub.dev" source: hosted version: "1.0.0" typed_data: dependency: transitive description: name: typed_data - url: "https://pub.dartlang.org" + sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + url: "https://pub.dev" source: hosted version: "1.3.1" universal_io: dependency: transitive description: name: universal_io - url: "https://pub.dartlang.org" + sha256: "79f78ddad839ee3aae3ec7c01eb4575faf0d5c860f8e5223bc9f9c17f7f03cef" + url: "https://pub.dev" source: hosted version: "2.0.4" universal_platform: dependency: transitive description: name: universal_platform - url: "https://pub.dartlang.org" + sha256: d315be0f6641898b280ffa34e2ddb14f3d12b1a37882557869646e0cc363d0cc + url: "https://pub.dev" source: hosted version: "1.0.0+1" url_launcher: dependency: "direct main" description: name: url_launcher - url: "https://pub.dartlang.org" + sha256: "3c92b0efb5e9dcb8f846aefabf9f0f739f91682ed486b991ceda51c288e60896" + url: "https://pub.dev" source: hosted version: "6.1.7" url_launcher_android: dependency: transitive description: name: url_launcher_android - url: "https://pub.dartlang.org" + sha256: "6f91d30ce9060c204b2dbe728adb300750fa4b228e8f7ed1b961aa1ceb728799" + url: "https://pub.dev" source: hosted version: "6.0.22" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - url: "https://pub.dartlang.org" + sha256: "6ba7dddee26c9fae27c9203c424631109d73c8fa26cfa7bc3e35e751cb87f62e" + url: "https://pub.dev" source: hosted version: "6.0.17" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - url: "https://pub.dartlang.org" + sha256: "360fa359ab06bcb4f7c5cd3123a2a9a4d3364d4575d27c4b33468bd4497dd094" + url: "https://pub.dev" source: hosted version: "3.0.1" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - url: "https://pub.dartlang.org" + sha256: a9b3ea9043eabfaadfa3fb89de67a11210d85569086d22b3854484beab8b3978 + url: "https://pub.dev" source: hosted version: "3.0.1" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - url: "https://pub.dartlang.org" + sha256: "4eae912628763eb48fc214522e58e942fd16ce195407dbf45638239523c759a6" + url: "https://pub.dev" source: hosted version: "2.1.1" url_launcher_web: dependency: transitive description: name: url_launcher_web - url: "https://pub.dartlang.org" + sha256: "5669882643b96bb6d5786637cac727c6e918a790053b09245fd4513b8a07df2a" + url: "https://pub.dev" source: hosted version: "2.0.13" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - url: "https://pub.dartlang.org" + sha256: e3c3b16d3104260c10eea3b0e34272aaa57921f83148b0619f74c2eced9b7ef1 + url: "https://pub.dev" source: hosted version: "3.0.1" uuid: dependency: "direct main" description: name: uuid - url: "https://pub.dartlang.org" + sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" + url: "https://pub.dev" source: hosted version: "3.0.7" vector_math: dependency: transitive description: name: vector_math - url: "https://pub.dartlang.org" + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.4" vm_service: dependency: transitive description: name: vm_service - url: "https://pub.dartlang.org" + sha256: e7fb6c2282f7631712b69c19d1bff82f3767eea33a2321c14fa59ad67ea391c7 + url: "https://pub.dev" source: hosted - version: "9.0.0" + version: "9.4.0" watcher: dependency: transitive description: name: watcher - url: "https://pub.dartlang.org" + sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + url: "https://pub.dev" source: hosted version: "1.0.2" web_socket_channel: dependency: "direct main" description: name: web_socket_channel - url: "https://pub.dartlang.org" + sha256: "3a969ddcc204a3e34e863d204b29c0752716f78b6f9cc8235083208d268a4ccd" + url: "https://pub.dev" source: hosted version: "2.2.0" webdriver: dependency: transitive description: name: webdriver - url: "https://pub.dartlang.org" + sha256: ef67178f0cc7e32c1494645b11639dd1335f1d18814aa8435113a92e9ef9d841 + url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.0.1" webkit_inspection_protocol: dependency: transitive description: name: webkit_inspection_protocol - url: "https://pub.dartlang.org" + sha256: "67d3a8b6c79e1987d19d848b0892e582dbb0c66c57cc1fef58a177dd2aa2823d" + url: "https://pub.dev" source: hosted version: "1.2.0" win32: dependency: transitive description: name: win32 - url: "https://pub.dartlang.org" + sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 + url: "https://pub.dev" source: hosted - version: "3.1.2" + version: "3.1.3" xdg_directories: dependency: transitive description: name: xdg_directories - url: "https://pub.dartlang.org" + sha256: "11541eedefbcaec9de35aa82650b695297ce668662bbd6e3911a7fabdbde589f" + url: "https://pub.dev" source: hosted version: "0.2.0+2" xml: dependency: transitive description: name: xml - url: "https://pub.dartlang.org" + sha256: "979ee37d622dec6365e2efa4d906c37470995871fe9ae080d967e192d88286b5" + url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.2.2" yaml: dependency: transitive description: name: yaml - url: "https://pub.dartlang.org" + sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + url: "https://pub.dev" source: hosted version: "3.1.1" sdks: - dart: ">=2.18.5 <3.0.0" + dart: ">=2.18.5 <4.0.0" flutter: ">=3.3.0" diff --git a/pubspec.yaml b/pubspec.yaml index 6c2f2eb..4464fe7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -58,10 +58,6 @@ dependencies: flutter_bloc: ^8.1.1 equatable: ^2.0.3 flutter_form_builder: ^7.5.0 - form_builder_extra_fields: - git: - url: https://github.com/flutter-form-builder-ecosystem/form_builder_extra_fields.git - ref: main form_builder_validators: ^8.4.0 infinite_scroll_pagination: ^3.2.0 package_info_plus: ^1.4.3+1 @@ -82,6 +78,7 @@ dependencies: hive: ^2.2.3 rxdart: ^0.27.7 badges: ^2.0.3 + flutter_colorpicker: ^1.0.3 dev_dependencies: integration_test: