mirror of
https://github.com/Xevion/paperless-mobile.git
synced 2025-12-08 08:07:56 -06:00
fix: Enable logging in production
This commit is contained in:
@@ -72,6 +72,10 @@ android {
|
|||||||
release {
|
release {
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug {
|
||||||
|
applicationIdSuffix ".debug"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
|
|
||||||
class ThemeModeAdapter extends TypeAdapter<ThemeMode> {
|
class ThemeModeAdapter extends TypeAdapter<ThemeMode> {
|
||||||
@override
|
@override
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/custom_adapters/theme_mode_adapter.dart';
|
import 'package:paperless_mobile/core/database/hive/custom_adapters/theme_mode_adapter.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/user_credentials.dart';
|
import 'package:paperless_mobile/core/database/tables/user_credentials.dart';
|
||||||
@@ -4,7 +4,7 @@ import 'dart:typed_data';
|
|||||||
|
|
||||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.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/database/tables/local_user_app_state.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart';
|
import 'package:paperless_mobile/features/settings/model/color_scheme_option.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/file_download_type.dart';
|
import 'package:paperless_mobile/features/settings/model/file_download_type.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/local_user_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_settings.dart';
|
||||||
|
|
||||||
part 'local_user_account.g.dart';
|
part 'local_user_account.g.dart';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/view_type.dart';
|
import 'package:paperless_mobile/features/settings/model/view_type.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
|
|
||||||
part 'local_user_settings.g.dart';
|
part 'local_user_settings.g.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
||||||
|
|
||||||
part 'user_credentials.g.dart';
|
part 'user_credentials.g.dart';
|
||||||
|
|||||||
18
lib/core/extensions/document_iterable_extensions.dart
Normal file
18
lib/core/extensions/document_iterable_extensions.dart
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
|
|
||||||
|
extension DocumentModelIterableExtension on Iterable<DocumentModel> {
|
||||||
|
Iterable<int> get ids => map((e) => e.id);
|
||||||
|
|
||||||
|
Iterable<DocumentModel> withDocumentreplaced(DocumentModel document) {
|
||||||
|
return map((e) => e.id == document.id ? document : e);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool containsDocument(DocumentModel document) {
|
||||||
|
return ids.contains(document.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterable<DocumentModel> withDocumentRemoved(DocumentModel document) {
|
||||||
|
return whereNot((element) => element.id == document.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:paperless_mobile/core/logging/data/logger.dart';
|
import 'package:paperless_mobile/features/logging/data/logger.dart';
|
||||||
import 'package:paperless_mobile/core/logging/utils/redaction_utils.dart';
|
import 'package:paperless_mobile/features/logging/utils/redaction_utils.dart';
|
||||||
import 'package:paperless_mobile/helpers/format_helpers.dart';
|
import 'package:paperless_mobile/helpers/format_helpers.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:path_provider/path_provider.dart';
|
import 'package:path_provider/path_provider.dart';
|
||||||
@@ -231,9 +231,9 @@ class FileService {
|
|||||||
type: StorageDirectory.downloads,
|
type: StorageDirectory.downloads,
|
||||||
);
|
);
|
||||||
directory = await downloadsDir!.first.create(recursive: true);
|
directory = await downloadsDir!.first.create(recursive: true);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
_downloadsDirectory = directory;
|
_downloadsDirectory = directory;
|
||||||
|
return;
|
||||||
} else if (Platform.isIOS) {
|
} else if (Platform.isIOS) {
|
||||||
final appDir = await getApplicationDocumentsDirectory();
|
final appDir = await getApplicationDocumentsDirectory();
|
||||||
final dir = Directory('${appDir.path}/downloads');
|
final dir = Directory('${appDir.path}/downloads');
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:paperless_mobile/core/model/github_error_report.model.dart';
|
import 'package:paperless_mobile/core/model/github_error_report.model.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/error_report_page.dart';
|
import 'package:paperless_mobile/core/widgets/error_report_page.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:paperless_mobile/extensions/dart_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/dart_extensions.dart';
|
||||||
|
|
||||||
class GithubIssueService {
|
class GithubIssueService {
|
||||||
static void openCreateGithubIssue({
|
static void openCreateGithubIssue({
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter/services.dart';
|
|||||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
import 'package:paperless_mobile/core/model/github_error_report.model.dart';
|
import 'package:paperless_mobile/core/model/github_error_report.model.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_cancel_button.dart';
|
import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_cancel_button.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
|
|
||||||
class ErrorReportPage extends StatefulWidget {
|
class ErrorReportPage extends StatefulWidget {
|
||||||
final StackTrace? stackTrace;
|
final StackTrace? stackTrace;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ 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/widgets/form_builder_fields/extended_date_range_form_field/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/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
class ExtendedDateRangeDialog extends StatefulWidget {
|
class ExtendedDateRangeDialog extends StatefulWidget {
|
||||||
|
|||||||
@@ -0,0 +1,285 @@
|
|||||||
|
import 'dart:collection';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:extended_masked_text/extended_masked_text.dart';
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
|
import 'package:synchronized/extension.dart';
|
||||||
|
|
||||||
|
final class NeighbourAwareDateInputSegmentControls
|
||||||
|
with LinkedListEntry<NeighbourAwareDateInputSegmentControls> {
|
||||||
|
final FocusNode node;
|
||||||
|
final TextEditingController controller;
|
||||||
|
final int position;
|
||||||
|
final String format;
|
||||||
|
final DateTime? initialDate;
|
||||||
|
|
||||||
|
NeighbourAwareDateInputSegmentControls({
|
||||||
|
required this.node,
|
||||||
|
required this.controller,
|
||||||
|
required this.format,
|
||||||
|
this.initialDate,
|
||||||
|
required this.position,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
class FormBuilderLocalizedDatePicker extends StatefulWidget {
|
||||||
|
final String name;
|
||||||
|
final String labelText;
|
||||||
|
final Widget? prefixIcon;
|
||||||
|
final DateTime? initialValue;
|
||||||
|
final DateTime firstDate;
|
||||||
|
final DateTime lastDate;
|
||||||
|
final Locale locale;
|
||||||
|
|
||||||
|
const FormBuilderLocalizedDatePicker({
|
||||||
|
super.key,
|
||||||
|
required this.name,
|
||||||
|
this.initialValue,
|
||||||
|
required this.firstDate,
|
||||||
|
required this.lastDate,
|
||||||
|
required this.locale,
|
||||||
|
required this.labelText,
|
||||||
|
this.prefixIcon,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<FormBuilderLocalizedDatePicker> createState() =>
|
||||||
|
_FormBuilderLocalizedDatePickerState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _FormBuilderLocalizedDatePickerState
|
||||||
|
extends State<FormBuilderLocalizedDatePicker> {
|
||||||
|
late final String _separator;
|
||||||
|
late final String _format;
|
||||||
|
|
||||||
|
final _textFieldControls =
|
||||||
|
LinkedList<NeighbourAwareDateInputSegmentControls>();
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
final format =
|
||||||
|
DateFormat.yMd(widget.locale.toString()).format(DateTime(1000, 11, 22));
|
||||||
|
_separator = format.replaceAll(RegExp(r'\d'), '').characters.first;
|
||||||
|
_format = format
|
||||||
|
.replaceAll("1000", "yyyy")
|
||||||
|
.replaceAll("11", "MM")
|
||||||
|
.replaceAll("22", "dd");
|
||||||
|
|
||||||
|
final components = _format.split(_separator);
|
||||||
|
for (int i = 0; i < components.length; i++) {
|
||||||
|
final formatString = components[i];
|
||||||
|
final initialText = widget.initialValue != null
|
||||||
|
? DateFormat(formatString).format(widget.initialValue!)
|
||||||
|
: null;
|
||||||
|
final item = NeighbourAwareDateInputSegmentControls(
|
||||||
|
node: FocusNode(debugLabel: formatString),
|
||||||
|
controller: TextEditingController(text: initialText),
|
||||||
|
format: formatString,
|
||||||
|
position: i,
|
||||||
|
);
|
||||||
|
item.controller.addListener(() {
|
||||||
|
if (item.controller.text.length == item.format.length) {
|
||||||
|
// _textFieldControls.elementAt(i).next?.node.requestFocus();
|
||||||
|
// _textFieldControls.elementAt(i).next?.controller.selection =
|
||||||
|
// const TextSelection.collapsed(offset: 0);
|
||||||
|
// return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
item.node.addListener(() {
|
||||||
|
if (item.node.hasFocus) {
|
||||||
|
item.controller.selection = const TextSelection.collapsed(offset: 0);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
_textFieldControls.add(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return RawKeyboardListener(
|
||||||
|
focusNode: FocusNode(),
|
||||||
|
onKey: (value) {
|
||||||
|
if (value.logicalKey == LogicalKeyboardKey.backspace &&
|
||||||
|
value is RawKeyDownEvent) {
|
||||||
|
final currentFocus = _textFieldControls
|
||||||
|
.where((element) => element.node.hasFocus)
|
||||||
|
.firstOrNull;
|
||||||
|
if (currentFocus == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (currentFocus.controller.text.isEmpty) {
|
||||||
|
currentFocus.previous?.node.requestFocus();
|
||||||
|
final endOffset = currentFocus.previous?.controller.text.length;
|
||||||
|
currentFocus.previous?.controller.selection =
|
||||||
|
TextSelection.collapsed(offset: endOffset ?? 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
child: FormBuilderField<DateTime>(
|
||||||
|
name: widget.name,
|
||||||
|
initialValue: widget.initialValue,
|
||||||
|
validator: (value) {
|
||||||
|
if (value?.isBefore(widget.firstDate) ?? false) {
|
||||||
|
return "Date must be before " +
|
||||||
|
DateFormat.yMd(widget.locale.toString())
|
||||||
|
.format(widget.firstDate);
|
||||||
|
}
|
||||||
|
if (value?.isAfter(widget.lastDate) ?? false) {
|
||||||
|
return "Date must be after " +
|
||||||
|
DateFormat.yMd(widget.locale.toString())
|
||||||
|
.format(widget.lastDate);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
builder: (field) {
|
||||||
|
return SizedBox(
|
||||||
|
height: 56,
|
||||||
|
child: InputDecorator(
|
||||||
|
textAlignVertical: TextAlignVertical.bottom,
|
||||||
|
decoration: InputDecoration(
|
||||||
|
labelText: widget.labelText,
|
||||||
|
prefixIcon: widget.prefixIcon,
|
||||||
|
suffixIcon: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
IconButton(
|
||||||
|
icon: const Icon(Icons.calendar_month_outlined),
|
||||||
|
onPressed: () async {
|
||||||
|
final selectedDate = await showDatePicker(
|
||||||
|
context: context,
|
||||||
|
initialDate: widget.initialValue ?? DateTime.now(),
|
||||||
|
firstDate: widget.firstDate,
|
||||||
|
lastDate: widget.lastDate,
|
||||||
|
initialEntryMode: DatePickerEntryMode.calendarOnly,
|
||||||
|
);
|
||||||
|
if (selectedDate != null) {
|
||||||
|
_updateInputsWithDate(selectedDate);
|
||||||
|
field.didChange(selectedDate);
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
|
field.didChange(null);
|
||||||
|
for (var c in _textFieldControls) {
|
||||||
|
c.controller.clear();
|
||||||
|
}
|
||||||
|
_textFieldControls.first.node.requestFocus();
|
||||||
|
},
|
||||||
|
icon: const Icon(Icons.clear),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
).paddedOnly(right: 4),
|
||||||
|
),
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
for (var s in _textFieldControls) ...[
|
||||||
|
SizedBox(
|
||||||
|
width: switch (s.format) {
|
||||||
|
== "dd" => 32,
|
||||||
|
== "MM" => 32,
|
||||||
|
== "yyyy" => 48,
|
||||||
|
_ => 0,
|
||||||
|
},
|
||||||
|
child: _buildDateSegmentInput(s, context, field),
|
||||||
|
),
|
||||||
|
if (s.position < 2) Text(_separator).paddedOnly(right: 4),
|
||||||
|
],
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateInputsWithDate(DateTime date) {
|
||||||
|
final components = _format.split(_separator);
|
||||||
|
for (int i = 0; i < components.length; i++) {
|
||||||
|
final formatString = components[i];
|
||||||
|
final value = DateFormat(formatString).format(date);
|
||||||
|
_textFieldControls.elementAt(i).controller.text = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildDateSegmentInput(
|
||||||
|
NeighbourAwareDateInputSegmentControls controls,
|
||||||
|
BuildContext context,
|
||||||
|
FormFieldState<DateTime> field,
|
||||||
|
) {
|
||||||
|
return TextFormField(
|
||||||
|
onFieldSubmitted: (value) {
|
||||||
|
_textFieldControls
|
||||||
|
.elementAt(controls.position)
|
||||||
|
.next
|
||||||
|
?.node
|
||||||
|
.requestFocus();
|
||||||
|
},
|
||||||
|
// onTap: () {
|
||||||
|
// controls.controller.clear();
|
||||||
|
// },
|
||||||
|
canRequestFocus: true,
|
||||||
|
keyboardType: TextInputType.datetime,
|
||||||
|
textInputAction: TextInputAction.done,
|
||||||
|
controller: controls.controller,
|
||||||
|
focusNode: _textFieldControls.elementAt(controls.position).node,
|
||||||
|
maxLength: controls.format.length,
|
||||||
|
maxLengthEnforcement: MaxLengthEnforcement.truncateAfterCompositionEnds,
|
||||||
|
enableInteractiveSelection: false,
|
||||||
|
inputFormatters: [
|
||||||
|
FilteringTextInputFormatter.digitsOnly,
|
||||||
|
ReplacingTextFormatter(),
|
||||||
|
],
|
||||||
|
decoration: InputDecoration(
|
||||||
|
isDense: true,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
counterText: '',
|
||||||
|
hintText: controls.format,
|
||||||
|
border: Theme.of(context).inputDecorationTheme.border?.copyWith(
|
||||||
|
borderSide: const BorderSide(
|
||||||
|
width: 0,
|
||||||
|
style: BorderStyle.none,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReplacingTextFormatter extends TextInputFormatter {
|
||||||
|
@override
|
||||||
|
TextEditingValue formatEditUpdate(
|
||||||
|
TextEditingValue oldValue,
|
||||||
|
TextEditingValue newValue,
|
||||||
|
) {
|
||||||
|
final oldOffset = oldValue.selection.baseOffset;
|
||||||
|
final newOffset = newValue.selection.baseOffset;
|
||||||
|
final replacement = newValue.text.substring(oldOffset, newOffset);
|
||||||
|
print(
|
||||||
|
"DBG: Received ${oldValue.text} -> ${newValue.text}. New char = $replacement");
|
||||||
|
if (oldOffset < newOffset) {
|
||||||
|
final oldText = oldValue.text;
|
||||||
|
final newText = oldText.replaceRange(
|
||||||
|
oldOffset,
|
||||||
|
newOffset,
|
||||||
|
newValue.text.substring(oldOffset, newOffset),
|
||||||
|
);
|
||||||
|
print("DBG: Replacing $oldText -> $newText");
|
||||||
|
return newValue.copyWith(
|
||||||
|
text: newText,
|
||||||
|
selection: TextSelection.collapsed(offset: newOffset),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
class FullscreenSelectionForm extends StatefulWidget {
|
class FullscreenSelectionForm extends StatefulWidget {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
class HintCard extends StatelessWidget {
|
class HintCard extends StatelessWidget {
|
||||||
|
|||||||
@@ -1,41 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
|
||||||
import 'package:paperless_mobile/generated/assets.gen.dart';
|
|
||||||
|
|
||||||
class PaperlessLogo extends StatelessWidget {
|
|
||||||
static const _paperlessGreen = Color(0xFF18541F);
|
|
||||||
final double? height;
|
|
||||||
final double? width;
|
|
||||||
final Color _color;
|
|
||||||
|
|
||||||
const PaperlessLogo.white({
|
|
||||||
super.key,
|
|
||||||
this.height,
|
|
||||||
this.width,
|
|
||||||
}) : _color = Colors.white;
|
|
||||||
|
|
||||||
const PaperlessLogo.green({super.key, this.height, this.width})
|
|
||||||
: _color = _paperlessGreen;
|
|
||||||
|
|
||||||
const PaperlessLogo.black({super.key, this.height, this.width})
|
|
||||||
: _color = Colors.black;
|
|
||||||
|
|
||||||
const PaperlessLogo.colored(Color color, {super.key, this.height, this.width})
|
|
||||||
: _color = color;
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return Container(
|
|
||||||
constraints: BoxConstraints(
|
|
||||||
maxHeight: height ?? Theme.of(context).iconTheme.size ?? 32,
|
|
||||||
maxWidth: width ?? Theme.of(context).iconTheme.size ?? 32,
|
|
||||||
),
|
|
||||||
padding: const EdgeInsets.only(right: 8),
|
|
||||||
child: Assets.logos.paperlessLogoWhiteSvg.svg(
|
|
||||||
colorFilter: ColorFilter.mode(
|
|
||||||
_color,
|
|
||||||
BlendMode.srcIn,
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,9 +4,8 @@ import 'package:flutter_animate/flutter_animate.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:paperless_mobile/constants.dart';
|
import 'package:paperless_mobile/constants.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/logging/view/app_logs_page.dart';
|
import 'package:paperless_mobile/features/logging/view/app_logs_page.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/paperless_logo.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
|
||||||
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart';
|
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/sharing/cubit/receive_share_cubit.dart';
|
import 'package:paperless_mobile/features/sharing/cubit/receive_share_cubit.dart';
|
||||||
@@ -38,10 +37,10 @@ class AppDrawer extends StatelessWidget {
|
|||||||
children: [
|
children: [
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
const PaperlessLogo.green(
|
const $AssetsLogosGen()
|
||||||
width: 32,
|
.paperlessLogoGreenSvg
|
||||||
height: 32,
|
.svg(width: 32, height: 32),
|
||||||
),
|
SizedBox(width: 8),
|
||||||
Text(
|
Text(
|
||||||
"Paperless Mobile",
|
"Paperless Mobile",
|
||||||
style: Theme.of(context).textTheme.titleMedium,
|
style: Theme.of(context).textTheme.titleMedium,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_markdown/flutter_markdown.dart';
|
import 'package:flutter_markdown/flutter_markdown.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
import 'package:paperless_mobile/theme.dart';
|
import 'package:paperless_mobile/theme.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/form_fields/fullscreen_selection_form.dart';
|
import 'package:paperless_mobile/core/widgets/form_fields/fullscreen_selection_form.dart';
|
||||||
import 'package:paperless_mobile/extensions/dart_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/dart_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_bulk_action/view/widgets/confirm_bulk_modify_label_dialog.dart';
|
import 'package:paperless_mobile/features/document_bulk_action/view/widgets/confirm_bulk_modify_label_dialog.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/form_fields/fullscreen_selection_form.dart';
|
import 'package:paperless_mobile/core/widgets/form_fields/fullscreen_selection_form.dart';
|
||||||
import 'package:paperless_mobile/extensions/dart_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/dart_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_bulk_action/cubit/document_bulk_action_cubit.dart';
|
import 'package:paperless_mobile/features/document_bulk_action/cubit/document_bulk_action_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/document_bulk_action/view/widgets/confirm_bulk_modify_tags_dialog.dart';
|
import 'package:paperless_mobile/features/document_bulk_action/view/widgets/confirm_bulk_modify_tags_dialog.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
import 'package:open_filex/open_filex.dart';
|
import 'package:open_filex/open_filex.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/logging/data/logger.dart';
|
import 'package:paperless_mobile/features/logging/data/logger.dart';
|
||||||
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||||
import 'package:paperless_mobile/core/service/file_service.dart';
|
import 'package:paperless_mobile/core/service/file_service.dart';
|
||||||
@@ -30,10 +30,12 @@ class DocumentDetailsCubit extends Cubit<DocumentDetailsState> {
|
|||||||
this._notifier,
|
this._notifier,
|
||||||
this._notificationService, {
|
this._notificationService, {
|
||||||
required DocumentModel initialDocument,
|
required DocumentModel initialDocument,
|
||||||
}) : super(DocumentDetailsState(
|
}) : super(DocumentDetailsState(document: initialDocument)) {
|
||||||
document: initialDocument,
|
_notifier.addListener(this, onUpdated: (document) {
|
||||||
)) {
|
if (document.id == state.document.id) {
|
||||||
_notifier.addListener(this, onUpdated: replace);
|
replace(document);
|
||||||
|
}
|
||||||
|
});
|
||||||
_labelRepository.addListener(
|
_labelRepository.addListener(
|
||||||
this,
|
this,
|
||||||
onChanged: (labels) => emit(
|
onChanged: (labels) => emit(
|
||||||
@@ -127,7 +129,7 @@ class DocumentDetailsCubit extends Cubit<DocumentDetailsState> {
|
|||||||
if (!await File(targetPath).exists()) {
|
if (!await File(targetPath).exists()) {
|
||||||
await File(targetPath).create();
|
await File(targetPath).create();
|
||||||
} else {
|
} else {
|
||||||
await _notificationService.notifyFileDownload(
|
await _notificationService.notifyDocumentDownload(
|
||||||
document: state.document,
|
document: state.document,
|
||||||
filename: p.basename(targetPath),
|
filename: p.basename(targetPath),
|
||||||
filePath: targetPath,
|
filePath: targetPath,
|
||||||
@@ -151,7 +153,7 @@ class DocumentDetailsCubit extends Cubit<DocumentDetailsState> {
|
|||||||
targetPath,
|
targetPath,
|
||||||
original: downloadOriginal,
|
original: downloadOriginal,
|
||||||
onProgressChanged: (progress) {
|
onProgressChanged: (progress) {
|
||||||
_notificationService.notifyFileDownload(
|
_notificationService.notifyDocumentDownload(
|
||||||
document: state.document,
|
document: state.document,
|
||||||
filename: p.basename(targetPath),
|
filename: p.basename(targetPath),
|
||||||
filePath: targetPath,
|
filePath: targetPath,
|
||||||
@@ -162,7 +164,7 @@ class DocumentDetailsCubit extends Cubit<DocumentDetailsState> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
await _notificationService.notifyFileDownload(
|
await _notificationService.notifyDocumentDownload(
|
||||||
document: state.document,
|
document: state.document,
|
||||||
filename: p.basename(targetPath),
|
filename: p.basename(targetPath),
|
||||||
filePath: targetPath,
|
filePath: targetPath,
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import 'package:paperless_mobile/core/bloc/connectivity_cubit.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/translation/error_code_localization_mapper.dart';
|
import 'package:paperless_mobile/core/translation/error_code_localization_mapper.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/material/colored_tab_bar.dart';
|
import 'package:paperless_mobile/core/widgets/material/colored_tab_bar.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/view/widgets/document_content_widget.dart';
|
import 'package:paperless_mobile/features/document_details/view/widgets/document_content_widget.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/view/widgets/document_download_button.dart';
|
import 'package:paperless_mobile/features/document_details/view/widgets/document_download_button.dart';
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
import 'package:paperless_mobile/core/bloc/connectivity_cubit.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/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/highlighted_text.dart';
|
import 'package:paperless_mobile/core/widgets/highlighted_text.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart';
|
import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ import 'dart:io';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.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/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/view/dialogs/select_file_type_dialog.dart';
|
import 'package:paperless_mobile/features/document_details/view/dialogs/select_file_type_dialog.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.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/database/tables/local_user_account.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_account.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/view/widgets/archive_serial_number_field.dart';
|
import 'package:paperless_mobile/features/document_details/view/widgets/archive_serial_number_field.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/view/widgets/details_item.dart';
|
import 'package:paperless_mobile/features/document_details/view/widgets/details_item.dart';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ 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/repository/label_repository.dart';
|
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/highlighted_text.dart';
|
import 'package:paperless_mobile/core/widgets/highlighted_text.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/view/widgets/details_item.dart';
|
import 'package:paperless_mobile/features/document_details/view/widgets/details_item.dart';
|
||||||
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_widget.dart';
|
import 'package:paperless_mobile/features/labels/tags/view/widgets/tags_widget.dart';
|
||||||
import 'package:paperless_mobile/features/labels/view/widgets/label_text.dart';
|
import 'package:paperless_mobile/features/labels/view/widgets/label_text.dart';
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:hive_flutter/hive_flutter.dart';
|
import 'package:hive_flutter/hive_flutter.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/constants.dart';
|
import 'package:paperless_mobile/constants.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
import 'package:paperless_mobile/features/document_details/cubit/document_details_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/document_details/view/dialogs/select_file_type_dialog.dart';
|
import 'package:paperless_mobile/features/document_details/view/dialogs/select_file_type_dialog.dart';
|
||||||
import 'package:paperless_mobile/features/settings/model/file_download_type.dart';
|
import 'package:paperless_mobile/features/settings/model/file_download_type.dart';
|
||||||
|
|||||||
@@ -22,7 +22,11 @@ class DocumentEditCubit extends Cubit<DocumentEditState> {
|
|||||||
required DocumentModel document,
|
required DocumentModel document,
|
||||||
}) : _initialDocument = document,
|
}) : _initialDocument = document,
|
||||||
super(DocumentEditState(document: document)) {
|
super(DocumentEditState(document: document)) {
|
||||||
_notifier.addListener(this, onUpdated: replace);
|
_notifier.addListener(this, onUpdated: (doc) {
|
||||||
|
if (doc.id == document.id) {
|
||||||
|
emit(state.copyWith(document: doc));
|
||||||
|
}
|
||||||
|
});
|
||||||
_labelRepository.addListener(
|
_labelRepository.addListener(
|
||||||
this,
|
this,
|
||||||
onChanged: (labels) {
|
onChanged: (labels) {
|
||||||
@@ -69,10 +73,6 @@ class DocumentEditCubit extends Cubit<DocumentEditState> {
|
|||||||
emit(state.copyWith(suggestions: suggestions));
|
emit(state.copyWith(suggestions: suggestions));
|
||||||
}
|
}
|
||||||
|
|
||||||
void replace(DocumentModel document) {
|
|
||||||
emit(state.copyWith(document: document));
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() {
|
Future<void> close() {
|
||||||
_notifier.removeListener(this);
|
_notifier.removeListener(this);
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import 'dart:async';
|
|||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
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:flutter_typeahead/flutter_typeahead.dart';
|
import 'package:flutter_typeahead/flutter_typeahead.dart';
|
||||||
@@ -12,8 +11,9 @@ 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/widgets/dialog_utils/dialog_cancel_button.dart';
|
import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_cancel_button.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/dialog_utils/pop_with_unsaved_changes.dart';
|
import 'package:paperless_mobile/core/widgets/dialog_utils/pop_with_unsaved_changes.dart';
|
||||||
|
import 'package:paperless_mobile/core/widgets/form_builder_fields/form_builder_localized_date_picker.dart';
|
||||||
import 'package:paperless_mobile/core/workarounds/colored_chip.dart';
|
import 'package:paperless_mobile/core/workarounds/colored_chip.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_edit/cubit/document_edit_cubit.dart';
|
import 'package:paperless_mobile/features/document_edit/cubit/document_edit_cubit.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';
|
||||||
import 'package:paperless_mobile/features/labels/view/widgets/label_form_field.dart';
|
import 'package:paperless_mobile/features/labels/view/widgets/label_form_field.dart';
|
||||||
@@ -21,7 +21,6 @@ import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
|||||||
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
||||||
import 'package:paperless_mobile/routes/typed/branches/labels_route.dart';
|
import 'package:paperless_mobile/routes/typed/branches/labels_route.dart';
|
||||||
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
|
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
|
||||||
import 'package:paperless_mobile/theme.dart';
|
|
||||||
|
|
||||||
class DocumentEditPage extends StatefulWidget {
|
class DocumentEditPage extends StatefulWidget {
|
||||||
const DocumentEditPage({
|
const DocumentEditPage({
|
||||||
@@ -401,6 +400,12 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
name: fkTitle,
|
name: fkTitle,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
label: Text(S.of(context)!.title),
|
label: Text(S.of(context)!.title),
|
||||||
|
suffixIcon: IconButton(
|
||||||
|
icon: Icon(Icons.clear),
|
||||||
|
onPressed: () {
|
||||||
|
_formKey.currentState?.fields[fkTitle]?.didChange(null);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
initialValue: initialTitle,
|
initialValue: initialTitle,
|
||||||
);
|
);
|
||||||
@@ -408,6 +413,15 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
|
|||||||
|
|
||||||
Widget _buildCreatedAtFormField(
|
Widget _buildCreatedAtFormField(
|
||||||
DateTime? initialCreatedAtDate, FieldSuggestions? filteredSuggestions) {
|
DateTime? initialCreatedAtDate, FieldSuggestions? filteredSuggestions) {
|
||||||
|
// return FormBuilderLocalizedDatePicker(
|
||||||
|
// name: fkCreatedDate,
|
||||||
|
// initialValue: initialCreatedAtDate,
|
||||||
|
// labelText: S.of(context)!.createdAt,
|
||||||
|
// firstDate: DateTime(1970, 1, 1),
|
||||||
|
// lastDate: DateTime.now(),
|
||||||
|
// locale: Localizations.localeOf(context),
|
||||||
|
// prefixIcon: Icon(Icons.calendar_today),
|
||||||
|
// );
|
||||||
return Column(
|
return Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import 'package:flutter/foundation.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/logging/data/logger.dart';
|
import 'package:paperless_mobile/features/logging/data/logger.dart';
|
||||||
import 'package:paperless_mobile/core/model/info_message_exception.dart';
|
import 'package:paperless_mobile/core/model/info_message_exception.dart';
|
||||||
import 'package:paperless_mobile/core/service/file_service.dart';
|
import 'package:paperless_mobile/core/service/file_service.dart';
|
||||||
import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart';
|
import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart';
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/constants.dart';
|
import 'package:paperless_mobile/constants.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/core/global/constants.dart';
|
import 'package:paperless_mobile/core/global/constants.dart';
|
||||||
import 'package:paperless_mobile/core/service/file_service.dart';
|
import 'package:paperless_mobile/core/service/file_service.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:animations/animations.dart';
|
import 'package:animations/animations.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.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/database/tables/local_user_app_state.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
||||||
import 'package:paperless_mobile/features/document_search/cubit/document_search_cubit.dart';
|
import 'package:paperless_mobile/features/document_search/cubit/document_search_cubit.dart';
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import 'dart:math' as math;
|
|||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_search/cubit/document_search_cubit.dart';
|
import 'package:paperless_mobile/features/document_search/cubit/document_search_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/document_search/view/remove_history_entry_dialog.dart';
|
import 'package:paperless_mobile/features/document_search/view/remove_history_entry_dialog.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/adaptive_documents_view.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/adaptive_documents_view.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.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/features/document_search/view/document_search_bar.dart';
|
import 'package:paperless_mobile/features/document_search/view/document_search_bar.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/manage_accounts_page.dart';
|
import 'package:paperless_mobile/features/settings/view/manage_accounts_page.dart';
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ import 'package:hive/hive.dart';
|
|||||||
import 'package:intl/date_symbol_data_local.dart';
|
import 'package:intl/date_symbol_data_local.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/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.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/logging/data/logger.dart';
|
import 'package:paperless_mobile/features/logging/data/logger.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/future_or_builder.dart';
|
import 'package:paperless_mobile/core/widgets/future_or_builder.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/document_upload/cubit/document_upload_cubit.dart';
|
import 'package:paperless_mobile/features/document_upload/cubit/document_upload_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/edit_label/view/impl/add_correspondent_page.dart';
|
import 'package:paperless_mobile/features/edit_label/view/impl/add_correspondent_page.dart';
|
||||||
import 'package:paperless_mobile/features/edit_label/view/impl/add_document_type_page.dart';
|
import 'package:paperless_mobile/features/edit_label/view/impl/add_document_type_page.dart';
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:hydrated_bloc/hydrated_bloc.dart';
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
||||||
|
import 'package:paperless_mobile/core/extensions/document_iterable_extensions.dart';
|
||||||
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||||
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
||||||
@@ -44,18 +45,15 @@ class DocumentsCubit extends Cubit<DocumentsState>
|
|||||||
replace(document);
|
replace(document);
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
selection: state.selection
|
selection:
|
||||||
.map((e) => e.id == document.id ? document : e)
|
state.selection.withDocumentreplaced(document).toList()),
|
||||||
.toList(),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
onDeleted: (document) {
|
onDeleted: (document) {
|
||||||
remove(document);
|
remove(document);
|
||||||
emit(
|
emit(
|
||||||
state.copyWith(
|
state.copyWith(
|
||||||
selection:
|
selection: state.selection.withDocumentRemoved(document).toList(),
|
||||||
state.selection.where((e) => e.id != document.id).toList(),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
import 'package:paperless_mobile/core/bloc/connectivity_cubit.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/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart';
|
import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart';
|
||||||
import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart';
|
import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart';
|
||||||
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/paged_document_view/cubit/paged_documents_state.dart';
|
import 'package:paperless_mobile/features/paged_document_view/cubit/paged_documents_state.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import 'package:flutter_html/flutter_html.dart';
|
|||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.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/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.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/repository/label_repository.dart';
|
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/items/document_item.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/items/document_item.dart';
|
||||||
import 'package:paperless_mobile/features/labels/correspondent/view/widgets/correspondent_widget.dart';
|
import 'package:paperless_mobile/features/labels/correspondent/view/widgets/correspondent_widget.dart';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart';
|
import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/placeholder/tags_placeholder.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/placeholder/tags_placeholder.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/placeholder/text_placeholder.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/placeholder/text_placeholder.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
|
|
||||||
class TagsPlaceholder extends StatelessWidget {
|
class TagsPlaceholder extends StatelessWidget {
|
||||||
static const _lengths = <double>[90, 70, 130];
|
static const _lengths = <double>[90, 70, 130];
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'dart:math';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/routes/typed/branches/saved_views_route.dart';
|
import 'package:paperless_mobile/routes/typed/branches/saved_views_route.dart';
|
||||||
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
|
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart';
|
import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/saved_views/saved_view_chip.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/saved_views/saved_view_chip.dart';
|
||||||
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart';
|
import 'package:paperless_mobile/features/saved_view/cubit/saved_view_cubit.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/translation/sort_field_localization_mapper.dart';
|
import 'package:paperless_mobile/core/translation/sort_field_localization_mapper.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
class SortFieldSelectionBottomSheet extends StatefulWidget {
|
class SortFieldSelectionBottomSheet extends StatefulWidget {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/selection/bulk_delete_confirmation_dialog.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/selection/bulk_delete_confirmation_dialog.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'package:go_router/go_router.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/translation/matching_algorithm_localization_mapper.dart';
|
import 'package:paperless_mobile/core/translation/matching_algorithm_localization_mapper.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
import 'package:paperless_mobile/helpers/message_helpers.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_extensions.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_extensions.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
||||||
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'dart:async';
|
|||||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/logging/data/logger.dart';
|
import 'package:paperless_mobile/features/logging/data/logger.dart';
|
||||||
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
import 'package:paperless_mobile/core/repository/label_repository.dart';
|
||||||
import 'package:paperless_mobile/core/repository/label_repository_state.dart';
|
import 'package:paperless_mobile/core/repository/label_repository_state.dart';
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
|||||||
import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_cancel_button.dart';
|
import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_cancel_button.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_confirm_button.dart';
|
import 'package:paperless_mobile/core/widgets/dialog_utils/dialog_confirm_button.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/hint_card.dart';
|
import 'package:paperless_mobile/core/widgets/hint_card.dart';
|
||||||
import 'package:paperless_mobile/extensions/dart_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/dart_extensions.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart';
|
import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart';
|
||||||
import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart';
|
import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart';
|
||||||
import 'package:paperless_mobile/features/inbox/cubit/inbox_cubit.dart';
|
import 'package:paperless_mobile/features/inbox/cubit/inbox_cubit.dart';
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ 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/widgets/shimmer_placeholder.dart';
|
import 'package:paperless_mobile/core/widgets/shimmer_placeholder.dart';
|
||||||
import 'package:paperless_mobile/core/workarounds/colored_chip.dart';
|
import 'package:paperless_mobile/core/workarounds/colored_chip.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/delete_document_confirmation_dialog.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/delete_document_confirmation_dialog.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/document_preview.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/placeholder/tags_placeholder.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/placeholder/tags_placeholder.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/edit_label/view/impl/add_tag_page.dart';
|
import 'package:paperless_mobile/features/edit_label/view/impl/add_tag_page.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
import 'package:paperless_mobile/routes/typed/branches/labels_route.dart';
|
import 'package:paperless_mobile/routes/typed/branches/labels_route.dart';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ 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/workarounds/colored_chip.dart';
|
import 'package:paperless_mobile/core/workarounds/colored_chip.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/labels/tags/view/widgets/fullscreen_tags_form.dart';
|
import 'package:paperless_mobile/features/labels/tags/view/widgets/fullscreen_tags_form.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.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/delegate/customizable_sliver_persistent_header_delegate.dart';
|
import 'package:paperless_mobile/core/delegate/customizable_sliver_persistent_header_delegate.dart';
|
||||||
import 'package:paperless_mobile/core/logging/data/logger.dart';
|
import 'package:paperless_mobile/features/logging/data/logger.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/material/colored_tab_bar.dart';
|
import 'package:paperless_mobile/core/widgets/material/colored_tab_bar.dart';
|
||||||
import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart';
|
import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart';
|
||||||
import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart';
|
import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
class FullscreenLabelForm<T extends Label> extends StatefulWidget {
|
class FullscreenLabelForm<T extends Label> extends StatefulWidget {
|
||||||
|
|||||||
@@ -4,7 +4,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:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/workarounds/colored_chip.dart';
|
import 'package:paperless_mobile/core/workarounds/colored_chip.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/labels/view/widgets/fullscreen_label_form.dart';
|
import 'package:paperless_mobile/features/labels/view/widgets/fullscreen_label_form.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
|||||||
import 'package:paperless_mobile/core/translation/matching_algorithm_localization_mapper.dart';
|
import 'package:paperless_mobile/core/translation/matching_algorithm_localization_mapper.dart';
|
||||||
import 'package:paperless_mobile/core/widgets/offline_widget.dart';
|
import 'package:paperless_mobile/core/widgets/offline_widget.dart';
|
||||||
import 'package:paperless_mobile/features/labels/view/widgets/label_item.dart';
|
import 'package:paperless_mobile/features/labels/view/widgets/label_item.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
|
|
||||||
class LabelTabView<T extends Label> extends StatelessWidget {
|
class LabelTabView<T extends Label> extends StatelessWidget {
|
||||||
final Map<int, T> labels;
|
final Map<int, T> labels;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
|||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/constants.dart';
|
import 'package:paperless_mobile/constants.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/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart';
|
import 'package:paperless_mobile/features/app_drawer/view/app_drawer.dart';
|
||||||
import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart';
|
import 'package:paperless_mobile/features/document_search/view/sliver_search_bar.dart';
|
||||||
import 'package:paperless_mobile/features/landing/view/widgets/expansion_card.dart';
|
import 'package:paperless_mobile/features/landing/view/widgets/expansion_card.dart';
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:paperless_mobile/core/logging/models/parsed_log_message.dart';
|
import 'package:paperless_mobile/features/logging/models/parsed_log_message.dart';
|
||||||
import 'package:paperless_mobile/core/service/file_service.dart';
|
import 'package:paperless_mobile/core/service/file_service.dart';
|
||||||
|
import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart';
|
||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
|
import 'package:permission_handler/permission_handler.dart';
|
||||||
import 'package:rxdart/rxdart.dart';
|
import 'package:rxdart/rxdart.dart';
|
||||||
part 'app_logs_state.dart';
|
part 'app_logs_state.dart';
|
||||||
|
|
||||||
@@ -16,7 +18,11 @@ final _fileNameFormat = DateFormat("yyyy-MM-dd");
|
|||||||
|
|
||||||
class AppLogsCubit extends Cubit<AppLogsState> {
|
class AppLogsCubit extends Cubit<AppLogsState> {
|
||||||
StreamSubscription? _fileChangesSubscription;
|
StreamSubscription? _fileChangesSubscription;
|
||||||
AppLogsCubit(DateTime date) : super(AppLogsStateInitial(date: date));
|
final LocalNotificationService _localNotificationService;
|
||||||
|
AppLogsCubit(
|
||||||
|
DateTime date,
|
||||||
|
this._localNotificationService,
|
||||||
|
) : super(AppLogsStateInitial(date: date));
|
||||||
|
|
||||||
Future<void> loadLogs(DateTime date) async {
|
Future<void> loadLogs(DateTime date) async {
|
||||||
if (date == state.date) {
|
if (date == state.date) {
|
||||||
@@ -42,24 +48,12 @@ class AppLogsCubit extends Cubit<AppLogsState> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final logs = await logFile.readAsLines();
|
_updateLogsFromFile(logFile, date, availableLogs);
|
||||||
final parsedLogs =
|
|
||||||
ParsedLogMessage.parse(logs.skip(2000).toList()).reversed.toList();
|
|
||||||
_fileChangesSubscription = logFile.watch().listen((event) async {
|
_fileChangesSubscription = logFile.watch().listen((event) async {
|
||||||
if (!isClosed) {
|
if (!isClosed) {
|
||||||
final logs = await logFile.readAsLines();
|
_updateLogsFromFile(logFile, date, availableLogs);
|
||||||
emit(AppLogsStateLoaded(
|
|
||||||
date: date,
|
|
||||||
logs: parsedLogs,
|
|
||||||
availableLogs: availableLogs,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
emit(AppLogsStateLoaded(
|
|
||||||
date: date,
|
|
||||||
logs: parsedLogs,
|
|
||||||
availableLogs: availableLogs,
|
|
||||||
));
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(AppLogsStateError(
|
emit(AppLogsStateError(
|
||||||
error: e,
|
error: e,
|
||||||
@@ -68,6 +62,17 @@ class AppLogsCubit extends Cubit<AppLogsState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _updateLogsFromFile(
|
||||||
|
File file, DateTime date, List<DateTime> availableLogs) async {
|
||||||
|
final logs = await file.readAsLines();
|
||||||
|
final parsedLogs = ParsedLogMessage.parse(logs).reversed.toList();
|
||||||
|
emit(AppLogsStateLoaded(
|
||||||
|
date: date,
|
||||||
|
logs: parsedLogs,
|
||||||
|
availableLogs: availableLogs,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> clearLogs(DateTime date) async {
|
Future<void> clearLogs(DateTime date) async {
|
||||||
final logFile = _getLogfile(date);
|
final logFile = _getLogfile(date);
|
||||||
await logFile.writeAsString('');
|
await logFile.writeAsString('');
|
||||||
@@ -86,16 +91,19 @@ class AppLogsCubit extends Cubit<AppLogsState> {
|
|||||||
Future<void> saveLogs(DateTime date, String locale) async {
|
Future<void> saveLogs(DateTime date, String locale) async {
|
||||||
var formattedDate = _fileNameFormat.format(date);
|
var formattedDate = _fileNameFormat.format(date);
|
||||||
final filename = 'paperless_mobile_logs_$formattedDate.log';
|
final filename = 'paperless_mobile_logs_$formattedDate.log';
|
||||||
final parentDir = await FilePicker.platform.getDirectoryPath(
|
// final parentDir = await FilePicker.platform.getDirectoryPath(
|
||||||
dialogTitle: "Save log from ${DateFormat.yMd(locale).format(date)}",
|
// dialogTitle: "Save log from ${DateFormat.yMd(locale).format(date)}",
|
||||||
initialDirectory: Platform.isAndroid
|
// initialDirectory: Platform.isAndroid
|
||||||
? FileService.instance.downloadsDirectory.path
|
// ? FileService.instance.downloadsDirectory.path
|
||||||
: null,
|
// : null,
|
||||||
);
|
// );
|
||||||
|
// if (parentDir == null) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
final logFile = _getLogfile(date);
|
final logFile = _getLogfile(date);
|
||||||
if (parentDir != null) {
|
final parentDir = FileService.instance.downloadsDirectory;
|
||||||
await logFile.copy(p.join(parentDir, filename));
|
final downloadedFile = await logFile.copy(p.join(parentDir.path, filename));
|
||||||
}
|
_localNotificationService.notifyFileDownload(filePath: downloadedFile.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
File _getLogfile(DateTime date) {
|
File _getLogfile(DateTime date) {
|
||||||
@@ -104,8 +112,8 @@ class AppLogsCubit extends Cubit<AppLogsState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> close() {
|
Future<void> close() async {
|
||||||
_fileChangesSubscription?.cancel();
|
await _fileChangesSubscription?.cancel();
|
||||||
return super.close();
|
return super.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
import 'package:paperless_mobile/core/logging/models/formatted_log_message.dart';
|
import 'package:paperless_mobile/features/logging/models/formatted_log_message.dart';
|
||||||
|
|
||||||
class FormattedPrinter extends LogPrinter {
|
class FormattedPrinter extends LogPrinter {
|
||||||
static final _timestampFormat = DateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
static final _timestampFormat = DateFormat("yyyy-MM-dd HH:mm:ss.SSS");
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
import 'package:paperless_mobile/core/logging/models/formatted_log_message.dart';
|
import 'package:paperless_mobile/features/logging/models/formatted_log_message.dart';
|
||||||
|
|
||||||
late Logger logger;
|
late Logger logger;
|
||||||
|
|
||||||
@@ -9,8 +9,9 @@ import 'package:paperless_mobile/core/service/file_service.dart';
|
|||||||
import 'package:path/path.dart' as p;
|
import 'package:path/path.dart' as p;
|
||||||
import 'package:synchronized/synchronized.dart';
|
import 'package:synchronized/synchronized.dart';
|
||||||
|
|
||||||
|
typedef f = FileOutput;
|
||||||
|
|
||||||
class MirroredFileOutput extends LogOutput {
|
class MirroredFileOutput extends LogOutput {
|
||||||
final Completer _initCompleter = Completer();
|
|
||||||
var lock = Lock();
|
var lock = Lock();
|
||||||
MirroredFileOutput();
|
MirroredFileOutput();
|
||||||
|
|
||||||
@@ -22,7 +23,6 @@ class MirroredFileOutput extends LogOutput {
|
|||||||
final logDir = FileService.instance.logDirectory;
|
final logDir = FileService.instance.logDirectory;
|
||||||
file = File(p.join(logDir.path, '$today.log'));
|
file = File(p.join(logDir.path, '$today.log'));
|
||||||
debugPrint("Logging files to ${file.path}.");
|
debugPrint("Logging files to ${file.path}.");
|
||||||
_initCompleter.complete();
|
|
||||||
try {
|
try {
|
||||||
final oldLogs = await FileService.instance.getAllFiles(logDir);
|
final oldLogs = await FileService.instance.getAllFiles(logDir);
|
||||||
if (oldLogs.length > 10) {
|
if (oldLogs.length > 10) {
|
||||||
@@ -42,12 +42,10 @@ class MirroredFileOutput extends LogOutput {
|
|||||||
await lock.synchronized(() async {
|
await lock.synchronized(() async {
|
||||||
for (var line in event.lines) {
|
for (var line in event.lines) {
|
||||||
debugPrint(line);
|
debugPrint(line);
|
||||||
if (_initCompleter.isCompleted) {
|
await file.writeAsString(
|
||||||
await file.writeAsString(
|
"$line${Platform.lineTerminator}",
|
||||||
"$line${Platform.lineTerminator}",
|
mode: FileMode.append,
|
||||||
mode: FileMode.append,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -40,12 +40,13 @@ class ParsedErrorLogMessage {
|
|||||||
static bool canConsumeFirstLine(String line) =>
|
static bool canConsumeFirstLine(String line) =>
|
||||||
_errorBeginPattern.hasMatch(line);
|
_errorBeginPattern.hasMatch(line);
|
||||||
|
|
||||||
static (int consumedLines, ParsedErrorLogMessage result) consume(
|
static (int consumedLines, ParsedErrorLogMessage? result) consume(
|
||||||
List<String> log) {
|
List<String> log) {
|
||||||
assert(log.isNotEmpty && canConsumeFirstLine(log.first));
|
assert(log.isNotEmpty && canConsumeFirstLine(log.first));
|
||||||
String errorText = "";
|
String errorText = "";
|
||||||
int currentLine =
|
int currentLine =
|
||||||
1; // Skip first because we know that the first line is ---BEGIN ERROR---
|
1; // Skip first because we know that the first line is ---BEGIN ERROR---
|
||||||
|
|
||||||
while (!_errorEndPattern.hasMatch(log[currentLine])) {
|
while (!_errorEndPattern.hasMatch(log[currentLine])) {
|
||||||
errorText += log[currentLine] + _newLine;
|
errorText += log[currentLine] + _newLine;
|
||||||
currentLine++;
|
currentLine++;
|
||||||
@@ -3,10 +3,10 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:logger/logger.dart';
|
import 'package:logger/logger.dart';
|
||||||
import 'package:paperless_mobile/core/logging/cubit/app_logs_cubit.dart';
|
import 'package:paperless_mobile/features/logging/cubit/app_logs_cubit.dart';
|
||||||
import 'package:paperless_mobile/core/logging/models/parsed_log_message.dart';
|
import 'package:paperless_mobile/features/logging/models/parsed_log_message.dart';
|
||||||
import 'package:paperless_mobile/extensions/dart_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/dart_extensions.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
class AppLogsPage extends StatefulWidget {
|
class AppLogsPage extends StatefulWidget {
|
||||||
@@ -134,9 +134,8 @@ class _AppLogsPageState extends State<AppLogsPage> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
AppLogsStateError() => Center(
|
AppLogsStateError() => Center(
|
||||||
child: Text(
|
child:
|
||||||
S.of(context)!.couldNotLoadLogfileFrom(formattedDate),
|
Text(S.of(context)!.couldNotLoadLogfileFrom(formattedDate)),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
_ => _buildLoadingLogs(state.date)
|
_ => _buildLoadingLogs(state.date)
|
||||||
},
|
},
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
import 'package:dio/dio.dart';
|
import 'package:dio/dio.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_extensions.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_extensions.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.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/database/tables/local_user_app_state.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
||||||
@@ -14,8 +13,8 @@ import 'package:paperless_mobile/core/database/tables/local_user_settings.dart';
|
|||||||
import 'package:paperless_mobile/core/database/tables/user_credentials.dart';
|
import 'package:paperless_mobile/core/database/tables/user_credentials.dart';
|
||||||
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
||||||
import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart';
|
import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart';
|
||||||
import 'package:paperless_mobile/core/logging/data/logger.dart';
|
import 'package:paperless_mobile/features/logging/data/logger.dart';
|
||||||
import 'package:paperless_mobile/core/logging/utils/redaction_utils.dart';
|
import 'package:paperless_mobile/features/logging/utils/redaction_utils.dart';
|
||||||
import 'package:paperless_mobile/core/model/info_message_exception.dart';
|
import 'package:paperless_mobile/core/model/info_message_exception.dart';
|
||||||
import 'package:paperless_mobile/core/security/session_manager.dart';
|
import 'package:paperless_mobile/core/security/session_manager.dart';
|
||||||
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
||||||
|
|
||||||
part 'authentication_information.g.dart';
|
part 'authentication_information.g.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
|
|
||||||
part 'client_certificate.g.dart';
|
part 'client_certificate.g.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import 'package:paperless_api/paperless_api.dart';
|
|||||||
import 'package:paperless_mobile/core/exception/server_message_exception.dart';
|
import 'package:paperless_mobile/core/exception/server_message_exception.dart';
|
||||||
import 'package:paperless_mobile/core/model/info_message_exception.dart';
|
import 'package:paperless_mobile/core/model/info_message_exception.dart';
|
||||||
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
import 'package:paperless_mobile/features/login/model/client_certificate.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/client_certificate_form_model.dart';
|
import 'package:paperless_mobile/features/login/model/client_certificate_form_model.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_extensions.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_extensions.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
import 'package:paperless_mobile/core/model/info_message_exception.dart';
|
import 'package:paperless_mobile/core/model/info_message_exception.dart';
|
||||||
import 'package:paperless_mobile/features/app_intro/application_intro_slideshow.dart';
|
import 'package:paperless_mobile/features/app_intro/application_intro_slideshow.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_extensions.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/users/view/widgets/user_account_list_tile.dart';
|
import 'package:paperless_mobile/features/users/view/widgets/user_account_list_tile.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
|
import 'package:paperless_mobile/routes/typed/shells/authenticated_route.dart';
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import 'dart:typed_data';
|
|||||||
import 'package:file_picker/file_picker.dart';
|
import 'package:file_picker/file_picker.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/client_certificate_form_model.dart';
|
import 'package:paperless_mobile/features/login/model/client_certificate_form_model.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
|
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_extensions.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_extensions.dart';
|
||||||
|
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
import 'package:paperless_mobile/features/login/model/login_form_credentials.dart';
|
||||||
import 'package:paperless_mobile/features/login/view/widgets/form_fields/obscured_input_text_form_field.dart';
|
import 'package:paperless_mobile/features/login/view/widgets/form_fields/obscured_input_text_form_field.dart';
|
||||||
import 'package:paperless_mobile/features/login/view/widgets/form_fields/server_address_form_field.dart';
|
import 'package:paperless_mobile/features/login/view/widgets/form_fields/server_address_form_field.dart';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/theme.dart';
|
import 'package:paperless_mobile/theme.dart';
|
||||||
|
|
||||||
class LoginTransitionPage extends StatelessWidget {
|
class LoginTransitionPage extends StatelessWidget {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:paperless_mobile/features/notifications/models/notification_actions.dart';
|
import 'package:paperless_mobile/features/notifications/models/notification_actions.dart';
|
||||||
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/notification_tap_response_payload.dart';
|
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/notification_tap_response_payload.dart';
|
||||||
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/open_downloaded_document_payload.dart';
|
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/open_directory_notification_response_payload.dart';
|
||||||
|
|
||||||
class NotificationTapResponsePayloadConverter
|
class NotificationTapResponsePayloadConverter
|
||||||
implements
|
implements
|
||||||
@@ -11,8 +11,8 @@ class NotificationTapResponsePayloadConverter
|
|||||||
NotificationTapResponsePayload fromJson(Map<String, dynamic> json) {
|
NotificationTapResponsePayload fromJson(Map<String, dynamic> json) {
|
||||||
final type = NotificationResponseOpenAction.values.byName(json['type']);
|
final type = NotificationResponseOpenAction.values.byName(json['type']);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NotificationResponseOpenAction.openDownloadedDocumentPath:
|
case NotificationResponseOpenAction.openDirectory:
|
||||||
return OpenDownloadedDocumentPayload.fromJson(
|
return OpenDirectoryNotificationResponsePayload.fromJson(
|
||||||
json,
|
json,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,5 +7,5 @@ enum NotificationResponseButtonAction {
|
|||||||
|
|
||||||
@JsonEnum()
|
@JsonEnum()
|
||||||
enum NotificationResponseOpenAction {
|
enum NotificationResponseOpenAction {
|
||||||
openDownloadedDocumentPath;
|
openDirectory;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
enum NotificationChannel {
|
enum NotificationChannel {
|
||||||
task("task_channel", "Paperless tasks"),
|
task("task_channel", "Paperless tasks"),
|
||||||
documentDownload("document_download_channel", "Document downloads");
|
documentDownload("document_download_channel", "Document downloads"),
|
||||||
|
fileDownload("file_download_channel", "File downloads");
|
||||||
|
|
||||||
final String id;
|
final String id;
|
||||||
final String name;
|
final String name;
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
import 'package:paperless_mobile/features/notifications/models/notification_actions.dart';
|
||||||
|
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/notification_tap_response_payload.dart';
|
||||||
|
|
||||||
|
part 'open_directory_notification_response_payload.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class OpenDirectoryNotificationResponsePayload
|
||||||
|
extends NotificationTapResponsePayload {
|
||||||
|
final String filePath;
|
||||||
|
OpenDirectoryNotificationResponsePayload({
|
||||||
|
required this.filePath,
|
||||||
|
super.type = NotificationResponseOpenAction.openDirectory,
|
||||||
|
});
|
||||||
|
|
||||||
|
factory OpenDirectoryNotificationResponsePayload.fromJson(
|
||||||
|
Map<String, dynamic> json) =>
|
||||||
|
_$OpenDirectoryNotificationResponsePayloadFromJson(json);
|
||||||
|
@override
|
||||||
|
Map<String, dynamic> toJson() =>
|
||||||
|
_$OpenDirectoryNotificationResponsePayloadToJson(this);
|
||||||
|
}
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
|
||||||
import 'package:paperless_mobile/features/notifications/models/notification_actions.dart';
|
|
||||||
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/notification_tap_response_payload.dart';
|
|
||||||
|
|
||||||
part 'open_downloaded_document_payload.g.dart';
|
|
||||||
|
|
||||||
@JsonSerializable()
|
|
||||||
class OpenDownloadedDocumentPayload extends NotificationTapResponsePayload {
|
|
||||||
final String filePath;
|
|
||||||
OpenDownloadedDocumentPayload({
|
|
||||||
required this.filePath,
|
|
||||||
super.type = NotificationResponseOpenAction.openDownloadedDocumentPath,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory OpenDownloadedDocumentPayload.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$OpenDownloadedDocumentPayloadFromJson(json);
|
|
||||||
@override
|
|
||||||
Map<String, dynamic> toJson() => _$OpenDownloadedDocumentPayloadToJson(this);
|
|
||||||
}
|
|
||||||
@@ -6,10 +6,10 @@ import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
|||||||
import 'package:open_filex/open_filex.dart';
|
import 'package:open_filex/open_filex.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/features/notifications/converters/notification_tap_response_payload.dart';
|
import 'package:paperless_mobile/features/notifications/converters/notification_tap_response_payload.dart';
|
||||||
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_action/create_document_success_payload.dart';
|
|
||||||
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/open_downloaded_document_payload.dart';
|
|
||||||
import 'package:paperless_mobile/features/notifications/models/notification_actions.dart';
|
import 'package:paperless_mobile/features/notifications/models/notification_actions.dart';
|
||||||
import 'package:paperless_mobile/features/notifications/models/notification_channels.dart';
|
import 'package:paperless_mobile/features/notifications/models/notification_channels.dart';
|
||||||
|
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_action/create_document_success_payload.dart';
|
||||||
|
import 'package:paperless_mobile/features/notifications/models/notification_payloads/notification_tap/open_directory_notification_response_payload.dart';
|
||||||
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
import 'package:paperless_mobile/generated/l10n/app_localizations.dart';
|
||||||
|
|
||||||
class LocalNotificationService {
|
class LocalNotificationService {
|
||||||
@@ -48,6 +48,31 @@ class LocalNotificationService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> notifyFileDownload({
|
Future<void> notifyFileDownload({
|
||||||
|
required String filePath,
|
||||||
|
}) async {
|
||||||
|
await _plugin.show(
|
||||||
|
filePath.hashCode,
|
||||||
|
filePath,
|
||||||
|
"File download complete.",
|
||||||
|
NotificationDetails(
|
||||||
|
android: AndroidNotificationDetails(
|
||||||
|
NotificationChannel.fileDownload.id + "_${filePath.hashCode}",
|
||||||
|
NotificationChannel.fileDownload.name,
|
||||||
|
importance: Importance.max,
|
||||||
|
priority: Priority.high,
|
||||||
|
showProgress: false,
|
||||||
|
when: DateTime.now().millisecondsSinceEpoch,
|
||||||
|
category: AndroidNotificationCategory.status,
|
||||||
|
icon: 'file_download_done',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
payload: jsonEncode(
|
||||||
|
OpenDirectoryNotificationResponsePayload(filePath: filePath)
|
||||||
|
.toJson()),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> notifyDocumentDownload({
|
||||||
required DocumentModel document,
|
required DocumentModel document,
|
||||||
required String filename,
|
required String filename,
|
||||||
required String filePath,
|
required String filePath,
|
||||||
@@ -89,7 +114,7 @@ class LocalNotificationService {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
payload: jsonEncode(
|
payload: jsonEncode(
|
||||||
OpenDownloadedDocumentPayload(
|
OpenDirectoryNotificationResponsePayload(
|
||||||
filePath: filePath,
|
filePath: filePath,
|
||||||
).toJson(),
|
).toJson(),
|
||||||
),
|
),
|
||||||
@@ -139,7 +164,7 @@ class LocalNotificationService {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
payload: jsonEncode(
|
payload: jsonEncode(
|
||||||
OpenDownloadedDocumentPayload(filePath: filePath).toJson(),
|
OpenDirectoryNotificationResponsePayload(filePath: filePath).toJson(),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -281,9 +306,10 @@ class LocalNotificationService {
|
|||||||
NotificationResponse response,
|
NotificationResponse response,
|
||||||
) {
|
) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NotificationResponseOpenAction.openDownloadedDocumentPath:
|
case NotificationResponseOpenAction.openDirectory:
|
||||||
final payload = OpenDownloadedDocumentPayload.fromJson(
|
final payload = OpenDirectoryNotificationResponsePayload.fromJson(
|
||||||
jsonDecode(response.payload!));
|
jsonDecode(response.payload!),
|
||||||
|
);
|
||||||
OpenFilex.open(payload.filePath);
|
OpenFilex.open(payload.filePath);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
|
import 'package:collection/collection.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
|
import 'package:paperless_mobile/core/extensions/document_iterable_extensions.dart';
|
||||||
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
||||||
|
|
||||||
part 'saved_view_preview_state.dart';
|
part 'saved_view_preview_state.dart';
|
||||||
@@ -8,11 +11,55 @@ class SavedViewPreviewCubit extends Cubit<SavedViewPreviewState> {
|
|||||||
final PaperlessDocumentsApi _api;
|
final PaperlessDocumentsApi _api;
|
||||||
final SavedView view;
|
final SavedView view;
|
||||||
final ConnectivityStatusService _connectivityStatusService;
|
final ConnectivityStatusService _connectivityStatusService;
|
||||||
|
final DocumentChangedNotifier _changedNotifier;
|
||||||
SavedViewPreviewCubit(
|
SavedViewPreviewCubit(
|
||||||
this._api,
|
this._api,
|
||||||
this._connectivityStatusService, {
|
this._connectivityStatusService,
|
||||||
|
this._changedNotifier, {
|
||||||
required this.view,
|
required this.view,
|
||||||
}) : super(const InitialSavedViewPreviewState());
|
}) : super(const InitialSavedViewPreviewState()) {
|
||||||
|
_changedNotifier.addListener(
|
||||||
|
this,
|
||||||
|
onDeleted: (document) {
|
||||||
|
final s = state;
|
||||||
|
if (s is! LoadedSavedViewPreviewState) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!s.documents.containsDocument(document)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emit(
|
||||||
|
LoadedSavedViewPreviewState(
|
||||||
|
documents: s.documents.withDocumentRemoved(document).toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
onUpdated: (document) {
|
||||||
|
final s = state;
|
||||||
|
if (s is! LoadedSavedViewPreviewState) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!s.documents.containsDocument(document)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final shouldRemainInFilter = view.toDocumentFilter().matches(document);
|
||||||
|
if (!shouldRemainInFilter) {
|
||||||
|
emit(
|
||||||
|
LoadedSavedViewPreviewState(
|
||||||
|
documents: s.documents.withDocumentRemoved(document).toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
emit(
|
||||||
|
LoadedSavedViewPreviewState(
|
||||||
|
documents: s.documents.withDocumentreplaced(document).toList(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> initialize() async {
|
Future<void> initialize() async {
|
||||||
final isConnected =
|
final isConnected =
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/extensions/flutter_extensions.dart';
|
import 'package:paperless_mobile/core/extensions/flutter_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
import 'package:paperless_mobile/features/documents/cubit/documents_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/documents/view/widgets/items/document_list_item.dart';
|
import 'package:paperless_mobile/features/documents/view/widgets/items/document_list_item.dart';
|
||||||
import 'package:paperless_mobile/features/landing/view/widgets/expansion_card.dart';
|
import 'package:paperless_mobile/features/landing/view/widgets/expansion_card.dart';
|
||||||
@@ -24,6 +24,7 @@ class SavedViewPreview extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Provider(
|
return Provider(
|
||||||
create: (context) => SavedViewPreviewCubit(
|
create: (context) => SavedViewPreviewCubit(
|
||||||
|
context.read(),
|
||||||
context.read(),
|
context.read(),
|
||||||
context.read(),
|
context.read(),
|
||||||
view: savedView,
|
view: savedView,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
|
|
||||||
part 'color_scheme_option.g.dart';
|
part 'color_scheme_option.g.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
|
|
||||||
part 'file_download_type.g.dart';
|
part 'file_download_type.g.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
|
|
||||||
part 'view_type.g.dart';
|
part 'view_type.g.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_extensions.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_extensions.dart';
|
||||||
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
import 'package:paperless_mobile/features/login/cubit/authentication_cubit.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/dialogs/switch_account_dialog.dart';
|
import 'package:paperless_mobile/features/settings/view/dialogs/switch_account_dialog.dart';
|
||||||
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
import 'package:paperless_mobile/features/settings/view/widgets/global_settings_builder.dart';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
|
|
||||||
class GlobalSettingsBuilder extends StatelessWidget {
|
class GlobalSettingsBuilder extends StatelessWidget {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.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/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
||||||
|
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import 'package:fluttertoast/fluttertoast.dart';
|
|||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_extensions.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_extensions.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/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import 'package:package_info_plus/package_info_plus.dart';
|
|||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/constants.dart';
|
import 'package:paperless_mobile/constants.dart';
|
||||||
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.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/database/tables/local_user_app_state.dart';
|
import 'package:paperless_mobile/core/database/tables/local_user_app_state.dart';
|
||||||
@@ -29,9 +29,9 @@ import 'package:paperless_mobile/core/exception/server_message_exception.dart';
|
|||||||
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
||||||
import 'package:paperless_mobile/core/factory/paperless_api_factory_impl.dart';
|
import 'package:paperless_mobile/core/factory/paperless_api_factory_impl.dart';
|
||||||
import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart';
|
import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart';
|
||||||
import 'package:paperless_mobile/core/logging/data/formatted_printer.dart';
|
import 'package:paperless_mobile/features/logging/data/formatted_printer.dart';
|
||||||
import 'package:paperless_mobile/core/logging/data/logger.dart';
|
import 'package:paperless_mobile/features/logging/data/logger.dart';
|
||||||
import 'package:paperless_mobile/core/logging/data/mirrored_file_output.dart';
|
import 'package:paperless_mobile/features/logging/data/mirrored_file_output.dart';
|
||||||
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
import 'package:paperless_mobile/core/notifier/document_changed_notifier.dart';
|
||||||
import 'package:paperless_mobile/core/security/session_manager.dart';
|
import 'package:paperless_mobile/core/security/session_manager.dart';
|
||||||
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
import 'package:paperless_mobile/core/service/connectivity_status_service.dart';
|
||||||
@@ -129,6 +129,7 @@ void main() async {
|
|||||||
output: MirroredFileOutput(),
|
output: MirroredFileOutput(),
|
||||||
printer: FormattedPrinter(),
|
printer: FormattedPrinter(),
|
||||||
level: l.Level.trace,
|
level: l.Level.trace,
|
||||||
|
filter: l.ProductionFilter(),
|
||||||
);
|
);
|
||||||
Paint.enableDithering = true;
|
Paint.enableDithering = true;
|
||||||
|
|
||||||
@@ -236,6 +237,12 @@ void main() async {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}, (error, stackTrace) {
|
}, (error, stackTrace) {
|
||||||
|
if (error is StateError &&
|
||||||
|
error.message.contains("Cannot emit new states")) {
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
// Catches all unexpected/uncaught errors and prints them to the console.
|
// Catches all unexpected/uncaught errors and prints them to the console.
|
||||||
final message = switch (error) {
|
final message = switch (error) {
|
||||||
PaperlessApiException e => e.details ?? error.toString(),
|
PaperlessApiException e => e.details ?? error.toString(),
|
||||||
@@ -332,12 +339,6 @@ class _GoRouterShellState extends State<GoRouterShell> {
|
|||||||
if (context.canPop()) {
|
if (context.canPop()) {
|
||||||
context.pop();
|
context.pop();
|
||||||
}
|
}
|
||||||
// LoginRoute(
|
|
||||||
// $extra: errorState.clientCertificate,
|
|
||||||
// password: errorState.password,
|
|
||||||
// serverUrl: errorState.serverUrl,
|
|
||||||
// username: errorState.username,
|
|
||||||
// ).go(context);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hive_flutter/adapters.dart';
|
import 'package:hive_flutter/adapters.dart';
|
||||||
import 'package:paperless_api/paperless_api.dart';
|
import 'package:paperless_api/paperless_api.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.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/factory/paperless_api_factory.dart';
|
import 'package:paperless_mobile/core/factory/paperless_api_factory.dart';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:paperless_mobile/core/config/hive/hive_config.dart';
|
import 'package:paperless_mobile/core/database/hive/hive_config.dart';
|
||||||
import 'package:paperless_mobile/core/database/tables/global_settings.dart';
|
import 'package:paperless_mobile/core/database/tables/global_settings.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/features/home/view/scaffold_with_navigation_bar.dart';
|
import 'package:paperless_mobile/features/home/view/scaffold_with_navigation_bar.dart';
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user