feat: Update assets, bump version, update changelogs, minor visual improvements
@@ -0,0 +1,2 @@
|
|||||||
|
- Kleinere visuelle Änderungen
|
||||||
|
- Aktualisieren der Store-Präsenz
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
- Minor visual updates
|
||||||
|
- Update store assets
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
An (almost) fully fledged mobile Paperless client compatible with Paperless.
|
|
||||||
|
|
||||||
Using this app requires access to running a Paperless-ng*x instance.
|
Using this app requires access to running a Paperless-ng*x instance.
|
||||||
|
|
||||||
* View and search documents
|
* View and search documents
|
||||||
* Add, delete or edit documents
|
* Add, delete or edit documents
|
||||||
* Share, download, print or preview your documents
|
* Share, download, print and preview your documents
|
||||||
* Manage correspondents, document types, tags and storage paths
|
* Manage correspondents, document types, tags and storage paths
|
||||||
* Scan and upload documents with preset correspondent, document type, tags and creation date
|
* Scan and upload documents with preset correspondent, document type, tags and creation date
|
||||||
* Review and quickly process newly added documents in the inbox
|
* Review and quickly process newly added documents in the inbox
|
||||||
@@ -14,4 +12,4 @@ Using this app requires access to running a Paperless-ng*x instance.
|
|||||||
* Modern, intuitive UI built according to the Material Design 3 specification
|
* Modern, intuitive UI built according to the Material Design 3 specification
|
||||||
* Light and dark theme
|
* Light and dark theme
|
||||||
* Support for dynamic color (Android 12+ only)
|
* Support for dynamic color (Android 12+ only)
|
||||||
* Available in English, German, French, Catalan, Polish, Czech and Turkish language
|
* Available in English, German, French, Spanish, Catalan, Polish, Czech, Russian and Turkish language with more to come
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 68 KiB |
|
Before Width: | Height: | Size: 252 KiB After Width: | Height: | Size: 350 KiB |
|
Before Width: | Height: | Size: 252 KiB After Width: | Height: | Size: 353 KiB |
|
Before Width: | Height: | Size: 249 KiB After Width: | Height: | Size: 532 KiB |
|
Before Width: | Height: | Size: 263 KiB After Width: | Height: | Size: 405 KiB |
|
Before Width: | Height: | Size: 252 KiB After Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 256 KiB |
|
Before Width: | Height: | Size: 258 KiB After Width: | Height: | Size: 274 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 353 KiB |
@@ -1 +1 @@
|
|||||||
An (almost) fully fledged mobile Paperless client.
|
An (almost) fully fledged mobile paperless-ng*x client.
|
||||||
@@ -115,11 +115,11 @@ class FileService {
|
|||||||
formatBytes(await getDirSizeInBytes(consumptionDir));
|
formatBytes(await getDirSizeInBytes(consumptionDir));
|
||||||
|
|
||||||
logger.ft(
|
logger.ft(
|
||||||
"Removing scans...",
|
"Clearing scans directory...",
|
||||||
className: runtimeType.toString(),
|
className: runtimeType.toString(),
|
||||||
methodName: "clearUserData",
|
methodName: "clearUserData",
|
||||||
);
|
);
|
||||||
await _temporaryScansDirectory.delete(recursive: true);
|
await _temporaryScansDirectory.clear();
|
||||||
logger.ft(
|
logger.ft(
|
||||||
"Removed $scanDirSize...",
|
"Removed $scanDirSize...",
|
||||||
className: runtimeType.toString(),
|
className: runtimeType.toString(),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.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/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/core/widgets/form_builder_fields/extended_date_range_form_field/relative_date_range_picker_helper.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
@@ -11,6 +12,7 @@ class FormBuilderExtendedDateRangePicker extends StatefulWidget {
|
|||||||
final String labelText;
|
final String labelText;
|
||||||
final DateRangeQuery initialValue;
|
final DateRangeQuery initialValue;
|
||||||
final void Function(DateRangeQuery? query)? onChanged;
|
final void Function(DateRangeQuery? query)? onChanged;
|
||||||
|
final EdgeInsets padding;
|
||||||
|
|
||||||
const FormBuilderExtendedDateRangePicker({
|
const FormBuilderExtendedDateRangePicker({
|
||||||
super.key,
|
super.key,
|
||||||
@@ -18,6 +20,7 @@ class FormBuilderExtendedDateRangePicker extends StatefulWidget {
|
|||||||
required this.labelText,
|
required this.labelText,
|
||||||
required this.initialValue,
|
required this.initialValue,
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
|
required this.padding,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -49,29 +52,36 @@ class _FormBuilderExtendedDateRangePickerState
|
|||||||
builder: (field) {
|
builder: (field) {
|
||||||
return Column(
|
return Column(
|
||||||
children: [
|
children: [
|
||||||
TextFormField(
|
Padding(
|
||||||
controller: _textEditingController,
|
padding: widget.padding.copyWith(bottom: 0),
|
||||||
readOnly: true,
|
child: TextFormField(
|
||||||
onTap: () => _showExtendedDateRangePicker(field),
|
controller: _textEditingController,
|
||||||
decoration: InputDecoration(
|
readOnly: true,
|
||||||
prefixIcon: const Icon(Icons.date_range),
|
onTap: () => _showExtendedDateRangePicker(field),
|
||||||
labelText: widget.labelText,
|
decoration: InputDecoration(
|
||||||
suffixIcon: _textEditingController.text.isNotEmpty
|
prefixIcon: const Icon(Icons.date_range),
|
||||||
? IconButton(
|
labelText: widget.labelText,
|
||||||
icon: const Icon(Icons.clear),
|
suffixIcon: _textEditingController.text.isNotEmpty
|
||||||
onPressed: () {
|
? IconButton(
|
||||||
field.didChange(const UnsetDateRangeQuery());
|
icon: const Icon(Icons.clear),
|
||||||
},
|
onPressed: () {
|
||||||
)
|
field.didChange(const UnsetDateRangeQuery());
|
||||||
: null,
|
},
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
MediaQuery.removePadding(
|
RelativeDateRangePickerHelper(
|
||||||
context: context,
|
field: field,
|
||||||
removeLeft: true,
|
padding: widget.padding,
|
||||||
removeRight: true,
|
)
|
||||||
child: RelativeDateRangePickerHelper(field: field),
|
// MediaQuery.removePadding(
|
||||||
),
|
//context: context,
|
||||||
|
//removeLeft: true,
|
||||||
|
//removeRight: true,
|
||||||
|
//child: ,
|
||||||
|
//),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,11 +6,13 @@ import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
|||||||
class RelativeDateRangePickerHelper extends StatefulWidget {
|
class RelativeDateRangePickerHelper extends StatefulWidget {
|
||||||
final FormFieldState<DateRangeQuery> field;
|
final FormFieldState<DateRangeQuery> field;
|
||||||
final void Function(DateRangeQuery value)? onChanged;
|
final void Function(DateRangeQuery value)? onChanged;
|
||||||
|
final EdgeInsets padding;
|
||||||
|
|
||||||
const RelativeDateRangePickerHelper({
|
const RelativeDateRangePickerHelper({
|
||||||
super.key,
|
super.key,
|
||||||
required this.field,
|
required this.field,
|
||||||
this.onChanged,
|
this.onChanged,
|
||||||
|
required this.padding,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -24,25 +26,32 @@ class _RelativeDateRangePickerHelperState
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SizedBox(
|
return SizedBox(
|
||||||
height: 64,
|
height: 64,
|
||||||
child: ListView.separated(
|
child: CustomScrollView(
|
||||||
itemCount: _options.length,
|
|
||||||
separatorBuilder: (context, index) => const SizedBox(width: 8.0),
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
final option = _options[index];
|
|
||||||
return ColoredChipWrapper(
|
|
||||||
child: 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,
|
scrollDirection: Axis.horizontal,
|
||||||
|
slivers: [
|
||||||
|
SliverToBoxAdapter(child: SizedBox(width: widget.padding.left)),
|
||||||
|
SliverList.separated(
|
||||||
|
itemCount: _options.length,
|
||||||
|
separatorBuilder: (context, index) => const SizedBox(width: 8.0),
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
final option = _options[index];
|
||||||
|
return ColoredChipWrapper(
|
||||||
|
child: 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,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(child: SizedBox(width: widget.padding.right))
|
||||||
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class ChangelogDialog extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const _versionNumbers = {
|
const _versionNumbers = {
|
||||||
|
"4023": "3.1.7",
|
||||||
"4013": "3.1.6",
|
"4013": "3.1.6",
|
||||||
"4003": "3.1.5",
|
"4003": "3.1.5",
|
||||||
"58": "3.1.4",
|
"58": "3.1.4",
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class _DocumentSearchBarState extends State<DocumentSearchBar> {
|
|||||||
constraints: const BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
maxWidth: 720,
|
maxWidth: 720,
|
||||||
minWidth: 360,
|
minWidth: 360,
|
||||||
maxHeight: 56,
|
maxHeight: 48,
|
||||||
minHeight: 48,
|
minHeight: 48,
|
||||||
),
|
),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
||||||
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
import 'package:paperless_mobile/core/repository/label_repository.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/core/widgets/form_builder_fields/extended_date_range_form_field/form_builder_extended_date_range_picker.dart';
|
||||||
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_form_field.dart';
|
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_form_field.dart';
|
||||||
@@ -93,14 +94,14 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
|
|||||||
|
|
||||||
List<Widget> _buildFormFieldList(LabelRepository labelRepository) {
|
List<Widget> _buildFormFieldList(LabelRepository labelRepository) {
|
||||||
return [
|
return [
|
||||||
_buildQueryFormField(),
|
_buildQueryFormField().paddedSymmetrically(horizontal: 12),
|
||||||
Align(
|
Align(
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
child: Text(
|
child: Text(
|
||||||
S.of(context)!.advanced,
|
S.of(context)!.advanced,
|
||||||
style: Theme.of(context).textTheme.bodySmall,
|
style: Theme.of(context).textTheme.bodySmall,
|
||||||
),
|
),
|
||||||
),
|
).paddedLTRB(12, 16, 12, 0),
|
||||||
FormBuilderExtendedDateRangePicker(
|
FormBuilderExtendedDateRangePicker(
|
||||||
name: DocumentFilterForm.fkCreatedAt,
|
name: DocumentFilterForm.fkCreatedAt,
|
||||||
initialValue: widget.initialFilter.created,
|
initialValue: widget.initialFilter.created,
|
||||||
@@ -108,6 +109,7 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
|
|||||||
onChanged: (_) {
|
onChanged: (_) {
|
||||||
_checkQueryConstraints();
|
_checkQueryConstraints();
|
||||||
},
|
},
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||||
),
|
),
|
||||||
FormBuilderExtendedDateRangePicker(
|
FormBuilderExtendedDateRangePicker(
|
||||||
name: DocumentFilterForm.fkAddedAt,
|
name: DocumentFilterForm.fkAddedAt,
|
||||||
@@ -116,17 +118,28 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
|
|||||||
onChanged: (_) {
|
onChanged: (_) {
|
||||||
_checkQueryConstraints();
|
_checkQueryConstraints();
|
||||||
},
|
},
|
||||||
|
padding: EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
||||||
),
|
),
|
||||||
_buildCorrespondentFormField(labelRepository.correspondents),
|
_buildCorrespondentFormField(labelRepository.correspondents)
|
||||||
_buildDocumentTypeFormField(labelRepository.documentTypes),
|
.paddedSymmetrically(
|
||||||
_buildStoragePathFormField(labelRepository.storagePaths),
|
horizontal: 16,
|
||||||
_buildTagsFormField(labelRepository.tags),
|
vertical: 4,
|
||||||
]
|
),
|
||||||
.map((w) => SliverPadding(
|
_buildDocumentTypeFormField(labelRepository.documentTypes)
|
||||||
padding: widget.padding,
|
.paddedSymmetrically(
|
||||||
sliver: SliverToBoxAdapter(child: w),
|
horizontal: 16,
|
||||||
))
|
vertical: 4,
|
||||||
.toList();
|
),
|
||||||
|
_buildStoragePathFormField(labelRepository.storagePaths)
|
||||||
|
.paddedSymmetrically(
|
||||||
|
horizontal: 16,
|
||||||
|
vertical: 4,
|
||||||
|
),
|
||||||
|
_buildTagsFormField(labelRepository.tags).paddedSymmetrically(
|
||||||
|
horizontal: 16,
|
||||||
|
vertical: 4,
|
||||||
|
),
|
||||||
|
].map((e) => SliverToBoxAdapter(child: e)).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _checkQueryConstraints() {
|
void _checkQueryConstraints() {
|
||||||
|
|||||||
@@ -384,7 +384,7 @@ class _GoRouterShellState extends State<GoRouterShell> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
routerConfig: _router,
|
routerConfig: _router,
|
||||||
debugShowCheckedModeBanner: true,
|
debugShowCheckedModeBanner: false,
|
||||||
title: "Paperless Mobile",
|
title: "Paperless Mobile",
|
||||||
theme: buildTheme(
|
theme: buildTheme(
|
||||||
brightness: Brightness.light,
|
brightness: Brightness.light,
|
||||||
@@ -396,7 +396,7 @@ class _GoRouterShellState extends State<GoRouterShell> {
|
|||||||
dynamicScheme: darkDynamic,
|
dynamicScheme: darkDynamic,
|
||||||
preferredColorScheme: settings.preferredColorSchemeOption,
|
preferredColorScheme: settings.preferredColorSchemeOption,
|
||||||
),
|
),
|
||||||
themeMode: settings.preferredThemeMode,
|
themeMode: ThemeMode.light,
|
||||||
supportedLocales: const [
|
supportedLocales: const [
|
||||||
Locale('en'),
|
Locale('en'),
|
||||||
Locale('de'),
|
Locale('de'),
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
|
|||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
version: 3.1.6+401
|
version: 3.1.7+402
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=3.1.0 <4.0.0"
|
sdk: ">=3.1.0 <4.0.0"
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 4.9 KiB |
@@ -9,7 +9,7 @@ function mergeChangelogs () {
|
|||||||
__target_file=$__target_dir/changelogs_$1.md
|
__target_file=$__target_dir/changelogs_$1.md
|
||||||
rm -f $__target_file
|
rm -f $__target_file
|
||||||
touch $__target_file
|
touch $__target_file
|
||||||
ls $__script_dir/../android/fastlane/metadata/android/$1/changelogs/[0-9]*.txt | tac | while read f; do
|
ls -1v $__script_dir/../android/fastlane/metadata/android/$1/changelogs/[0-9]*.txt | tac | while read f; do
|
||||||
__build_number="${f%.*}"
|
__build_number="${f%.*}"
|
||||||
echo "# $(basename -- $__build_number)" >> $__target_file
|
echo "# $(basename -- $__build_number)" >> $__target_file
|
||||||
cat $f >> $__target_file
|
cat $f >> $__target_file
|
||||||
|
|||||||