Externalized API and models as own package

This commit is contained in:
Anton Stubenbord
2022-12-02 01:48:13 +01:00
parent 60d1a2e62a
commit ec7707e4a4
143 changed files with 1496 additions and 1339 deletions

5
.gitignore vendored
View File

@@ -56,4 +56,7 @@ di_initializer.config.dart
# l10n generated files: # l10n generated files:
lib/generated/* lib/generated/*
untranslated_messages.txt untranslated_messages.txt
#lakos generated files
**/dot_images/*

View File

@@ -0,0 +1,17 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
void main() {
final binding = IntegrationTestWidgetsFlutterBinding.ensureInitialized();
testWidgets('screenshot', (WidgetTester tester) async {
// Build the app.
// This is required prior to taking the screenshot (Android only).
await binding.convertFlutterSurfaceToImage();
// Trigger a frame.
await tester.pumpAndSettle();
await binding.takeScreenshot('screenshot-1');
});
}

View File

@@ -1,17 +1,21 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:paperless_mobile/core/model/paperless_server_information.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/service/paperless_server_information_service.dart'; import 'package:paperless_mobile/core/bloc/paperless_server_information_state.dart';
@singleton @singleton
class PaperlessServerInformationCubit class PaperlessServerInformationCubit
extends Cubit<PaperlessServerInformation> { extends Cubit<PaperlessServerInformationState> {
final PaperlessServerInformationService service; final PaperlessServerStatsApi service;
PaperlessServerInformationCubit(this.service) PaperlessServerInformationCubit(this.service)
: super(PaperlessServerInformation()); : super(PaperlessServerInformationState());
Future<void> updateInformtion() async { Future<void> updateInformtion() async {
emit(await service.getInformation()); final information = await service.getServerInformation();
emit(PaperlessServerInformationState(
isLoaded: true,
information: information,
));
} }
} }

View File

@@ -0,0 +1,11 @@
import 'package:paperless_api/paperless_api.dart';
class PaperlessServerInformationState {
final bool isLoaded;
final PaperlessServerInformationModel? information;
PaperlessServerInformationState({
this.isLoaded = false,
this.information,
});
}

View File

@@ -1,35 +1,32 @@
import 'dart:developer'; import 'dart:developer';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart'; import 'package:paperless_mobile/core/store/local_vault.dart';
import 'package:http_interceptor/http_interceptor.dart'; import 'package:http_interceptor/http_interceptor.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
@injectable @injectable
class AuthenticationInterceptor implements InterceptorContract { class AuthenticationInterceptor implements InterceptorContract {
AuthenticationCubit authenticationCubit; final LocalVault _localVault;
AuthenticationInterceptor(this.authenticationCubit); AuthenticationInterceptor(this._localVault);
@override @override
Future<BaseRequest> interceptRequest({required BaseRequest request}) async { Future<BaseRequest> interceptRequest({required BaseRequest request}) async {
final authState = authenticationCubit.state; final auth = await _localVault.loadAuthenticationInformation();
if (kDebugMode) { if (kDebugMode) {
log("Intercepted ${request.method} request to ${request.url.toString()}"); log("Intercepted ${request.method} request to ${request.url.toString()}");
} }
if (authState.authentication == null) { if (auth == null) {
throw const ErrorMessage(ErrorCode.notAuthenticated); throw const PaperlessServerException(ErrorCode.notAuthenticated);
} }
return request.copyWith( return request.copyWith(
//Append server Url //Append server Url
url: Uri.parse( url: Uri.parse(auth.serverUrl + request.url.toString()),
authState.authentication!.serverUrl + request.url.toString()), headers: auth.token.isEmpty
headers: authState.authentication!.token.isEmpty
? request.headers ? request.headers
: { : {...request.headers, 'Authorization': 'Token ${auth.token}'},
...request.headers,
'Authorization': 'Token ${authState.authentication!.token}'
},
); );
} }

View File

@@ -1,5 +1,5 @@
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
String translateError(BuildContext context, ErrorCode code) { String translateError(BuildContext context, ErrorCode code) {

View File

@@ -2,7 +2,7 @@ import 'dart:typed_data';
import 'dart:convert'; import 'dart:convert';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.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/core/type/types.dart'; import 'package:paperless_mobile/core/type/types.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
@@ -24,8 +24,8 @@ class TimeoutClient implements BaseClient {
Future<StreamedResponse> send(BaseRequest request) async { Future<StreamedResponse> send(BaseRequest request) async {
return getIt<BaseClient>().send(request).timeout( return getIt<BaseClient>().send(request).timeout(
requestTimeout, requestTimeout,
onTimeout: () => onTimeout: () => Future.error(
Future.error(const ErrorMessage(ErrorCode.requestTimedOut)), const PaperlessServerException(ErrorCode.requestTimedOut)),
); );
} }
@@ -47,8 +47,8 @@ class TimeoutClient implements BaseClient {
.delete(url, headers: headers, body: body, encoding: encoding) .delete(url, headers: headers, body: body, encoding: encoding)
.timeout( .timeout(
requestTimeout, requestTimeout,
onTimeout: () => onTimeout: () => Future.error(
Future.error(const ErrorMessage(ErrorCode.requestTimedOut)), const PaperlessServerException(ErrorCode.requestTimedOut)),
), ),
); );
} }
@@ -62,8 +62,8 @@ class TimeoutClient implements BaseClient {
return _handle400Error( return _handle400Error(
await getIt<BaseClient>().get(url, headers: headers).timeout( await getIt<BaseClient>().get(url, headers: headers).timeout(
requestTimeout, requestTimeout,
onTimeout: () => onTimeout: () => Future.error(
Future.error(const ErrorMessage(ErrorCode.requestTimedOut)), const PaperlessServerException(ErrorCode.requestTimedOut)),
), ),
); );
} }
@@ -77,8 +77,8 @@ class TimeoutClient implements BaseClient {
return _handle400Error( return _handle400Error(
await getIt<BaseClient>().head(url, headers: headers).timeout( await getIt<BaseClient>().head(url, headers: headers).timeout(
requestTimeout, requestTimeout,
onTimeout: () => onTimeout: () => Future.error(
Future.error(const ErrorMessage(ErrorCode.requestTimedOut)), const PaperlessServerException(ErrorCode.requestTimedOut)),
), ),
); );
} }
@@ -96,8 +96,8 @@ class TimeoutClient implements BaseClient {
.patch(url, headers: headers, body: body, encoding: encoding) .patch(url, headers: headers, body: body, encoding: encoding)
.timeout( .timeout(
requestTimeout, requestTimeout,
onTimeout: () => onTimeout: () => Future.error(
Future.error(const ErrorMessage(ErrorCode.requestTimedOut)), const PaperlessServerException(ErrorCode.requestTimedOut)),
), ),
); );
} }
@@ -115,8 +115,8 @@ class TimeoutClient implements BaseClient {
.post(url, headers: headers, body: body, encoding: encoding) .post(url, headers: headers, body: body, encoding: encoding)
.timeout( .timeout(
requestTimeout, requestTimeout,
onTimeout: () => onTimeout: () => Future.error(
Future.error(const ErrorMessage(ErrorCode.requestTimedOut)), const PaperlessServerException(ErrorCode.requestTimedOut)),
), ),
); );
} }
@@ -134,8 +134,8 @@ class TimeoutClient implements BaseClient {
.put(url, headers: headers, body: body, encoding: encoding) .put(url, headers: headers, body: body, encoding: encoding)
.timeout( .timeout(
requestTimeout, requestTimeout,
onTimeout: () => onTimeout: () => Future.error(
Future.error(const ErrorMessage(ErrorCode.requestTimedOut)), const PaperlessServerException(ErrorCode.requestTimedOut)),
), ),
); );
} }
@@ -148,8 +148,8 @@ class TimeoutClient implements BaseClient {
await _handleOfflineState(); await _handleOfflineState();
return getIt<BaseClient>().read(url, headers: headers).timeout( return getIt<BaseClient>().read(url, headers: headers).timeout(
requestTimeout, requestTimeout,
onTimeout: () => onTimeout: () => Future.error(
Future.error(const ErrorMessage(ErrorCode.requestTimedOut)), const PaperlessServerException(ErrorCode.requestTimedOut)),
); );
} }
@@ -161,8 +161,8 @@ class TimeoutClient implements BaseClient {
await _handleOfflineState(); await _handleOfflineState();
return getIt<BaseClient>().readBytes(url, headers: headers).timeout( return getIt<BaseClient>().readBytes(url, headers: headers).timeout(
requestTimeout, requestTimeout,
onTimeout: () => onTimeout: () => Future.error(
Future.error(const ErrorMessage(ErrorCode.requestTimedOut)), const PaperlessServerException(ErrorCode.requestTimedOut)),
); );
} }
@@ -188,7 +188,7 @@ class TimeoutClient implements BaseClient {
Future<void> _handleOfflineState() async { Future<void> _handleOfflineState() async {
if (!(await connectivityStatusService.isConnectedToInternet())) { if (!(await connectivityStatusService.isConnectedToInternet())) {
throw const ErrorMessage(ErrorCode.deviceOffline); throw const PaperlessServerException(ErrorCode.deviceOffline);
} }
} }
} }

View File

@@ -1,8 +1,8 @@
import 'package:paperless_mobile/core/model/paperless_statistics.dart'; import 'package:paperless_api/paperless_api.dart';
class PaperlessStatisticsState { class PaperlessStatisticsState {
final bool isLoaded; final bool isLoaded;
final PaperlessStatistics? statistics; final PaperlessServerStatisticsModel? statistics;
PaperlessStatisticsState({ PaperlessStatisticsState({
required this.isLoaded, required this.isLoaded,

View File

@@ -1,7 +1,7 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:uuid/uuid.dart'; import 'package:uuid/uuid.dart';
@@ -12,7 +12,7 @@ class FileService {
) async { ) async {
final dir = await documentsDirectory; final dir = await documentsDirectory;
if (dir == null) { if (dir == null) {
throw const ErrorMessage.unknown(); //TODO: better handling throw const PaperlessServerException.unknown(); //TODO: better handling
} }
File file = File("${dir.path}/$filename"); File file = File("${dir.path}/$filename");
return file..writeAsBytes(bytes); return file..writeAsBytes(bytes);

View File

@@ -1,37 +0,0 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:injectable/injectable.dart';
import 'package:paperless_mobile/core/model/paperless_server_information.dart';
import 'package:paperless_mobile/core/store/local_vault.dart';
@injectable
class PaperlessServerInformationService {
final BaseClient client;
final LocalVault localStore;
PaperlessServerInformationService(
@Named("timeoutClient") this.client,
this.localStore,
);
Future<PaperlessServerInformation> getInformation() async {
final response = await client.get(Uri.parse("/api/ui_settings/"));
final version =
response.headers[PaperlessServerInformation.versionHeader] ?? 'unknown';
final apiVersion = int.tryParse(
response.headers[PaperlessServerInformation.apiVersionHeader] ?? '1');
final String username =
jsonDecode(utf8.decode(response.bodyBytes))['username'];
final String? host =
response.headers[PaperlessServerInformation.hostHeader] ??
response.request?.headers[PaperlessServerInformation.hostHeader] ??
('${response.request?.url.host}:${response.request?.url.port}');
return PaperlessServerInformation(
username: username,
version: version,
apiVersion: apiVersion,
host: host,
);
}
}

View File

@@ -1,29 +0,0 @@
import 'dart:convert';
import 'package:http/http.dart';
import 'package:injectable/injectable.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/core/model/paperless_statistics.dart';
import 'package:paperless_mobile/core/type/types.dart';
abstract class PaperlessStatisticsService {
Future<PaperlessStatistics> getStatistics();
}
@Injectable(as: PaperlessStatisticsService)
class PaperlessStatisticsServiceImpl extends PaperlessStatisticsService {
final BaseClient client;
PaperlessStatisticsServiceImpl(@Named('timeoutClient') this.client);
@override
Future<PaperlessStatistics> getStatistics() async {
final response = await client.get(Uri.parse('/api/statistics/'));
if (response.statusCode == 200) {
return PaperlessStatistics.fromJson(
jsonDecode(utf8.decode(response.bodyBytes)) as JSON,
);
}
throw const ErrorMessage.unknown();
}
}

View File

@@ -3,14 +3,13 @@ import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:http/http.dart'; import 'package:http/http.dart';
import 'package:injectable/injectable.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/bloc/document_status_cubit.dart'; import 'package:paperless_mobile/core/bloc/document_status_cubit.dart';
import 'package:paperless_mobile/core/model/document_processing_status.dart'; import 'package:paperless_mobile/core/model/document_processing_status.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/model/paged_search_result.dart';
import 'package:paperless_mobile/features/login/model/authentication_information.dart'; import 'package:paperless_mobile/features/login/model/authentication_information.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
import 'package:injectable/injectable.dart';
import 'package:web_socket_channel/io.dart'; import 'package:web_socket_channel/io.dart';
abstract class StatusService { abstract class StatusService {

View File

@@ -3,6 +3,7 @@ import 'dart:io';
import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:connectivity_plus/connectivity_plus.dart';
import 'package:encrypted_shared_preferences/encrypted_shared_preferences.dart'; import 'package:encrypted_shared_preferences/encrypted_shared_preferences.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/interceptor/authentication.interceptor.dart'; import 'package:paperless_mobile/core/interceptor/authentication.interceptor.dart';
import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart'; import 'package:paperless_mobile/core/interceptor/language_header.interceptor.dart';
import 'package:paperless_mobile/core/interceptor/response_conversion.interceptor.dart'; import 'package:paperless_mobile/core/interceptor/response_conversion.interceptor.dart';
@@ -51,4 +52,28 @@ abstract class RegisterModule {
CacheManager getCacheManager(BaseClient client) => CacheManager( CacheManager getCacheManager(BaseClient client) => CacheManager(
Config('cacheKey', fileService: HttpFileService(httpClient: client))); Config('cacheKey', fileService: HttpFileService(httpClient: client)));
PaperlessAuthenticationApi authenticationModule(BaseClient client) =>
PaperlessAuthenticationApiImpl(client);
PaperlessLabelsApi labelsModule(
@Named('timeoutClient') BaseClient timeoutClient,
) =>
PaperlessLabelApiImpl(timeoutClient);
PaperlessDocumentsApi documentsModule(
@Named('timeoutClient') BaseClient timeoutClient,
HttpClient httpClient,
) =>
PaperlessDocumentsApiImpl(timeoutClient, httpClient);
PaperlessSavedViewsApi savedViewsModule(
@Named('timeoutClient') BaseClient timeoutClient,
) =>
PaperlessSavedViewsApiImpl(timeoutClient);
PaperlessServerStatsApi serverStatsModule(
@Named('timeoutClient') BaseClient timeoutClient,
) =>
PaperlessServerStatsApiImpl(timeoutClient);
} }

View File

@@ -62,7 +62,7 @@ class _BiometricAuthenticationIntroSlideState
final settings = final settings =
BlocProvider.of<ApplicationSettingsCubit>(context) BlocProvider.of<ApplicationSettingsCubit>(context)
.state; .state;
getIt<AuthenticationService>() getIt<LocalAuthenticationService>()
.authenticateLocalUser( .authenticateLocalUser(
"Please authenticate to secure Paperless Mobile") "Please authenticate to secure Paperless Mobile")
.then((isEnabled) { .then((isEnabled) {

View File

@@ -1,29 +1,28 @@
import 'package:bloc/bloc.dart'; import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
part 'document_details_state.dart'; part 'document_details_state.dart';
class DocumentDetailsCubit extends Cubit<DocumentDetailsState> { class DocumentDetailsCubit extends Cubit<DocumentDetailsState> {
final DocumentRepository _documentRepository; final PaperlessDocumentsApi _api;
DocumentDetailsCubit(this._documentRepository, DocumentModel initialDocument) DocumentDetailsCubit(this._api, DocumentModel initialDocument)
: super(DocumentDetailsState(document: initialDocument)); : super(DocumentDetailsState(document: initialDocument));
Future<void> delete(DocumentModel document) async { Future<void> delete(DocumentModel document) async {
await _documentRepository.delete(document); await _api.delete(document);
emit(const DocumentDetailsState()); emit(const DocumentDetailsState());
} }
Future<void> update(DocumentModel document) async { Future<void> update(DocumentModel document) async {
final updatedDocument = await _documentRepository.update(document); final updatedDocument = await _api.update(document);
emit(DocumentDetailsState(document: updatedDocument)); emit(DocumentDetailsState(document: updatedDocument));
} }
Future<void> assignAsn(DocumentModel document) async { Future<void> assignAsn(DocumentModel document) async {
if (document.archiveSerialNumber == null) { if (document.archiveSerialNumber == null) {
final int asn = await _documentRepository.findNextAsn(); final int asn = await _api.findNextAsn();
update(document.copyWith(archiveSerialNumber: asn)); update(document.copyWith(archiveSerialNumber: asn));
} }
} }

View File

@@ -7,14 +7,11 @@ import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.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_mobile/core/model/error_message.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/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart'; import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/model/document_meta_data.model.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
import 'package:paperless_mobile/features/documents/view/pages/document_edit_page.dart'; import 'package:paperless_mobile/features/documents/view/pages/document_edit_page.dart';
import 'package:paperless_mobile/features/documents/view/pages/document_view.dart'; import 'package:paperless_mobile/features/documents/view/pages/document_view.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';
@@ -235,7 +232,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
Widget _buildDocumentMetaDataView(DocumentModel document) { Widget _buildDocumentMetaDataView(DocumentModel document) {
return FutureBuilder<DocumentMetaData>( return FutureBuilder<DocumentMetaData>(
future: getIt<DocumentRepository>().getMetaData(document), future: getIt<PaperlessDocumentsApi>().getMetaData(document),
builder: (context, snapshot) { builder: (context, snapshot) {
if (!snapshot.hasData) { if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
@@ -295,7 +292,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
Future<void> _assignAsn(DocumentModel document) async { Future<void> _assignAsn(DocumentModel document) async {
try { try {
await BlocProvider.of<DocumentDetailsCubit>(context).assignAsn(document); await BlocProvider.of<DocumentDetailsCubit>(context).assignAsn(document);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }
@@ -414,7 +411,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
return; return;
} }
setState(() => _isDownloadPending = true); setState(() => _isDownloadPending = true);
getIt<DocumentRepository>().download(document).then((bytes) async { getIt<PaperlessDocumentsApi>().download(document).then((bytes) async {
final Directory dir = (await getExternalStorageDirectories( final Directory dir = (await getExternalStorageDirectories(
type: StorageDirectory.downloads))! type: StorageDirectory.downloads))!
.first; .first;
@@ -431,7 +428,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
/// ///
Future<void> _onShare(DocumentModel document) async { Future<void> _onShare(DocumentModel document) async {
Uint8List documentBytes = Uint8List documentBytes =
await getIt<DocumentRepository>().download(document); await getIt<PaperlessDocumentsApi>().download(document);
final dir = await getTemporaryDirectory(); final dir = await getTemporaryDirectory();
final String path = "${dir.path}/${document.originalFileName}"; final String path = "${dir.path}/${document.originalFileName}";
await File(path).writeAsBytes(documentBytes); await File(path).writeAsBytes(documentBytes);
@@ -459,7 +456,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
try { try {
await BlocProvider.of<DocumentDetailsCubit>(context).delete(document); await BlocProvider.of<DocumentDetailsCubit>(context).delete(document);
showSnackBar(context, S.of(context).documentDeleteSuccessMessage); showSnackBar(context, S.of(context).documentDeleteSuccessMessage);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} finally { } finally {
// Document deleted => go back to primary route // Document deleted => go back to primary route
@@ -472,7 +469,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
Navigator.of(context).push( Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
builder: (context) => DocumentView( builder: (context) => DocumentView(
documentBytes: getIt<DocumentRepository>().getPreview(document.id), documentBytes: getIt<PaperlessDocumentsApi>().getPreview(document.id),
), ),
), ),
); );

View File

@@ -2,21 +2,17 @@ import 'dart:typed_data';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/model/bulk_edit.model.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart';
import 'package:paperless_mobile/features/documents/model/paged_search_result.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
@singleton @singleton
class DocumentsCubit extends Cubit<DocumentsState> { class DocumentsCubit extends Cubit<DocumentsState> {
final DocumentRepository documentRepository; final PaperlessDocumentsApi _api;
DocumentsCubit(this.documentRepository) : super(DocumentsState.initial); DocumentsCubit(this._api) : super(DocumentsState.initial);
Future<void> bulkRemove(List<DocumentModel> documents) async { Future<void> bulkRemove(List<DocumentModel> documents) async {
await documentRepository.bulkAction( await _api.bulkAction(
BulkDeleteAction(documents.map((doc) => doc.id)), BulkDeleteAction(documents.map((doc) => doc.id)),
); );
await reload(); await reload();
@@ -27,7 +23,7 @@ class DocumentsCubit extends Cubit<DocumentsState> {
Iterable<int> addTags = const [], Iterable<int> addTags = const [],
Iterable<int> removeTags = const [], Iterable<int> removeTags = const [],
}) async { }) async {
await documentRepository.bulkAction(BulkModifyTagsAction( await _api.bulkAction(BulkModifyTagsAction(
documents.map((doc) => doc.id), documents.map((doc) => doc.id),
addTags: addTags, addTags: addTags,
removeTags: removeTags, removeTags: removeTags,
@@ -40,13 +36,13 @@ class DocumentsCubit extends Cubit<DocumentsState> {
bool updateRemote = true, bool updateRemote = true,
]) async { ]) async {
if (updateRemote) { if (updateRemote) {
await documentRepository.update(document); await _api.update(document);
} }
await reload(); await reload();
} }
Future<void> load() async { Future<void> load() async {
final result = await documentRepository.find(state.filter); final result = await _api.find(state.filter);
emit(DocumentsState( emit(DocumentsState(
isLoaded: true, isLoaded: true,
value: [...state.value, result], value: [...state.value, result],
@@ -60,15 +56,14 @@ class DocumentsCubit extends Cubit<DocumentsState> {
} }
var newPages = <PagedSearchResult>[]; var newPages = <PagedSearchResult>[];
for (final page in state.value) { for (final page in state.value) {
final result = await documentRepository final result = await _api.find(state.filter.copyWith(page: page.pageKey));
.find(state.filter.copyWith(page: page.pageKey));
newPages.add(result); newPages.add(result);
} }
emit(DocumentsState(isLoaded: true, value: newPages, filter: state.filter)); emit(DocumentsState(isLoaded: true, value: newPages, filter: state.filter));
} }
Future<void> _bulkReloadDocuments() async { Future<void> _bulkReloadDocuments() async {
final result = await documentRepository final result = await _api
.find(state.filter.copyWith(page: 1, pageSize: state.documents.length)); .find(state.filter.copyWith(page: 1, pageSize: state.documents.length));
emit(DocumentsState(isLoaded: true, value: [result], filter: state.filter)); emit(DocumentsState(isLoaded: true, value: [result], filter: state.filter));
} }
@@ -78,7 +73,7 @@ class DocumentsCubit extends Cubit<DocumentsState> {
return; return;
} }
final newFilter = state.filter.copyWith(page: state.filter.page + 1); final newFilter = state.filter.copyWith(page: state.filter.page + 1);
final result = await documentRepository.find(newFilter); final result = await _api.find(newFilter);
emit( emit(
DocumentsState( DocumentsState(
isLoaded: true, value: [...state.value, result], filter: newFilter), isLoaded: true, value: [...state.value, result], filter: newFilter),
@@ -91,7 +86,7 @@ class DocumentsCubit extends Cubit<DocumentsState> {
Future<void> updateFilter({ Future<void> updateFilter({
final DocumentFilter filter = DocumentFilter.initial, final DocumentFilter filter = DocumentFilter.initial,
}) async { }) async {
final result = await documentRepository.find(filter.copyWith(page: 1)); final result = await _api.find(filter.copyWith(page: 1));
emit(DocumentsState(filter: filter, value: [result], isLoaded: true)); emit(DocumentsState(filter: filter, value: [result], isLoaded: true));
} }

View File

@@ -1,7 +1,5 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart';
import 'package:paperless_mobile/features/documents/model/paged_search_result.dart';
class DocumentsState extends Equatable { class DocumentsState extends Equatable {
final bool isLoaded; final bool isLoaded;

View File

@@ -1,56 +0,0 @@
import 'dart:convert';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/core/util.dart';
import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/model/saved_view.model.dart';
import 'package:http/http.dart';
import 'package:injectable/injectable.dart';
abstract class SavedViewsRepository {
Future<List<SavedView>> getAll();
Future<SavedView> save(SavedView view);
Future<int> delete(SavedView view);
}
@Injectable(as: SavedViewsRepository)
class SavedViewRepositoryImpl implements SavedViewsRepository {
final BaseClient httpClient;
SavedViewRepositoryImpl(@Named("timeoutClient") this.httpClient);
@override
Future<List<SavedView>> getAll() {
return getCollection(
"/api/saved_views/",
SavedView.fromJson,
ErrorCode.loadSavedViewsError,
);
}
@override
Future<SavedView> save(SavedView view) async {
final response = await httpClient.post(
Uri.parse("/api/saved_views/"),
body: jsonEncode(view.toJson()),
headers: {'Content-Type': 'application/json'},
);
if (response.statusCode == 201) {
return SavedView.fromJson(jsonDecode(utf8.decode(response.bodyBytes)));
}
throw ErrorMessage(ErrorCode.createSavedViewError,
httpStatusCode: response.statusCode);
}
@override
Future<int> delete(SavedView view) async {
final response =
await httpClient.delete(Uri.parse("/api/saved_views/${view.id}/"));
if (response.statusCode == 204) {
return view.id!;
}
throw ErrorMessage(ErrorCode.deleteSavedViewError,
httpStatusCode: response.statusCode);
}
}

View File

@@ -6,26 +6,15 @@ 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:form_builder_validators/form_builder_validators.dart'; import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/correspondent_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/document_type_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/id_query_parameter.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/storage_path_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/tags_query.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart'; import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart';
import 'package:paperless_mobile/features/labels/correspondent/model/correspondent.model.dart';
import 'package:paperless_mobile/features/labels/correspondent/view/pages/add_correspondent_page.dart'; import 'package:paperless_mobile/features/labels/correspondent/view/pages/add_correspondent_page.dart';
import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart'; import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart';
import 'package:paperless_mobile/features/labels/document_type/model/document_type.model.dart';
import 'package:paperless_mobile/features/labels/document_type/view/pages/add_document_type_page.dart'; import 'package:paperless_mobile/features/labels/document_type/view/pages/add_document_type_page.dart';
import 'package:paperless_mobile/features/labels/model/label_state.dart'; import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart'; import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart';
import 'package:paperless_mobile/features/labels/storage_path/model/storage_path.model.dart';
import 'package:paperless_mobile/features/labels/storage_path/view/pages/add_storage_path_page.dart'; import 'package:paperless_mobile/features/labels/storage_path/view/pages/add_storage_path_page.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';
@@ -62,7 +51,8 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
@override @override
void initState() { void initState() {
super.initState(); super.initState();
documentBytes = getIt<DocumentRepository>().getPreview(widget.document.id); documentBytes =
getIt<PaperlessDocumentsApi>().getPreview(widget.document.id);
} }
@override @override
@@ -92,7 +82,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
try { try {
await widget.onEdit(updatedDocument); await widget.onEdit(updatedDocument);
showSnackBar(context, S.of(context).documentUpdateSuccessMessage); showSnackBar(context, S.of(context).documentUpdateSuccessMessage);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} finally { } finally {
setState(() { setState(() {

View File

@@ -1,8 +1,5 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:pdfx/pdfx.dart'; import 'package:pdfx/pdfx.dart';

View File

@@ -1,16 +1,13 @@
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:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.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/model/error_message.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart'; import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart';
import 'package:paperless_mobile/features/document_details/view/pages/document_details_page.dart'; import 'package:paperless_mobile/features/document_details/view/pages/document_details_page.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/tags_query.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
import 'package:paperless_mobile/features/documents/view/widgets/documents_empty_state.dart'; import 'package:paperless_mobile/features/documents/view/widgets/documents_empty_state.dart';
import 'package:paperless_mobile/features/documents/view/widgets/grid/document_grid.dart'; import 'package:paperless_mobile/features/documents/view/widgets/grid/document_grid.dart';
import 'package:paperless_mobile/features/documents/view/widgets/list/document_list.dart'; import 'package:paperless_mobile/features/documents/view/widgets/list/document_list.dart';
@@ -48,7 +45,7 @@ class _DocumentsPageState extends State<DocumentsPage> {
super.initState(); super.initState();
try { try {
BlocProvider.of<DocumentsCubit>(context).load(); BlocProvider.of<DocumentsCubit>(context).load();
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
_pagingController.addPageRequestListener(_loadNewPage); _pagingController.addPageRequestListener(_loadNewPage);
@@ -69,7 +66,7 @@ class _DocumentsPageState extends State<DocumentsPage> {
} }
try { try {
await documentsCubit.loadMore(); await documentsCubit.loadMore();
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }
@@ -83,7 +80,7 @@ class _DocumentsPageState extends State<DocumentsPage> {
await BlocProvider.of<DocumentsCubit>(context).updateCurrentFilter( await BlocProvider.of<DocumentsCubit>(context).updateCurrentFilter(
(filter) => filter.copyWith(page: 1), (filter) => filter.copyWith(page: 1),
); );
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }
@@ -254,7 +251,8 @@ class _DocumentsPageState extends State<DocumentsPage> {
value: BlocProvider.of<StoragePathCubit>(context), value: BlocProvider.of<StoragePathCubit>(context),
), ),
BlocProvider.value( BlocProvider.value(
value: DocumentDetailsCubit(getIt<DocumentRepository>(), document), value:
DocumentDetailsCubit(getIt<PaperlessDocumentsApi>(), document),
), ),
], ],
child: const DocumentDetailsPage(), child: const DocumentDetailsPage(),
@@ -281,7 +279,7 @@ class _DocumentsPageState extends State<DocumentsPage> {
), ),
); );
} }
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
class DeleteDocumentConfirmationDialog extends StatelessWidget { class DeleteDocumentConfirmationDialog extends StatelessWidget {

View File

@@ -1,8 +1,8 @@
import 'package:cached_network_image/cached_network_image.dart'; import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart'; 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:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
import 'package:shimmer/shimmer.dart'; import 'package:shimmer/shimmer.dart';
class DocumentPreview extends StatelessWidget { class DocumentPreview extends StatelessWidget {
@@ -30,7 +30,7 @@ class DocumentPreview extends StatelessWidget {
fit: fit, fit: fit,
alignment: Alignment.topCenter, alignment: Alignment.topCenter,
cacheKey: "thumb_$id", cacheKey: "thumb_$id",
imageUrl: getIt<DocumentRepository>().getThumbnailUrl(id), imageUrl: getIt<PaperlessDocumentsApi>().getThumbnailUrl(id),
errorWidget: (ctxt, msg, __) => Text(msg), errorWidget: (ctxt, msg, __) => Text(msg),
placeholder: (context, value) => Shimmer.fromColors( placeholder: (context, value) => Shimmer.fromColors(
baseColor: Colors.grey[300]!, baseColor: Colors.grey[300]!,

View File

@@ -1,13 +1,12 @@
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_mobile/core/widgets/empty_state.dart'; import 'package:paperless_mobile/core/widgets/empty_state.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart';
import 'package:paperless_mobile/features/saved_view/bloc/saved_view_cubit.dart'; import 'package:paperless_mobile/features/saved_view/bloc/saved_view_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/util.dart';
class DocumentsEmptyState extends StatelessWidget { class DocumentsEmptyState extends StatelessWidget {
final DocumentsState state; final DocumentsState state;

View File

@@ -1,8 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart'; import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/tags_query.dart';
import 'package:paperless_mobile/features/documents/view/widgets/grid/document_grid_item.dart'; import 'package:paperless_mobile/features/documents/view/widgets/grid/document_grid_item.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart'; import 'package:paperless_api/paperless_api.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/labels/correspondent/view/widgets/correspondent_widget.dart'; import 'package:paperless_mobile/features/labels/correspondent/view/widgets/correspondent_widget.dart';
import 'package:paperless_mobile/features/labels/document_type/view/widgets/document_type_widget.dart'; import 'package:paperless_mobile/features/labels/document_type/view/widgets/document_type_widget.dart';

View File

@@ -1,12 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart'; import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart';
import 'package:paperless_mobile/core/widgets/offline_widget.dart'; import 'package:paperless_mobile/core/widgets/offline_widget.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/tags_query.dart';
import 'package:paperless_mobile/features/documents/view/widgets/list/document_list_item.dart'; import 'package:paperless_mobile/features/documents/view/widgets/list/document_list_item.dart';
import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:paperless_mobile/features/labels/tags/model/tag.model.dart';
class DocumentListView extends StatelessWidget { class DocumentListView extends StatelessWidget {
final void Function(DocumentModel) onTap; final void Function(DocumentModel) onTap;

View File

@@ -1,8 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart'; import 'package:paperless_api/paperless_api.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/labels/correspondent/view/widgets/correspondent_widget.dart'; import 'package:paperless_mobile/features/labels/correspondent/view/widgets/correspondent_widget.dart';
import 'package:paperless_mobile/features/labels/tags/model/tag.model.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';
class DocumentListItem extends StatelessWidget { class DocumentListItem extends StatelessWidget {

View File

@@ -1,6 +1,6 @@
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/features/documents/model/query_parameters/sort_field.dart'; import 'package:paperless_api/paperless_api.dart';
class OrderByDropdown extends StatefulWidget { class OrderByDropdown extends StatefulWidget {
static const fkOrderBy = "orderBy"; static const fkOrderBy = "orderBy";

View File

@@ -1,25 +1,15 @@
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:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/correspondent_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/document_type_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/query_type.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/storage_path_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/tags_query.dart';
import 'package:paperless_mobile/features/documents/view/widgets/search/query_type_form_field.dart'; import 'package:paperless_mobile/features/documents/view/widgets/search/query_type_form_field.dart';
import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart'; import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart';
import 'package:paperless_mobile/features/labels/correspondent/model/correspondent.model.dart';
import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart'; import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart';
import 'package:paperless_mobile/features/labels/document_type/model/document_type.model.dart'; import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/model/label_state.dart';
import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart'; import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart';
import 'package:paperless_mobile/features/labels/storage_path/model/storage_path.model.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';
import 'package:paperless_mobile/features/saved_view/bloc/saved_view_cubit.dart'; import 'package:paperless_mobile/features/saved_view/bloc/saved_view_cubit.dart';
@@ -468,7 +458,7 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
BlocProvider.of<SavedViewCubit>(context).resetSelection(); BlocProvider.of<SavedViewCubit>(context).resetSelection();
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
widget.panelController.close(); widget.panelController.close();
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,6 +1,6 @@
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/features/documents/model/query_parameters/query_type.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
class QueryTypeFormField extends StatelessWidget { class QueryTypeFormField extends StatelessWidget {

View File

@@ -1,12 +1,9 @@
import 'dart:developer';
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_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/sort_field.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/sort_order.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
@@ -20,16 +17,6 @@ class SortFieldSelectionBottomSheet extends StatefulWidget {
class _SortFieldSelectionBottomSheetState class _SortFieldSelectionBottomSheetState
extends State<SortFieldSelectionBottomSheet> { extends State<SortFieldSelectionBottomSheet> {
static const _sortFields = [
SortField.created,
SortField.added,
SortField.modified,
SortField.title,
SortField.correspondentName,
SortField.documentType,
SortField.archiveSerialNumber
];
SortField? _selectedFieldLoading; SortField? _selectedFieldLoading;
SortOrder? _selectedOrderLoading; SortOrder? _selectedOrderLoading;
@@ -49,7 +36,7 @@ class _SortFieldSelectionBottomSheetState
).padded( ).padded(
const EdgeInsets.symmetric(horizontal: 16, vertical: 16)), const EdgeInsets.symmetric(horizontal: 16, vertical: 16)),
Column( Column(
children: _sortFields children: SortField.values
.map( .map(
(e) => _buildSortOption( (e) => _buildSortOption(
e, e,

View File

@@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
class BulkDeleteConfirmationDialog extends StatelessWidget { class BulkDeleteConfirmationDialog extends StatelessWidget {

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:paperless_mobile/features/documents/model/saved_view.model.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
class ConfirmDeleteSavedViewDialog extends StatelessWidget { class ConfirmDeleteSavedViewDialog extends StatelessWidget {

View File

@@ -1,12 +1,10 @@
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/core/logic/error_code_localization_mapper.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_state.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/features/documents/view/widgets/selection/saved_view_selection_widget.dart'; import 'package:paperless_mobile/features/saved_view/view/saved_view_selection_widget.dart';
import 'package:paperless_mobile/features/documents/view/widgets/sort_documents_button.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
@@ -104,7 +102,7 @@ class _DocumentsPageAppBarState extends State<DocumentsPageAppBar> {
context, context,
S.of(context).documentsPageBulkDeleteSuccessfulText, S.of(context).documentsPageBulkDeleteSuccessfulText,
); );
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,18 +1,8 @@
import 'dart:developer';
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/core/logic/error_code_localization_mapper.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_state.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/sort_field.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/sort_order.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:paperless_mobile/features/documents/view/widgets/search/sort_field_selection_bottom_sheet.dart'; import 'package:paperless_mobile/features/documents/view/widgets/search/sort_field_selection_bottom_sheet.dart';
import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/util.dart';
class SortDocumentsButton extends StatefulWidget { class SortDocumentsButton extends StatefulWidget {
const SortDocumentsButton({ const SortDocumentsButton({

View File

@@ -1,9 +1,8 @@
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_mobile/core/bloc/connectivity_cubit.dart'; import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart'; import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/core/widgets/offline_banner.dart'; import 'package:paperless_mobile/core/widgets/offline_banner.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
@@ -90,7 +89,7 @@ class _HomePageState extends State<HomePage> {
getIt<StoragePathCubit>().initialize(), getIt<StoragePathCubit>().initialize(),
getIt<SavedViewCubit>().initialize(), getIt<SavedViewCubit>().initialize(),
]); ]);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
return Future.error(error); return Future.error(error);
} }

View File

@@ -1,8 +1,8 @@
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_mobile/core/bloc/paperless_server_information_cubit.dart'; import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_mobile/core/bloc/paperless_server_information_state.dart';
import 'package:paperless_mobile/core/model/paperless_server_information.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
@@ -67,8 +67,12 @@ class InfoDrawer extends StatelessWidget {
Align( Align(
alignment: Alignment.bottomRight, alignment: Alignment.bottomRight,
child: BlocBuilder<PaperlessServerInformationCubit, child: BlocBuilder<PaperlessServerInformationCubit,
PaperlessServerInformation>( PaperlessServerInformationState>(
builder: (context, state) { builder: (context, state) {
if (!state.isLoaded) {
return Container();
}
final info = state.information!;
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
@@ -77,7 +81,7 @@ class InfoDrawer extends StatelessWidget {
dense: true, dense: true,
title: Text( title: Text(
S.of(context).appDrawerHeaderLoggedInAsText + S.of(context).appDrawerHeaderLoggedInAsText +
(state.username ?? '?'), (info.username ?? '?'),
style: Theme.of(context).textTheme.bodyText2, style: Theme.of(context).textTheme.bodyText2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
textAlign: TextAlign.end, textAlign: TextAlign.end,
@@ -87,7 +91,7 @@ class InfoDrawer extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
children: [ children: [
Text( Text(
state.host ?? '', state.information!.host ?? '',
style: style:
Theme.of(context).textTheme.bodyText2, Theme.of(context).textTheme.bodyText2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@@ -95,7 +99,7 @@ class InfoDrawer extends StatelessWidget {
maxLines: 1, maxLines: 1,
), ),
Text( Text(
'${S.of(context).serverInformationPaperlessVersionText} ${state.version} (API v${state.apiVersion})', '${S.of(context).serverInformationPaperlessVersionText} ${info.version} (API v${info.apiVersion})',
style: Theme.of(context).textTheme.caption, style: Theme.of(context).textTheme.caption,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
textAlign: TextAlign.end, textAlign: TextAlign.end,
@@ -189,7 +193,7 @@ class InfoDrawer extends StatelessWidget {
getIt<DocumentTypeCubit>().reset(); getIt<DocumentTypeCubit>().reset();
getIt<TagCubit>().reset(); getIt<TagCubit>().reset();
getIt<DocumentScannerCubit>().reset(); getIt<DocumentScannerCubit>().reset();
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
}, },

View File

@@ -1,28 +1,20 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:paperless_mobile/features/documents/model/bulk_edit.model.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/sort_field.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/tags_query.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
import 'package:paperless_mobile/features/inbox/bloc/state/inbox_state.dart'; import 'package:paperless_mobile/features/inbox/bloc/state/inbox_state.dart';
import 'package:paperless_mobile/features/labels/repository/label_repository.dart';
@injectable @injectable
class InboxCubit extends Cubit<InboxState> { class InboxCubit extends Cubit<InboxState> {
final LabelRepository _labelRepository; final PaperlessLabelsApi _labelApi;
final DocumentRepository _documentRepository; final PaperlessDocumentsApi _documentsApi;
InboxCubit(this._labelRepository, this._documentRepository) InboxCubit(this._labelApi, this._documentsApi) : super(const InboxState());
: super(const InboxState());
/// ///
/// Fetches inbox tag ids and loads the inbox items (documents). /// Fetches inbox tag ids and loads the inbox items (documents).
/// ///
Future<void> loadInbox() async { Future<void> loadInbox() async {
final inboxTags = await _labelRepository.getTags().then( final inboxTags = await _labelApi.getTags().then(
(tags) => tags.where((t) => t.isInboxTag ?? false).map((t) => t.id!), (tags) => tags.where((t) => t.isInboxTag ?? false).map((t) => t.id!),
); );
if (inboxTags.isEmpty) { if (inboxTags.isEmpty) {
@@ -33,7 +25,7 @@ class InboxCubit extends Cubit<InboxState> {
inboxTags: [], inboxTags: [],
)); ));
} }
final inboxDocuments = await _documentRepository final inboxDocuments = await _documentsApi
.find(DocumentFilter( .find(DocumentFilter(
tags: AnyAssignedTagsQuery(tagIds: inboxTags), tags: AnyAssignedTagsQuery(tagIds: inboxTags),
sortField: SortField.added, sortField: SortField.added,
@@ -57,7 +49,7 @@ class InboxCubit extends Cubit<InboxState> {
final updatedTags = {...document.tags}..removeAll(tagsToRemove); final updatedTags = {...document.tags}..removeAll(tagsToRemove);
await _documentRepository.update( await _documentsApi.update(
document.copyWith( document.copyWith(
tags: updatedTags, tags: updatedTags,
overwriteTags: true, overwriteTags: true,
@@ -85,7 +77,7 @@ class InboxCubit extends Cubit<InboxState> {
tags: {...document.tags, ...removedTags}, tags: {...document.tags, ...removedTags},
overwriteTags: true, overwriteTags: true,
); );
await _documentRepository.update(updatedDoc); await _documentsApi.update(updatedDoc);
emit( emit(
InboxState( InboxState(
isLoaded: true, isLoaded: true,
@@ -100,7 +92,7 @@ class InboxCubit extends Cubit<InboxState> {
/// Removes inbox tags from all documents in the inbox. /// Removes inbox tags from all documents in the inbox.
/// ///
Future<void> clearInbox() async { Future<void> clearInbox() async {
await _documentRepository.bulkAction( await _documentsApi.bulkAction(
BulkModifyTagsAction.removeTags( BulkModifyTagsAction.removeTags(
state.inboxItems.map((e) => e.id), state.inboxItems.map((e) => e.id),
state.inboxTags, state.inboxTags,

View File

@@ -1,5 +1,5 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart'; import 'package:paperless_api/paperless_api.dart';
class InboxState with EquatableMixin { class InboxState with EquatableMixin {
final bool isLoaded; final bool isLoaded;

View File

@@ -1,19 +1,18 @@
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: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_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart'; import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart';
import 'package:paperless_mobile/extensions/dart_extensions.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart'; import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart';
import 'package:paperless_mobile/features/inbox/bloc/state/inbox_state.dart'; import 'package:paperless_mobile/features/inbox/bloc/state/inbox_state.dart';
import 'package:paperless_mobile/features/inbox/view/widgets/inbox_item.dart';
import 'package:paperless_mobile/features/inbox/view/widgets/inbox_empty_widget.dart'; import 'package:paperless_mobile/features/inbox/view/widgets/inbox_empty_widget.dart';
import 'package:paperless_mobile/features/inbox/view/widgets/inbox_item.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
import 'package:collection/collection.dart';
import 'package:paperless_mobile/extensions/dart_extensions.dart';
class InboxPage extends StatefulWidget { class InboxPage extends StatefulWidget {
const InboxPage({super.key}); const InboxPage({super.key});
@@ -230,13 +229,13 @@ class _InboxPageState extends State<InboxPage> {
), ),
); );
return true; return true;
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
return false; return false;
} catch (error) { } catch (error) {
showErrorMessage( showErrorMessage(
context, context,
const ErrorMessage.unknown(), const PaperlessServerException.unknown(),
); );
return false; return false;
} }
@@ -249,7 +248,7 @@ class _InboxPageState extends State<InboxPage> {
try { try {
await BlocProvider.of<InboxCubit>(context) await BlocProvider.of<InboxCubit>(context)
.undoRemove(document, removedTags); .undoRemove(document, removedTags);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,6 +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_mobile/features/inbox/bloc/inbox_cubit.dart'; import 'package:paperless_mobile/features/inbox/bloc/inbox_cubit.dart';
import 'package:paperless_mobile/generated/l10n.dart';
class InboxEmptyWidget extends StatelessWidget { class InboxEmptyWidget extends StatelessWidget {
const InboxEmptyWidget({ const InboxEmptyWidget({
@@ -22,11 +23,11 @@ class InboxEmptyWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text('You do not have unseen documents.'), Text(S.of(context).inboxPageNoNewDocumentsText),
TextButton( TextButton(
onPressed: () => onPressed: () =>
_emptyStateRefreshIndicatorKey.currentState?.show(), _emptyStateRefreshIndicatorKey.currentState?.show(),
child: Text('Refresh'), child: Text(S.of(context).inboxPageNoNewDocumentsRefreshLabel),
), ),
], ],
), ),

View File

@@ -1,12 +1,11 @@
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:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart'; import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/document_details/view/pages/document_details_page.dart'; import 'package:paperless_mobile/features/document_details/view/pages/document_details_page.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.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/labels/bloc/global_state_bloc_provider.dart'; import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.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';
@@ -54,7 +53,7 @@ class InboxItem extends StatelessWidget {
additionalProviders: [ additionalProviders: [
BlocProvider<DocumentDetailsCubit>( BlocProvider<DocumentDetailsCubit>(
create: (context) => DocumentDetailsCubit( create: (context) => DocumentDetailsCubit(
getIt<DocumentRepository>(), getIt<PaperlessDocumentsApi>(),
document, document,
), ),
), ),

View File

@@ -1,13 +1,12 @@
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/features/labels/model/label.model.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/model/label_state.dart'; import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/repository/label_repository.dart';
abstract class LabelCubit<T extends Label> extends Cubit<LabelState<T>> { abstract class LabelCubit<T extends Label> extends Cubit<LabelState<T>> {
final LabelRepository labelRepository; final PaperlessLabelsApi labelsApi;
LabelCubit(this.labelRepository) : super(LabelState.initial()); LabelCubit(this.labelsApi) : super(LabelState.initial());
@protected @protected
void loadFrom(Iterable<T> items) { void loadFrom(Iterable<T> items) {

View File

@@ -1,4 +1,4 @@
import 'package:paperless_mobile/features/labels/model/label.model.dart'; import 'package:paperless_api/paperless_api.dart';
class LabelState<T extends Label> { class LabelState<T extends Label> {
LabelState.initial() : this(isLoaded: false, labels: {}); LabelState.initial() : this(isLoaded: false, labels: {});

View File

@@ -1,5 +1,5 @@
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart'; import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/correspondent/model/correspondent.model.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
@singleton @singleton
@@ -8,18 +8,17 @@ class CorrespondentCubit extends LabelCubit<Correspondent> {
@override @override
Future<void> initialize() async { Future<void> initialize() async {
return labelRepository.getCorrespondents().then(loadFrom); return labelsApi.getCorrespondents().then(loadFrom);
} }
@override @override
Future<Correspondent> save(Correspondent item) => Future<Correspondent> save(Correspondent item) =>
labelRepository.saveCorrespondent(item); labelsApi.saveCorrespondent(item);
@override @override
Future<Correspondent> update(Correspondent item) => Future<Correspondent> update(Correspondent item) =>
labelRepository.updateCorrespondent(item); labelsApi.updateCorrespondent(item);
@override @override
Future<int> delete(Correspondent item) => Future<int> delete(Correspondent item) => labelsApi.deleteCorrespondent(item);
labelRepository.deleteCorrespondent(item);
} }

View File

@@ -1,7 +1,7 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.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_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart'; import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart';
import 'package:paperless_mobile/features/labels/correspondent/model/correspondent.model.dart';
import 'package:paperless_mobile/features/labels/view/pages/add_label_page.dart'; import 'package:paperless_mobile/features/labels/view/pages/add_label_page.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -1,11 +1,8 @@
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/core/logic/error_code_localization_mapper.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/correspondent_query.dart';
import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart'; import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart';
import 'package:paperless_mobile/features/labels/correspondent/model/correspondent.model.dart';
import 'package:paperless_mobile/features/labels/view/pages/edit_label_page.dart'; import 'package:paperless_mobile/features/labels/view/pages/edit_label_page.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
@@ -38,7 +35,7 @@ class EditCorrespondentPage extends StatelessWidget {
); );
} }
Navigator.pop(context); Navigator.pop(context);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,12 +1,9 @@
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/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/correspondent_query.dart';
import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart'; import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart';
import 'package:paperless_mobile/features/labels/correspondent/model/correspondent.model.dart'; import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/model/label_state.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
class CorrespondentWidget extends StatelessWidget { class CorrespondentWidget extends StatelessWidget {
@@ -60,7 +57,7 @@ class CorrespondentWidget extends StatelessWidget {
); );
} }
afterSelected?.call(); afterSelected?.call();
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,6 +1,5 @@
import 'package:flutter/foundation.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart'; import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/document_type/model/document_type.model.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
@singleton @singleton
@@ -9,18 +8,17 @@ class DocumentTypeCubit extends LabelCubit<DocumentType> {
@override @override
Future<void> initialize() async { Future<void> initialize() async {
labelRepository.getDocumentTypes().then(loadFrom); labelsApi.getDocumentTypes().then(loadFrom);
} }
@override @override
Future<DocumentType> save(DocumentType item) => Future<DocumentType> save(DocumentType item) =>
labelRepository.saveDocumentType(item); labelsApi.saveDocumentType(item);
@override @override
Future<DocumentType> update(DocumentType item) => Future<DocumentType> update(DocumentType item) =>
labelRepository.updateDocumentType(item); labelsApi.updateDocumentType(item);
@override @override
Future<int> delete(DocumentType item) => Future<int> delete(DocumentType item) => labelsApi.deleteDocumentType(item);
labelRepository.deleteDocumentType(item);
} }

View File

@@ -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_mobile/features/labels/document_type/bloc/document_type_cubit.dart'; import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart';
import 'package:paperless_mobile/features/labels/document_type/model/document_type.model.dart';
import 'package:paperless_mobile/features/labels/view/pages/add_label_page.dart'; import 'package:paperless_mobile/features/labels/view/pages/add_label_page.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -1,11 +1,8 @@
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/core/logic/error_code_localization_mapper.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/document_type_query.dart';
import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart'; import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart';
import 'package:paperless_mobile/features/labels/document_type/model/document_type.model.dart';
import 'package:paperless_mobile/features/labels/view/pages/edit_label_page.dart'; import 'package:paperless_mobile/features/labels/view/pages/edit_label_page.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
@@ -33,8 +30,8 @@ class EditDocumentTypePage extends StatelessWidget {
.copyWith(documentType: const DocumentTypeQuery.unset()), .copyWith(documentType: const DocumentTypeQuery.unset()),
); );
} }
} on ErrorMessage catch (e) { } on PaperlessServerException catch (error, stackTrace) {
showSnackBar(context, translateError(context, e.code)); showErrorMessage(context, error, stackTrace);
} finally { } finally {
Navigator.pop(context); Navigator.pop(context);
} }

View File

@@ -1,11 +1,9 @@
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/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/document_type_query.dart';
import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart'; import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart';
import 'package:paperless_mobile/features/labels/document_type/model/document_type.model.dart'; import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/model/label_state.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
class DocumentTypeWidget extends StatelessWidget { class DocumentTypeWidget extends StatelessWidget {
@@ -55,7 +53,7 @@ class DocumentTypeWidget extends StatelessWidget {
); );
} }
afterSelected?.call(); afterSelected?.call();
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,6 +1,6 @@
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart'; import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/storage_path/model/storage_path.model.dart';
@singleton @singleton
class StoragePathCubit extends LabelCubit<StoragePath> { class StoragePathCubit extends LabelCubit<StoragePath> {
@@ -8,18 +8,16 @@ class StoragePathCubit extends LabelCubit<StoragePath> {
@override @override
Future<void> initialize() async { Future<void> initialize() async {
return labelRepository.getStoragePaths().then(loadFrom); return labelsApi.getStoragePaths().then(loadFrom);
} }
@override @override
Future<StoragePath> save(StoragePath item) => Future<StoragePath> save(StoragePath item) => labelsApi.saveStoragePath(item);
labelRepository.saveStoragePath(item);
@override @override
Future<StoragePath> update(StoragePath item) => Future<StoragePath> update(StoragePath item) =>
labelRepository.updateStoragePath(item); labelsApi.updateStoragePath(item);
@override @override
Future<int> delete(StoragePath item) => Future<int> delete(StoragePath item) => labelsApi.deleteStoragePath(item);
labelRepository.deleteStoragePath(item);
} }

View File

@@ -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_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart'; import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart';
import 'package:paperless_mobile/features/labels/storage_path/model/storage_path.model.dart';
import 'package:paperless_mobile/features/labels/storage_path/view/widgets/storage_path_autofill_form_builder_field.dart'; import 'package:paperless_mobile/features/labels/storage_path/view/widgets/storage_path_autofill_form_builder_field.dart';
import 'package:paperless_mobile/features/labels/view/pages/add_label_page.dart'; import 'package:paperless_mobile/features/labels/view/pages/add_label_page.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -1,11 +1,8 @@
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/core/logic/error_code_localization_mapper.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/storage_path_query.dart';
import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart'; import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart';
import 'package:paperless_mobile/features/labels/storage_path/model/storage_path.model.dart';
import 'package:paperless_mobile/features/labels/storage_path/view/widgets/storage_path_autofill_form_builder_field.dart'; import 'package:paperless_mobile/features/labels/storage_path/view/widgets/storage_path_autofill_form_builder_field.dart';
import 'package:paperless_mobile/features/labels/view/pages/edit_label_page.dart'; import 'package:paperless_mobile/features/labels/view/pages/edit_label_page.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
@@ -43,7 +40,7 @@ class EditStoragePathPage extends StatelessWidget {
); );
} }
Navigator.pop(context); Navigator.pop(context);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,11 +1,9 @@
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/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/storage_path_query.dart'; import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/model/label_state.dart';
import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart'; import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart';
import 'package:paperless_mobile/features/labels/storage_path/model/storage_path.model.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
class StoragePathWidget extends StatelessWidget { class StoragePathWidget extends StatelessWidget {
@@ -59,7 +57,7 @@ class StoragePathWidget extends StatelessWidget {
); );
} }
afterSelected?.call(); afterSelected?.call();
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,5 +1,5 @@
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart'; import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/tags/model/tag.model.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
@singleton @singleton
@@ -8,15 +8,15 @@ class TagCubit extends LabelCubit<Tag> {
@override @override
Future<void> initialize() async { Future<void> initialize() async {
return labelRepository.getTags().then(loadFrom); return labelsApi.getTags().then(loadFrom);
} }
@override @override
Future<Tag> save(Tag item) => labelRepository.saveTag(item); Future<Tag> save(Tag item) => labelsApi.saveTag(item);
@override @override
Future<Tag> update(Tag item) => labelRepository.updateTag(item); Future<Tag> update(Tag item) => labelsApi.updateTag(item);
@override @override
Future<int> delete(Tag item) => labelRepository.deleteTag(item); Future<int> delete(Tag item) => labelsApi.deleteTag(item);
} }

View File

@@ -1,8 +1,8 @@
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: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_mobile/features/labels/tags/bloc/tags_cubit.dart'; import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart';
import 'package:paperless_mobile/features/labels/tags/model/tag.model.dart';
import 'package:paperless_mobile/features/labels/view/pages/add_label_page.dart'; import 'package:paperless_mobile/features/labels/view/pages/add_label_page.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:form_builder_extra_fields/form_builder_extra_fields.dart'; import 'package:form_builder_extra_fields/form_builder_extra_fields.dart';

View File

@@ -2,12 +2,9 @@ import 'package:flutter/material.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:form_builder_extra_fields/form_builder_extra_fields.dart'; import 'package:form_builder_extra_fields/form_builder_extra_fields.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/tags_query.dart';
import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart'; import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart';
import 'package:paperless_mobile/features/labels/tags/model/tag.model.dart';
import 'package:paperless_mobile/features/labels/view/pages/edit_label_page.dart'; import 'package:paperless_mobile/features/labels/view/pages/edit_label_page.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
@@ -61,7 +58,7 @@ class EditTagPage extends StatelessWidget {
} }
cubit.updateFilter(filter: updatedFilter); cubit.updateFilter(filter: updatedFilter);
Navigator.pop(context); Navigator.pop(context);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,5 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:paperless_mobile/features/labels/tags/model/tag.model.dart'; import 'package:paperless_api/paperless_api.dart';
class TagWidget extends StatelessWidget { class TagWidget extends StatelessWidget {
final Tag tag; final Tag tag;

View File

@@ -2,10 +2,9 @@ import 'package:flutter/material.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';
import 'package:paperless_mobile/features/documents/model/query_parameters/tags_query.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/model/label_state.dart'; import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart'; import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart';
import 'package:paperless_mobile/features/labels/tags/model/tag.model.dart';
import 'package:paperless_mobile/features/labels/tags/view/pages/add_tag_page.dart'; import 'package:paperless_mobile/features/labels/tags/view/pages/add_tag_page.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';

View File

@@ -1,8 +1,8 @@
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/features/labels/model/label_state.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart'; import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart';
import 'package:paperless_mobile/features/labels/tags/model/tag.model.dart';
import 'package:paperless_mobile/features/labels/tags/view/widgets/tag_widget.dart'; import 'package:paperless_mobile/features/labels/tags/view/widgets/tag_widget.dart';
class TagsWidget extends StatefulWidget { class TagsWidget extends StatefulWidget {

View File

@@ -1,17 +1,12 @@
import 'dart:developer';
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/features/labels/bloc/label_cubit.dart'; import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:paperless_mobile/core/logic/error_code_localization_mapper.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/core/type/types.dart'; import 'package:paperless_mobile/core/type/types.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/labels/document_type/model/matching_algorithm.dart'; import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/features/labels/model/label.model.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
import 'package:form_builder_validators/form_builder_validators.dart';
class AddLabelPage<T extends Label> extends StatefulWidget { class AddLabelPage<T extends Label> extends StatefulWidget {
final String? initialName; final String? initialName;
@@ -107,8 +102,8 @@ class _AddLabelPageState<T extends Label> extends State<AddLabelPage<T>> {
final label = await widget.cubit final label = await widget.cubit
.add(widget.fromJson(_formKey.currentState!.value)); .add(widget.fromJson(_formKey.currentState!.value));
Navigator.pop(context, label); Navigator.pop(context, label);
} on ErrorMessage catch (e) { } on PaperlessServerException catch (error, stackTrace) {
showSnackBar(context, translateError(context, e.code)); showErrorMessage(context, error, stackTrace);
} on PaperlessValidationErrors catch (json) { } on PaperlessValidationErrors catch (json) {
setState(() => _errors = json); setState(() => _errors = json);
} }

View File

@@ -3,11 +3,9 @@ import 'dart:async';
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:form_builder_validators/form_builder_validators.dart'; import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/type/types.dart'; import 'package:paperless_mobile/core/type/types.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/labels/document_type/model/matching_algorithm.dart';
import 'package:paperless_mobile/features/labels/model/label.model.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:paperless_mobile/util.dart'; import 'package:paperless_mobile/util.dart';
@@ -146,7 +144,7 @@ class _EditLabelPageState<T extends Label> extends State<EditLabelPage<T>> {
Navigator.pop(context); Navigator.pop(context);
} on PaperlessValidationErrors catch (errorMessages) { } on PaperlessValidationErrors catch (errorMessages) {
setState(() => _errors = errorMessages); setState(() => _errors = errorMessages);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -1,28 +1,20 @@
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/features/labels/bloc/global_state_bloc_provider.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/correspondent_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/document_type_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/storage_path_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/tags_query.dart';
import 'package:paperless_mobile/features/home/view/widget/info_drawer.dart'; import 'package:paperless_mobile/features/home/view/widget/info_drawer.dart';
import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart';
import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart'; import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart';
import 'package:paperless_mobile/features/labels/correspondent/model/correspondent.model.dart';
import 'package:paperless_mobile/features/labels/correspondent/view/pages/add_correspondent_page.dart'; import 'package:paperless_mobile/features/labels/correspondent/view/pages/add_correspondent_page.dart';
import 'package:paperless_mobile/features/labels/correspondent/view/pages/edit_correspondent_page.dart'; import 'package:paperless_mobile/features/labels/correspondent/view/pages/edit_correspondent_page.dart';
import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart'; import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart';
import 'package:paperless_mobile/features/labels/document_type/model/document_type.model.dart';
import 'package:paperless_mobile/features/labels/document_type/view/pages/add_document_type_page.dart'; import 'package:paperless_mobile/features/labels/document_type/view/pages/add_document_type_page.dart';
import 'package:paperless_mobile/features/labels/document_type/view/pages/edit_document_type_page.dart'; import 'package:paperless_mobile/features/labels/document_type/view/pages/edit_document_type_page.dart';
import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart'; import 'package:paperless_mobile/features/labels/storage_path/bloc/storage_path_cubit.dart';
import 'package:paperless_mobile/features/labels/storage_path/model/storage_path.model.dart';
import 'package:paperless_mobile/features/labels/storage_path/view/pages/add_storage_path_page.dart'; import 'package:paperless_mobile/features/labels/storage_path/view/pages/add_storage_path_page.dart';
import 'package:paperless_mobile/features/labels/storage_path/view/pages/edit_storage_path_page.dart'; import 'package:paperless_mobile/features/labels/storage_path/view/pages/edit_storage_path_page.dart';
import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart'; import 'package:paperless_mobile/features/labels/tags/bloc/tags_cubit.dart';
import 'package:paperless_mobile/features/labels/tags/model/tag.model.dart';
import 'package:paperless_mobile/features/labels/tags/view/pages/add_tag_page.dart'; import 'package:paperless_mobile/features/labels/tags/view/pages/add_tag_page.dart';
import 'package:paperless_mobile/features/labels/tags/view/pages/edit_tag_page.dart'; import 'package:paperless_mobile/features/labels/tags/view/pages/edit_tag_page.dart';
import 'package:paperless_mobile/features/labels/view/widgets/label_tab_view.dart'; import 'package:paperless_mobile/features/labels/view/widgets/label_tab_view.dart';

View File

@@ -1,10 +1,6 @@
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/features/documents/model/query_parameters/correspondent_query.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/id_query_parameter.dart';
import 'package:paperless_mobile/features/labels/correspondent/model/correspondent.model.dart';
import 'package:paperless_mobile/features/labels/document_type/model/document_type.model.dart';
import 'package:paperless_mobile/features/labels/model/label.model.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:form_builder_extra_fields/form_builder_extra_fields.dart'; import 'package:form_builder_extra_fields/form_builder_extra_fields.dart';

View File

@@ -1,13 +1,8 @@
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_mobile/features/labels/bloc/global_state_bloc_provider.dart'; import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart';
import 'package:paperless_mobile/core/logic/error_code_localization_mapper.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
import 'package:paperless_mobile/features/labels/model/label.model.dart';
import 'package:paperless_mobile/features/linked_documents_preview/bloc/linked_documents_cubit.dart'; import 'package:paperless_mobile/features/linked_documents_preview/bloc/linked_documents_cubit.dart';
import 'package:paperless_mobile/features/linked_documents_preview/view/pages/linked_documents_page.dart'; import 'package:paperless_mobile/features/linked_documents_preview/view/pages/linked_documents_page.dart';

View File

@@ -1,11 +1,10 @@
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_mobile/core/bloc/connectivity_cubit.dart'; import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart'; import 'package:paperless_mobile/features/labels/bloc/label_cubit.dart';
import 'package:paperless_mobile/core/widgets/offline_widget.dart'; import 'package:paperless_mobile/core/widgets/offline_widget.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart'; import 'package:paperless_mobile/features/labels/bloc/label_state.dart';
import 'package:paperless_mobile/features/labels/model/label.model.dart';
import 'package:paperless_mobile/features/labels/model/label_state.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/extensions/flutter_extensions.dart';

View File

@@ -1,18 +1,16 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
import 'package:paperless_mobile/features/linked_documents_preview/bloc/state/linked_documents_state.dart'; import 'package:paperless_mobile/features/linked_documents_preview/bloc/state/linked_documents_state.dart';
@injectable @injectable
class LinkedDocumentsCubit extends Cubit<LinkedDocumentsState> { class LinkedDocumentsCubit extends Cubit<LinkedDocumentsState> {
final DocumentRepository _documentRepository; final PaperlessDocumentsApi _api;
LinkedDocumentsCubit(this._documentRepository) LinkedDocumentsCubit(this._api) : super(LinkedDocumentsState());
: super(LinkedDocumentsState());
Future<void> initialize(DocumentFilter filter) async { Future<void> initialize(DocumentFilter filter) async {
final documents = await _documentRepository.find( final documents = await _api.find(
filter.copyWith( filter.copyWith(
pageSize: 100, pageSize: 100,
), ),

View File

@@ -1,6 +1,4 @@
import 'package:paperless_mobile/features/documents/model/document.model.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/model/document_filter.dart';
import 'package:paperless_mobile/features/documents/model/paged_search_result.dart';
class LinkedDocumentsState { class LinkedDocumentsState {
final bool isLoaded; final bool isLoaded;

View File

@@ -1,12 +1,11 @@
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:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart'; import 'package:paperless_mobile/core/widgets/documents_list_loading_widget.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart'; import 'package:paperless_mobile/features/document_details/bloc/document_details_cubit.dart';
import 'package:paperless_mobile/features/document_details/view/pages/document_details_page.dart'; import 'package:paperless_mobile/features/document_details/view/pages/document_details_page.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
import 'package:paperless_mobile/features/documents/view/widgets/list/document_list_item.dart'; import 'package:paperless_mobile/features/documents/view/widgets/list/document_list_item.dart';
import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart'; import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart';
import 'package:paperless_mobile/features/linked_documents_preview/bloc/linked_documents_cubit.dart'; import 'package:paperless_mobile/features/linked_documents_preview/bloc/linked_documents_cubit.dart';
@@ -69,7 +68,7 @@ class _LinkedDocumentsPageState extends State<LinkedDocumentsPage> {
additionalProviders: [ additionalProviders: [
BlocProvider<DocumentDetailsCubit>.value( BlocProvider<DocumentDetailsCubit>.value(
value: DocumentDetailsCubit( value: DocumentDetailsCubit(
getIt<DocumentRepository>(), getIt<PaperlessDocumentsApi>(),
document, document,
), ),
), ),

View File

@@ -1,8 +1,8 @@
import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:injectable/injectable.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/store/local_vault.dart'; import 'package:paperless_mobile/core/store/local_vault.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/login/model/authentication_information.dart'; import 'package:paperless_mobile/features/login/model/authentication_information.dart';
@@ -10,18 +10,19 @@ import 'package:paperless_mobile/features/login/model/client_certificate.dart';
import 'package:paperless_mobile/features/login/model/user_credentials.model.dart'; import 'package:paperless_mobile/features/login/model/user_credentials.model.dart';
import 'package:paperless_mobile/features/login/services/authentication.service.dart'; import 'package:paperless_mobile/features/login/services/authentication.service.dart';
import 'package:paperless_mobile/features/settings/model/application_settings_state.dart'; import 'package:paperless_mobile/features/settings/model/application_settings_state.dart';
import 'package:injectable/injectable.dart';
const authenticationKey = "authentication"; const authenticationKey = "authentication";
@singleton @singleton
class AuthenticationCubit extends Cubit<AuthenticationState> { class AuthenticationCubit extends Cubit<AuthenticationState> {
final LocalAuthenticationService _localAuthService;
final PaperlessAuthenticationApi _authApi;
final LocalVault localStore; final LocalVault localStore;
final AuthenticationService authenticationService;
AuthenticationCubit( AuthenticationCubit(
this.localStore, this.localStore,
this.authenticationService, this._localAuthService,
this._authApi,
) : super(AuthenticationState.initial); ) : super(AuthenticationState.initial);
Future<void> initialize() { Future<void> initialize() {
@@ -49,7 +50,7 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
), ),
), ),
); );
final token = await authenticationService.login( final token = await _authApi.login(
username: credentials.username!, username: credentials.username!,
password: credentials.password!, password: credentials.password!,
serverUrl: serverUrl, serverUrl: serverUrl,
@@ -70,14 +71,14 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
authentication: auth, authentication: auth,
)); ));
} on TlsException catch (_) { } on TlsException catch (_) {
const error = const error = PaperlessServerException(
ErrorMessage(ErrorCode.invalidClientCertificateConfiguration); ErrorCode.invalidClientCertificateConfiguration);
throw error; throw error;
} on SocketException catch (err) { } on SocketException catch (err) {
if (err.message.contains("connection timed out")) { if (err.message.contains("connection timed out")) {
throw const ErrorMessage(ErrorCode.requestTimedOut); throw const PaperlessServerException(ErrorCode.requestTimedOut);
} else { } else {
throw ErrorMessage.unknown(); throw const PaperlessServerException.unknown();
} }
} }
} }
@@ -95,7 +96,7 @@ class AuthenticationCubit extends Cubit<AuthenticationState> {
emit(AuthenticationState(isAuthenticated: false, wasLoginStored: false)); emit(AuthenticationState(isAuthenticated: false, wasLoginStored: false));
} else { } else {
if (!appSettings.isLocalAuthenticationEnabled || if (!appSettings.isLocalAuthenticationEnabled ||
await authenticationService await _localAuthService
.authenticateLocalUser("Authenticate to log back in")) { .authenticateLocalUser("Authenticate to log back in")) {
registerSecurityContext(storedAuth.clientCertificate); registerSecurityContext(storedAuth.clientCertificate);
emit( emit(

View File

@@ -1,5 +1,5 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:local_auth/local_auth.dart'; import 'package:local_auth/local_auth.dart';
@@ -12,7 +12,8 @@ class LocalAuthenticationCubit extends Cubit<LocalAuthenticationState> {
if (isAuthenticationSuccessful) { if (isAuthenticationSuccessful) {
emit(LocalAuthenticationState(true)); emit(LocalAuthenticationState(true));
} else { } else {
throw const ErrorMessage(ErrorCode.biometricAuthenticationFailed); throw const PaperlessServerException(
ErrorCode.biometricAuthenticationFailed);
} }
} }
} }

View File

@@ -1,57 +1,17 @@
import 'dart:convert';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/core/store/local_vault.dart';
import 'package:http/http.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:local_auth/local_auth.dart'; import 'package:local_auth/local_auth.dart';
import 'package:paperless_mobile/core/store/local_vault.dart';
@singleton @singleton
class AuthenticationService { class LocalAuthenticationService {
final BaseClient httpClient;
final LocalVault localStore; final LocalVault localStore;
final LocalAuthentication localAuthentication; final LocalAuthentication localAuthentication;
AuthenticationService( LocalAuthenticationService(
this.localStore, this.localStore,
this.localAuthentication, this.localAuthentication,
@Named("timeoutClient") this.httpClient,
); );
///
/// Returns the authentication token.
///
Future<String> login({
required String username,
required String password,
required String serverUrl,
}) async {
late Response response;
try {
response = await httpClient.post(
Uri.parse("/api/token/"),
body: {"username": username, "password": password},
);
} on FormatException catch (e) {
final source = e.source;
if (source is String &&
source.contains("400 No required SSL certificate was sent")) {
throw const ErrorMessage(ErrorCode.missingClientCertificate);
}
}
if (response.statusCode == 200) {
final data = jsonDecode(utf8.decode(response.bodyBytes));
return data['token'];
} else if (response.statusCode == 400 &&
response.body
.toLowerCase()
.contains("no required certificate was sent")) {
throw const ErrorMessage(ErrorCode.invalidClientCertificateConfiguration);
} else {
throw const ErrorMessage(ErrorCode.authenticationFailed);
}
}
Future<bool> authenticateLocalUser(String localizedReason) async { Future<bool> authenticateLocalUser(String localizedReason) async {
if (await localAuthentication.isDeviceSupported()) { if (await localAuthentication.isDeviceSupported()) {
return await localAuthentication.authenticate( return await localAuthentication.authenticate(

View File

@@ -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:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart'; import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart';
import 'package:paperless_mobile/features/login/view/widgets/client_certificate_form_field.dart'; import 'package:paperless_mobile/features/login/view/widgets/client_certificate_form_field.dart';
@@ -97,12 +97,12 @@ class _LoginPageState extends State<LoginPage> {
clientCertificate: clientCertificate:
form[ClientCertificateFormField.fkClientCertificate], form[ClientCertificateFormField.fkClientCertificate],
); );
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} on Map<String, dynamic> catch (error, stackTrace) { } on Map<String, dynamic> catch (error, stackTrace) {
showGenericError(context, error.values.first, stackTrace); showGenericError(context, error.values.first, stackTrace);
} catch (unknownError, stackTrace) { } catch (unknownError, stackTrace) {
showErrorMessage(context, ErrorMessage.unknown(), stackTrace); showGenericError(context, unknownError.toString(), stackTrace);
} finally { } finally {
setState(() => _isLoginLoading = false); setState(() => _isLoginLoading = false);
} }

View File

@@ -1,20 +1,19 @@
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/model/saved_view.model.dart';
import 'package:paperless_mobile/features/documents/repository/saved_views_repository.dart';
import 'package:paperless_mobile/features/saved_view/bloc/saved_view_state.dart'; import 'package:paperless_mobile/features/saved_view/bloc/saved_view_state.dart';
@singleton @singleton
class SavedViewCubit extends Cubit<SavedViewState> { class SavedViewCubit extends Cubit<SavedViewState> {
SavedViewCubit() : super(SavedViewState(value: {})); final PaperlessSavedViewsApi _api;
SavedViewCubit(this._api) : super(SavedViewState(value: {}));
void selectView(SavedView? view) { void selectView(SavedView? view) {
emit(SavedViewState(value: state.value, selectedSavedViewId: view?.id)); emit(SavedViewState(value: state.value, selectedSavedViewId: view?.id));
} }
Future<SavedView> add(SavedView view) async { Future<SavedView> add(SavedView view) async {
final savedView = await getIt<SavedViewsRepository>().save(view); final savedView = await _api.save(view);
emit( emit(
SavedViewState( SavedViewState(
value: {...state.value, savedView.id!: savedView}, value: {...state.value, savedView.id!: savedView},
@@ -25,7 +24,7 @@ class SavedViewCubit extends Cubit<SavedViewState> {
} }
Future<int> remove(SavedView view) async { Future<int> remove(SavedView view) async {
final id = await getIt<SavedViewsRepository>().delete(view); final id = await _api.delete(view);
final newValue = {...state.value}; final newValue = {...state.value};
newValue.removeWhere((key, value) => key == id); newValue.removeWhere((key, value) => key == id);
emit( emit(
@@ -40,7 +39,7 @@ class SavedViewCubit extends Cubit<SavedViewState> {
} }
Future<void> initialize() async { Future<void> initialize() async {
final views = await getIt<SavedViewsRepository>().getAll(); final views = await _api.getAll();
final values = {for (var element in views) element.id!: element}; final values = {for (var element in views) element.id!: element};
emit(SavedViewState(value: values)); emit(SavedViewState(value: values));
} }

View File

@@ -1,5 +1,5 @@
import 'package:equatable/equatable.dart'; import 'package:equatable/equatable.dart';
import 'package:paperless_mobile/features/documents/model/saved_view.model.dart'; import 'package:paperless_api/paperless_api.dart';
class SavedViewState with EquatableMixin { class SavedViewState with EquatableMixin {
final Map<int, SavedView> value; final Map<int, SavedView> value;
@@ -11,5 +11,8 @@ class SavedViewState with EquatableMixin {
}); });
@override @override
List<Object?> get props => [value, selectedSavedViewId]; List<Object?> get props => [
value,
selectedSavedViewId,
];
} }

View File

@@ -1,7 +1,6 @@
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/features/documents/model/document_filter.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/model/saved_view.model.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:form_builder_validators/form_builder_validators.dart'; import 'package:form_builder_validators/form_builder_validators.dart';

View File

@@ -1,10 +1,9 @@
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/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart'; import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/model/saved_view.model.dart'; import 'package:paperless_mobile/features/saved_view/view/add_saved_view_page.dart';
import 'package:paperless_mobile/features/documents/view/widgets/selection/add_saved_view_page.dart';
import 'package:paperless_mobile/features/documents/view/widgets/selection/confirm_delete_saved_view_dialog.dart'; import 'package:paperless_mobile/features/documents/view/widgets/selection/confirm_delete_saved_view_dialog.dart';
import 'package:paperless_mobile/features/saved_view/bloc/saved_view_cubit.dart'; import 'package:paperless_mobile/features/saved_view/bloc/saved_view_cubit.dart';
import 'package:paperless_mobile/features/saved_view/bloc/saved_view_state.dart'; import 'package:paperless_mobile/features/saved_view/bloc/saved_view_state.dart';
@@ -87,7 +86,7 @@ class SavedViewSelectionWidget extends StatelessWidget {
if (newView != null) { if (newView != null) {
try { try {
await BlocProvider.of<SavedViewCubit>(context).add(newView); await BlocProvider.of<SavedViewCubit>(context).add(newView);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }
@@ -104,7 +103,7 @@ class SavedViewSelectionWidget extends StatelessWidget {
BlocProvider.of<DocumentsCubit>(context).updateFilter(); BlocProvider.of<DocumentsCubit>(context).updateFilter();
BlocProvider.of<SavedViewCubit>(context).selectView(null); BlocProvider.of<SavedViewCubit>(context).selectView(null);
} }
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }
@@ -119,7 +118,7 @@ class SavedViewSelectionWidget extends StatelessWidget {
if (delete) { if (delete) {
try { try {
BlocProvider.of<SavedViewCubit>(context).remove(view); BlocProvider.of<SavedViewCubit>(context).remove(view);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }

View File

@@ -4,18 +4,18 @@ import 'dart:io';
import 'package:flutter/foundation.dart'; 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_mobile/core/model/error_message.dart';
import 'package:injectable/injectable.dart'; import 'package:injectable/injectable.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart';
@injectable @injectable
class DocumentScannerCubit extends Cubit<List<File>> { class DocumentScannerCubit extends Cubit<List<File>> {
final DocumentRepository documentRepository; final PaperlessDocumentsApi _api;
static List<File> initialState = []; static List<File> initialState = [];
DocumentScannerCubit(this.documentRepository) : super(initialState); DocumentScannerCubit(this._api) : super(initialState);
void addScan(File file) => emit([...state, file]); void addScan(File file) => emit([...state, file]);
@@ -26,7 +26,7 @@ class DocumentScannerCubit extends Cubit<List<File>> {
scans.removeAt(fileIndex); scans.removeAt(fileIndex);
emit(scans); emit(scans);
} catch (_) { } catch (_) {
throw const ErrorMessage(ErrorCode.scanRemoveFailed); throw const PaperlessServerException(ErrorCode.scanRemoveFailed);
} }
} }
@@ -41,7 +41,7 @@ class DocumentScannerCubit extends Cubit<List<File>> {
imageCache.clear(); imageCache.clear();
emit(initialState); emit(initialState);
} catch (_) { } catch (_) {
throw const ErrorMessage(ErrorCode.scanRemoveFailed); throw const PaperlessServerException(ErrorCode.scanRemoveFailed);
} }
} }
@@ -55,17 +55,23 @@ class DocumentScannerCubit extends Cubit<List<File>> {
Iterable<int> tags = const [], Iterable<int> tags = const [],
DateTime? createdAt, DateTime? createdAt,
}) async { }) async {
await documentRepository.create( final auth = getIt<AuthenticationCubit>().state.authentication;
if (auth == null) {
throw const PaperlessServerException(ErrorCode.notAuthenticated);
}
await _api.create(
bytes, bytes,
fileName, filename: fileName,
title: title, title: title,
documentType: documentType, documentType: documentType,
correspondent: correspondent, correspondent: correspondent,
tags: tags, tags: tags,
createdAt: createdAt, createdAt: createdAt,
authToken: auth.token,
serverUrl: auth.serverUrl,
); );
if (onConsumptionFinished != null) { if (onConsumptionFinished != null) {
documentRepository _api
.waitForConsumptionFinished(fileName, title) .waitForConsumptionFinished(fileName, title)
.then((value) => onConsumptionFinished(value)); .then((value) => onConsumptionFinished(value));
} }

View File

@@ -3,23 +3,15 @@ import 'dart:typed_data';
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:flutter_form_builder/flutter_form_builder.dart'; import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:paperless_mobile/core/model/error_message.dart'; import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/type/types.dart'; import 'package:paperless_mobile/core/type/types.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/extensions/flutter_extensions.dart'; import 'package:paperless_mobile/extensions/flutter_extensions.dart';
import 'package:paperless_mobile/features/documents/model/document.model.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/correspondent_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/document_type_query.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/id_query_parameter.dart';
import 'package:paperless_mobile/features/documents/model/query_parameters/tags_query.dart';
import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart'; import 'package:paperless_mobile/features/labels/correspondent/bloc/correspondents_cubit.dart';
import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart'; import 'package:paperless_mobile/features/labels/document_type/bloc/document_type_cubit.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/labels/correspondent/model/correspondent.model.dart';
import 'package:paperless_mobile/features/labels/correspondent/view/pages/add_correspondent_page.dart'; import 'package:paperless_mobile/features/labels/correspondent/view/pages/add_correspondent_page.dart';
import 'package:paperless_mobile/features/labels/document_type/model/document_type.model.dart';
import 'package:paperless_mobile/features/labels/document_type/view/pages/add_document_type_page.dart'; import 'package:paperless_mobile/features/labels/document_type/view/pages/add_document_type_page.dart';
import 'package:paperless_mobile/features/labels/model/label_state.dart'; import 'package:paperless_mobile/features/labels/bloc/label_state.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';
import 'package:paperless_mobile/features/scan/bloc/document_scanner_cubit.dart'; import 'package:paperless_mobile/features/scan/bloc/document_scanner_cubit.dart';
@@ -258,12 +250,13 @@ class _DocumentUploadPageState extends State<DocumentUploadPage> {
showSnackBar(context, S.of(context).documentUploadSuccessText); showSnackBar(context, S.of(context).documentUploadSuccessText);
Navigator.pop(context); Navigator.pop(context);
widget.afterUpload?.call(); widget.afterUpload?.call();
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} on PaperlessValidationErrors catch (errorMessages) { } on PaperlessValidationErrors catch (PaperlessServerExceptions) {
setState(() => _errors = errorMessages); setState(() => _errors = PaperlessServerExceptions);
} catch (unknownError, stackTrace) { } catch (unknownError, stackTrace) {
showErrorMessage(context, const ErrorMessage.unknown(), stackTrace); showErrorMessage(
context, const PaperlessServerException.unknown(), stackTrace);
} finally { } finally {
setState(() { setState(() {
_isUploadLoading = false; _isUploadLoading = false;

View File

@@ -8,13 +8,10 @@ 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:mime/mime.dart'; import 'package:mime/mime.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart'; import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart';
import 'package:paperless_mobile/core/global/constants.dart'; import 'package:paperless_mobile/core/global/constants.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/core/service/file_service.dart'; import 'package:paperless_mobile/core/service/file_service.dart';
import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/documents/bloc/documents_cubit.dart';
import 'package:paperless_mobile/features/documents/repository/document_repository.dart';
import 'package:paperless_mobile/features/documents/view/pages/document_view.dart'; import 'package:paperless_mobile/features/documents/view/pages/document_view.dart';
import 'package:paperless_mobile/features/home/view/widget/info_drawer.dart'; import 'package:paperless_mobile/features/home/view/widget/info_drawer.dart';
import 'package:paperless_mobile/features/scan/bloc/document_scanner_cubit.dart'; import 'package:paperless_mobile/features/scan/bloc/document_scanner_cubit.dart';
@@ -193,7 +190,7 @@ class _ScannerPageState extends State<ScannerPage>
try { try {
BlocProvider.of<DocumentScannerCubit>(context) BlocProvider.of<DocumentScannerCubit>(context)
.removeScan(index); .removeScan(index);
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
}, },
@@ -206,7 +203,7 @@ class _ScannerPageState extends State<ScannerPage>
void _reset(BuildContext context) { void _reset(BuildContext context) {
try { try {
BlocProvider.of<DocumentScannerCubit>(context).reset(); BlocProvider.of<DocumentScannerCubit>(context).reset();
} on ErrorMessage catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} }
} }
@@ -231,7 +228,7 @@ class _ScannerPageState extends State<ScannerPage>
)) { )) {
showErrorMessage( showErrorMessage(
context, context,
const ErrorMessage(ErrorCode.unsupportedFileFormat), const PaperlessServerException(ErrorCode.unsupportedFileFormat),
); );
return; return;
} }

View File

@@ -28,7 +28,7 @@ class BiometricAuthenticationSetting extends StatelessWidget {
: S : S
.of(context) .of(context)
.appSettingsDisableBiometricAuthenticationReasonText; .appSettingsDisableBiometricAuthenticationReasonText;
final changeValue = await getIt<AuthenticationService>() final changeValue = await getIt<LocalAuthenticationService>()
.authenticateLocalUser(localizedReason); .authenticateLocalUser(localizedReason);
if (changeValue) { if (changeValue) {
settingsBloc.setIsBiometricAuthenticationEnabled(val); settingsBloc.setIsBiometricAuthenticationEnabled(val);

View File

@@ -14,13 +14,18 @@ class LanguageSelectionSetting extends StatefulWidget {
} }
class _LanguageSelectionSettingState extends State<LanguageSelectionSetting> { class _LanguageSelectionSettingState extends State<LanguageSelectionSetting> {
static const _languageOptions = {
'en': 'English',
'de': 'Deutsch',
'cs': 'Česky',
};
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BlocBuilder<ApplicationSettingsCubit, ApplicationSettingsState>( return BlocBuilder<ApplicationSettingsCubit, ApplicationSettingsState>(
builder: (context, settings) { builder: (context, settings) {
return ListTile( return ListTile(
title: Text(S.of(context).settingsPageLanguageSettingLabel), title: Text(S.of(context).settingsPageLanguageSettingLabel),
subtitle: Text(_mapSubtagToLanguage(settings.preferredLocaleSubtag)), subtitle: Text(_languageOptions[settings.preferredLocaleSubtag]!),
onTap: () => showDialog( onTap: () => showDialog(
context: context, context: context,
builder: (_) => RadioSettingsDialog<String>( builder: (_) => RadioSettingsDialog<String>(
@@ -28,12 +33,16 @@ class _LanguageSelectionSettingState extends State<LanguageSelectionSetting> {
options: [ options: [
RadioOption( RadioOption(
value: 'en', value: 'en',
label: _mapSubtagToLanguage('en'), label: _languageOptions['en']!,
), ),
RadioOption( RadioOption(
value: 'de', value: 'de',
label: _mapSubtagToLanguage('de'), label: _languageOptions['de']!,
), ),
RadioOption(
value: 'cs',
label: _languageOptions['cs']!,
)
], ],
initialValue: BlocProvider.of<ApplicationSettingsCubit>(context) initialValue: BlocProvider.of<ApplicationSettingsCubit>(context)
.state .state
@@ -45,15 +54,4 @@ class _LanguageSelectionSettingState extends State<LanguageSelectionSetting> {
}, },
); );
} }
_mapSubtagToLanguage(String subtag) {
switch (subtag) {
case 'en':
return "English";
case 'de':
return "Deutsch";
default:
return "English";
}
}
} }

View File

@@ -415,5 +415,7 @@
"tagInboxTagPropertyLabel": "Tag inboxu", "tagInboxTagPropertyLabel": "Tag inboxu",
"@tagInboxTagPropertyLabel": {}, "@tagInboxTagPropertyLabel": {},
"uploadPageAutomaticallInferredFieldsHintText": "Pokud specifikuješ hodnoty pro tato pole, paperless instance nebude automaticky přiřazovat naučené hodnoty. Pokud mají být tato pole automaticky vyplňována, nevyplňujte zde nic.", "uploadPageAutomaticallInferredFieldsHintText": "Pokud specifikuješ hodnoty pro tato pole, paperless instance nebude automaticky přiřazovat naučené hodnoty. Pokud mají být tato pole automaticky vyplňována, nevyplňujte zde nic.",
"@uploadPageAutomaticallInferredFieldsHintText": {} "@uploadPageAutomaticallInferredFieldsHintText": {},
} "inboxPageNoNewDocumentsText": "You do not have unseen documents.",
"inboxPageNoNewDocumentsRefreshLabel": "Refresh"
}

View File

@@ -415,5 +415,7 @@
"tagInboxTagPropertyLabel": "Posteingangs-Tag", "tagInboxTagPropertyLabel": "Posteingangs-Tag",
"@tagInboxTagPropertyLabel": {}, "@tagInboxTagPropertyLabel": {},
"uploadPageAutomaticallInferredFieldsHintText": "Wenn Werte für diese Felder angegeben werden, wird Paperless nicht automatisch einen Wert zuweisen. Wenn diese Felder automatisch von Paperless erkannt werden sollen, sollten die Felder leer bleiben.", "uploadPageAutomaticallInferredFieldsHintText": "Wenn Werte für diese Felder angegeben werden, wird Paperless nicht automatisch einen Wert zuweisen. Wenn diese Felder automatisch von Paperless erkannt werden sollen, sollten die Felder leer bleiben.",
"@uploadPageAutomaticallInferredFieldsHintText": {} "@uploadPageAutomaticallInferredFieldsHintText": {},
"inboxPageNoNewDocumentsText": "You do not have unseen documents.",
"inboxPageNoNewDocumentsRefreshLabel": "Refresh"
} }

View File

@@ -1,419 +1,421 @@
{ {
"@@locale": "en", "@@locale": "en",
"aboutDialogDevelopedByText": "Developed by", "aboutDialogDevelopedByText": "Developed by",
"@aboutDialogDevelopedByText": {}, "@aboutDialogDevelopedByText": {},
"addCorrespondentPageTitle": "New Correspondent", "addCorrespondentPageTitle": "New Correspondent",
"@addCorrespondentPageTitle": {}, "@addCorrespondentPageTitle": {},
"addDocumentTypePageTitle": "New Document Type", "addDocumentTypePageTitle": "New Document Type",
"@addDocumentTypePageTitle": {}, "@addDocumentTypePageTitle": {},
"addStoragePathPageTitle": "New Storage Path", "addStoragePathPageTitle": "New Storage Path",
"@addStoragePathPageTitle": {}, "@addStoragePathPageTitle": {},
"addTagPageTitle": "New Tag", "addTagPageTitle": "New Tag",
"@addTagPageTitle": {}, "@addTagPageTitle": {},
"appDrawerAboutInfoLoadingText": "Retrieving application information...", "appDrawerAboutInfoLoadingText": "Retrieving application information...",
"@appDrawerAboutInfoLoadingText": {}, "@appDrawerAboutInfoLoadingText": {},
"appDrawerAboutLabel": "About this app", "appDrawerAboutLabel": "About this app",
"@appDrawerAboutLabel": {}, "@appDrawerAboutLabel": {},
"appDrawerHeaderLoggedInAsText": "Logged in as ", "appDrawerHeaderLoggedInAsText": "Logged in as ",
"@appDrawerHeaderLoggedInAsText": {}, "@appDrawerHeaderLoggedInAsText": {},
"appDrawerLogoutLabel": "Disconnect", "appDrawerLogoutLabel": "Disconnect",
"@appDrawerLogoutLabel": {}, "@appDrawerLogoutLabel": {},
"appDrawerReportBugLabel": "Report a Bug", "appDrawerReportBugLabel": "Report a Bug",
"@appDrawerReportBugLabel": {}, "@appDrawerReportBugLabel": {},
"appDrawerSettingsLabel": "Settings", "appDrawerSettingsLabel": "Settings",
"@appDrawerSettingsLabel": {}, "@appDrawerSettingsLabel": {},
"appSettingsBiometricAuthenticationDescriptionText": "Authenticate on app start", "appSettingsBiometricAuthenticationDescriptionText": "Authenticate on app start",
"@appSettingsBiometricAuthenticationDescriptionText": {}, "@appSettingsBiometricAuthenticationDescriptionText": {},
"appSettingsBiometricAuthenticationLabel": "Biometric authentication", "appSettingsBiometricAuthenticationLabel": "Biometric authentication",
"@appSettingsBiometricAuthenticationLabel": {}, "@appSettingsBiometricAuthenticationLabel": {},
"appSettingsDisableBiometricAuthenticationReasonText": "Authenticate to disable biometric authentication", "appSettingsDisableBiometricAuthenticationReasonText": "Authenticate to disable biometric authentication",
"@appSettingsDisableBiometricAuthenticationReasonText": {}, "@appSettingsDisableBiometricAuthenticationReasonText": {},
"appSettingsEnableBiometricAuthenticationReasonText": "Authenticate to enable biometric authentication", "appSettingsEnableBiometricAuthenticationReasonText": "Authenticate to enable biometric authentication",
"@appSettingsEnableBiometricAuthenticationReasonText": {}, "@appSettingsEnableBiometricAuthenticationReasonText": {},
"appTitleText": "Paperless Mobile", "appTitleText": "Paperless Mobile",
"@appTitleText": {}, "@appTitleText": {},
"bottomNavDocumentsPageLabel": "Documents", "bottomNavDocumentsPageLabel": "Documents",
"@bottomNavDocumentsPageLabel": {}, "@bottomNavDocumentsPageLabel": {},
"bottomNavInboxPageLabel": "Inbox", "bottomNavInboxPageLabel": "Inbox",
"@bottomNavInboxPageLabel": {}, "@bottomNavInboxPageLabel": {},
"bottomNavLabelsPageLabel": "Labels", "bottomNavLabelsPageLabel": "Labels",
"@bottomNavLabelsPageLabel": {}, "@bottomNavLabelsPageLabel": {},
"bottomNavScannerPageLabel": "Scanner", "bottomNavScannerPageLabel": "Scanner",
"@bottomNavScannerPageLabel": {}, "@bottomNavScannerPageLabel": {},
"correspondentFormFieldSearchHintText": "Start typing...", "correspondentFormFieldSearchHintText": "Start typing...",
"@correspondentFormFieldSearchHintText": {}, "@correspondentFormFieldSearchHintText": {},
"deleteViewDialogContentText": "Do you really want to delete this view?", "deleteViewDialogContentText": "Do you really want to delete this view?",
"@deleteViewDialogContentText": {}, "@deleteViewDialogContentText": {},
"deleteViewDialogTitleText": "Delete view ", "deleteViewDialogTitleText": "Delete view ",
"@deleteViewDialogTitleText": {}, "@deleteViewDialogTitleText": {},
"documentAddedPropertyLabel": "Added At", "documentAddedPropertyLabel": "Added At",
"@documentAddedPropertyLabel": {}, "@documentAddedPropertyLabel": {},
"documentArchiveSerialNumberPropertyLongLabel": "Archive Serial Number", "documentArchiveSerialNumberPropertyLongLabel": "Archive Serial Number",
"@documentArchiveSerialNumberPropertyLongLabel": {}, "@documentArchiveSerialNumberPropertyLongLabel": {},
"documentArchiveSerialNumberPropertyShortLabel": "ASN", "documentArchiveSerialNumberPropertyShortLabel": "ASN",
"@documentArchiveSerialNumberPropertyShortLabel": {}, "@documentArchiveSerialNumberPropertyShortLabel": {},
"documentCorrespondentPropertyLabel": "Correspondent", "documentCorrespondentPropertyLabel": "Correspondent",
"@documentCorrespondentPropertyLabel": {}, "@documentCorrespondentPropertyLabel": {},
"documentCreatedPropertyLabel": "Created At", "documentCreatedPropertyLabel": "Created At",
"@documentCreatedPropertyLabel": {}, "@documentCreatedPropertyLabel": {},
"documentDeleteSuccessMessage": "Document successfully deleted.", "documentDeleteSuccessMessage": "Document successfully deleted.",
"@documentDeleteSuccessMessage": {}, "@documentDeleteSuccessMessage": {},
"documentDetailsPageAssignAsnButtonLabel": "Assign", "documentDetailsPageAssignAsnButtonLabel": "Assign",
"@documentDetailsPageAssignAsnButtonLabel": {}, "@documentDetailsPageAssignAsnButtonLabel": {},
"documentDetailsPageSimilarDocumentsLabel": "Similar Documents", "documentDetailsPageSimilarDocumentsLabel": "Similar Documents",
"@documentDetailsPageSimilarDocumentsLabel": {}, "@documentDetailsPageSimilarDocumentsLabel": {},
"documentDetailsPageTabContentLabel": "Content", "documentDetailsPageTabContentLabel": "Content",
"@documentDetailsPageTabContentLabel": {}, "@documentDetailsPageTabContentLabel": {},
"documentDetailsPageTabMetaDataLabel": "Meta Data", "documentDetailsPageTabMetaDataLabel": "Meta Data",
"@documentDetailsPageTabMetaDataLabel": {}, "@documentDetailsPageTabMetaDataLabel": {},
"documentDetailsPageTabOverviewLabel": "Overview", "documentDetailsPageTabOverviewLabel": "Overview",
"@documentDetailsPageTabOverviewLabel": {}, "@documentDetailsPageTabOverviewLabel": {},
"documentDocumentTypePropertyLabel": "Document Type", "documentDocumentTypePropertyLabel": "Document Type",
"@documentDocumentTypePropertyLabel": {}, "@documentDocumentTypePropertyLabel": {},
"documentEditPageTitle": "Edit Document", "documentEditPageTitle": "Edit Document",
"@documentEditPageTitle": {}, "@documentEditPageTitle": {},
"documentMetaDataChecksumLabel": "Original MD5-Checksum", "documentMetaDataChecksumLabel": "Original MD5-Checksum",
"@documentMetaDataChecksumLabel": {}, "@documentMetaDataChecksumLabel": {},
"documentMetaDataMediaFilenamePropertyLabel": "Media Filename", "documentMetaDataMediaFilenamePropertyLabel": "Media Filename",
"@documentMetaDataMediaFilenamePropertyLabel": {}, "@documentMetaDataMediaFilenamePropertyLabel": {},
"documentMetaDataOriginalFileSizeLabel": "Original File Size", "documentMetaDataOriginalFileSizeLabel": "Original File Size",
"@documentMetaDataOriginalFileSizeLabel": {}, "@documentMetaDataOriginalFileSizeLabel": {},
"documentMetaDataOriginalMimeTypeLabel": "Original MIME-Type", "documentMetaDataOriginalMimeTypeLabel": "Original MIME-Type",
"@documentMetaDataOriginalMimeTypeLabel": {}, "@documentMetaDataOriginalMimeTypeLabel": {},
"documentModifiedPropertyLabel": "Modified At", "documentModifiedPropertyLabel": "Modified At",
"@documentModifiedPropertyLabel": {}, "@documentModifiedPropertyLabel": {},
"documentPreviewPageTitle": "Preview", "documentPreviewPageTitle": "Preview",
"@documentPreviewPageTitle": {}, "@documentPreviewPageTitle": {},
"documentScannerPageAddScanButtonLabel": "Scan a document", "documentScannerPageAddScanButtonLabel": "Scan a document",
"@documentScannerPageAddScanButtonLabel": {}, "@documentScannerPageAddScanButtonLabel": {},
"documentScannerPageEmptyStateText": "No documents scanned yet.", "documentScannerPageEmptyStateText": "No documents scanned yet.",
"@documentScannerPageEmptyStateText": {}, "@documentScannerPageEmptyStateText": {},
"documentScannerPageOrText": "or", "documentScannerPageOrText": "or",
"@documentScannerPageOrText": {}, "@documentScannerPageOrText": {},
"documentScannerPageResetButtonTooltipText": "Delete all scans", "documentScannerPageResetButtonTooltipText": "Delete all scans",
"@documentScannerPageResetButtonTooltipText": {}, "@documentScannerPageResetButtonTooltipText": {},
"documentScannerPageTitle": "Scan", "documentScannerPageTitle": "Scan",
"@documentScannerPageTitle": {}, "@documentScannerPageTitle": {},
"documentScannerPageUploadButtonTooltip": "Upload to Paperless", "documentScannerPageUploadButtonTooltip": "Upload to Paperless",
"@documentScannerPageUploadButtonTooltip": {}, "@documentScannerPageUploadButtonTooltip": {},
"documentScannerPageUploadFromThisDeviceButtonLabel": "Upload a document from this device", "documentScannerPageUploadFromThisDeviceButtonLabel": "Upload a document from this device",
"@documentScannerPageUploadFromThisDeviceButtonLabel": {}, "@documentScannerPageUploadFromThisDeviceButtonLabel": {},
"documentsFilterPageAdvancedLabel": "Advanced", "documentsFilterPageAdvancedLabel": "Advanced",
"@documentsFilterPageAdvancedLabel": {}, "@documentsFilterPageAdvancedLabel": {},
"documentsFilterPageApplyFilterLabel": "Apply", "documentsFilterPageApplyFilterLabel": "Apply",
"@documentsFilterPageApplyFilterLabel": {}, "@documentsFilterPageApplyFilterLabel": {},
"documentsFilterPageDateRangeFieldEndLabel": "To", "documentsFilterPageDateRangeFieldEndLabel": "To",
"@documentsFilterPageDateRangeFieldEndLabel": {}, "@documentsFilterPageDateRangeFieldEndLabel": {},
"documentsFilterPageDateRangeFieldStartLabel": "From", "documentsFilterPageDateRangeFieldStartLabel": "From",
"@documentsFilterPageDateRangeFieldStartLabel": {}, "@documentsFilterPageDateRangeFieldStartLabel": {},
"documentsFilterPageDateRangeLastMonthLabel": "Last Month", "documentsFilterPageDateRangeLastMonthLabel": "Last Month",
"@documentsFilterPageDateRangeLastMonthLabel": {}, "@documentsFilterPageDateRangeLastMonthLabel": {},
"documentsFilterPageDateRangeLastSevenDaysLabel": "Last 7 Days", "documentsFilterPageDateRangeLastSevenDaysLabel": "Last 7 Days",
"@documentsFilterPageDateRangeLastSevenDaysLabel": {}, "@documentsFilterPageDateRangeLastSevenDaysLabel": {},
"documentsFilterPageDateRangeLastThreeMonthsLabel": "Last 3 Months", "documentsFilterPageDateRangeLastThreeMonthsLabel": "Last 3 Months",
"@documentsFilterPageDateRangeLastThreeMonthsLabel": {}, "@documentsFilterPageDateRangeLastThreeMonthsLabel": {},
"documentsFilterPageDateRangeLastYearLabel": "Last Year", "documentsFilterPageDateRangeLastYearLabel": "Last Year",
"@documentsFilterPageDateRangeLastYearLabel": {}, "@documentsFilterPageDateRangeLastYearLabel": {},
"documentsFilterPageQueryOptionsAsnLabel": "ASN", "documentsFilterPageQueryOptionsAsnLabel": "ASN",
"@documentsFilterPageQueryOptionsAsnLabel": {}, "@documentsFilterPageQueryOptionsAsnLabel": {},
"documentsFilterPageQueryOptionsExtendedLabel": "Extended", "documentsFilterPageQueryOptionsExtendedLabel": "Extended",
"@documentsFilterPageQueryOptionsExtendedLabel": {}, "@documentsFilterPageQueryOptionsExtendedLabel": {},
"documentsFilterPageQueryOptionsTitleAndContentLabel": "Title & Content", "documentsFilterPageQueryOptionsTitleAndContentLabel": "Title & Content",
"@documentsFilterPageQueryOptionsTitleAndContentLabel": {}, "@documentsFilterPageQueryOptionsTitleAndContentLabel": {},
"documentsFilterPageQueryOptionsTitleLabel": "Title", "documentsFilterPageQueryOptionsTitleLabel": "Title",
"@documentsFilterPageQueryOptionsTitleLabel": {}, "@documentsFilterPageQueryOptionsTitleLabel": {},
"documentsFilterPageResetFilterLabel": "Reset", "documentsFilterPageResetFilterLabel": "Reset",
"@documentsFilterPageResetFilterLabel": {}, "@documentsFilterPageResetFilterLabel": {},
"documentsFilterPageSearchLabel": "Search", "documentsFilterPageSearchLabel": "Search",
"@documentsFilterPageSearchLabel": {}, "@documentsFilterPageSearchLabel": {},
"documentsFilterPageTitle": "Filter Documents", "documentsFilterPageTitle": "Filter Documents",
"@documentsFilterPageTitle": {}, "@documentsFilterPageTitle": {},
"documentsPageBulkDeleteSuccessfulText": "Documents successfully deleted.", "documentsPageBulkDeleteSuccessfulText": "Documents successfully deleted.",
"@documentsPageBulkDeleteSuccessfulText": {}, "@documentsPageBulkDeleteSuccessfulText": {},
"documentsPageEmptyStateNothingHereText": "There seems to be nothing here...", "documentsPageEmptyStateNothingHereText": "There seems to be nothing here...",
"@documentsPageEmptyStateNothingHereText": {}, "@documentsPageEmptyStateNothingHereText": {},
"documentsPageEmptyStateOopsText": "Oops.", "documentsPageEmptyStateOopsText": "Oops.",
"@documentsPageEmptyStateOopsText": {}, "@documentsPageEmptyStateOopsText": {},
"documentsPageOrderByLabel": "Order By", "documentsPageOrderByLabel": "Order By",
"@documentsPageOrderByLabel": {}, "@documentsPageOrderByLabel": {},
"documentsPageSelectionBulkDeleteDialogContinueText": "This action is irreversible. Do you wish to proceed anyway?", "documentsPageSelectionBulkDeleteDialogContinueText": "This action is irreversible. Do you wish to proceed anyway?",
"@documentsPageSelectionBulkDeleteDialogContinueText": {}, "@documentsPageSelectionBulkDeleteDialogContinueText": {},
"documentsPageSelectionBulkDeleteDialogTitle": "Confirm deletion", "documentsPageSelectionBulkDeleteDialogTitle": "Confirm deletion",
"@documentsPageSelectionBulkDeleteDialogTitle": {}, "@documentsPageSelectionBulkDeleteDialogTitle": {},
"documentsPageSelectionBulkDeleteDialogWarningTextMany": "Are you sure you want to delete the following documents?", "documentsPageSelectionBulkDeleteDialogWarningTextMany": "Are you sure you want to delete the following documents?",
"@documentsPageSelectionBulkDeleteDialogWarningTextMany": {}, "@documentsPageSelectionBulkDeleteDialogWarningTextMany": {},
"documentsPageSelectionBulkDeleteDialogWarningTextOne": "Are you sure you want to delete the following document?", "documentsPageSelectionBulkDeleteDialogWarningTextOne": "Are you sure you want to delete the following document?",
"@documentsPageSelectionBulkDeleteDialogWarningTextOne": {}, "@documentsPageSelectionBulkDeleteDialogWarningTextOne": {},
"documentsPageTitle": "Documents", "documentsPageTitle": "Documents",
"@documentsPageTitle": {}, "@documentsPageTitle": {},
"documentsSelectedText": "selected", "documentsSelectedText": "selected",
"@documentsSelectedText": {}, "@documentsSelectedText": {},
"documentStoragePathPropertyLabel": "Storage Path", "documentStoragePathPropertyLabel": "Storage Path",
"@documentStoragePathPropertyLabel": {}, "@documentStoragePathPropertyLabel": {},
"documentsUploadPageTitle": "Prepare document", "documentsUploadPageTitle": "Prepare document",
"@documentsUploadPageTitle": {}, "@documentsUploadPageTitle": {},
"documentTagsPropertyLabel": "Tags", "documentTagsPropertyLabel": "Tags",
"@documentTagsPropertyLabel": {}, "@documentTagsPropertyLabel": {},
"documentTitlePropertyLabel": "Title", "documentTitlePropertyLabel": "Title",
"@documentTitlePropertyLabel": {}, "@documentTitlePropertyLabel": {},
"documentTypeFormFieldSearchHintText": "Start typing...", "documentTypeFormFieldSearchHintText": "Start typing...",
"@documentTypeFormFieldSearchHintText": {}, "@documentTypeFormFieldSearchHintText": {},
"documentUpdateSuccessMessage": "Document successfully updated.", "documentUpdateSuccessMessage": "Document successfully updated.",
"@documentUpdateSuccessMessage": {}, "@documentUpdateSuccessMessage": {},
"documentUploadFileNameLabel": "File Name", "documentUploadFileNameLabel": "File Name",
"@documentUploadFileNameLabel": {}, "@documentUploadFileNameLabel": {},
"documentUploadPageSynchronizeTitleAndFilenameLabel": "Synchronize title and filename", "documentUploadPageSynchronizeTitleAndFilenameLabel": "Synchronize title and filename",
"@documentUploadPageSynchronizeTitleAndFilenameLabel": {}, "@documentUploadPageSynchronizeTitleAndFilenameLabel": {},
"documentUploadProcessingSuccessfulReloadActionText": "Reload", "documentUploadProcessingSuccessfulReloadActionText": "Reload",
"@documentUploadProcessingSuccessfulReloadActionText": {}, "@documentUploadProcessingSuccessfulReloadActionText": {},
"documentUploadProcessingSuccessfulText": "Document successfully processed.", "documentUploadProcessingSuccessfulText": "Document successfully processed.",
"@documentUploadProcessingSuccessfulText": {}, "@documentUploadProcessingSuccessfulText": {},
"documentUploadSuccessText": "Document successfully uploaded, processing...", "documentUploadSuccessText": "Document successfully uploaded, processing...",
"@documentUploadSuccessText": {}, "@documentUploadSuccessText": {},
"editLabelPageConfirmDeletionDialogTitle": "Confirm deletion", "editLabelPageConfirmDeletionDialogTitle": "Confirm deletion",
"@editLabelPageConfirmDeletionDialogTitle": {}, "@editLabelPageConfirmDeletionDialogTitle": {},
"editLabelPageDeletionDialogText": "This label contains references to other documents. By deleting this label, all references will be removed. Continue?", "editLabelPageDeletionDialogText": "This label contains references to other documents. By deleting this label, all references will be removed. Continue?",
"@editLabelPageDeletionDialogText": {}, "@editLabelPageDeletionDialogText": {},
"errorMessageAuthenticationFailed": "Authentication failed, please try again.", "errorMessageAuthenticationFailed": "Authentication failed, please try again.",
"@errorMessageAuthenticationFailed": {}, "@errorMessageAuthenticationFailed": {},
"errorMessageAutocompleteQueryError": "An error ocurred while trying to autocomplete your query.", "errorMessageAutocompleteQueryError": "An error ocurred while trying to autocomplete your query.",
"@errorMessageAutocompleteQueryError": {}, "@errorMessageAutocompleteQueryError": {},
"errorMessageBiometricAuthenticationFailed": "Biometric authentication failed.", "errorMessageBiometricAuthenticationFailed": "Biometric authentication failed.",
"@errorMessageBiometricAuthenticationFailed": {}, "@errorMessageBiometricAuthenticationFailed": {},
"errorMessageBiotmetricsNotSupported": "Biometric authentication not supported on this device.", "errorMessageBiotmetricsNotSupported": "Biometric authentication not supported on this device.",
"@errorMessageBiotmetricsNotSupported": {}, "@errorMessageBiotmetricsNotSupported": {},
"errorMessageBulkActionFailed": "Could not bulk edit documents.", "errorMessageBulkActionFailed": "Could not bulk edit documents.",
"@errorMessageBulkActionFailed": {}, "@errorMessageBulkActionFailed": {},
"errorMessageCorrespondentCreateFailed": "Could not create correspondent, please try again.", "errorMessageCorrespondentCreateFailed": "Could not create correspondent, please try again.",
"@errorMessageCorrespondentCreateFailed": {}, "@errorMessageCorrespondentCreateFailed": {},
"errorMessageCorrespondentLoadFailed": "Could not load correspondents.", "errorMessageCorrespondentLoadFailed": "Could not load correspondents.",
"@errorMessageCorrespondentLoadFailed": {}, "@errorMessageCorrespondentLoadFailed": {},
"errorMessageCreateSavedViewError": "Could not create saved view, please try again.", "errorMessageCreateSavedViewError": "Could not create saved view, please try again.",
"@errorMessageCreateSavedViewError": {}, "@errorMessageCreateSavedViewError": {},
"errorMessageDeleteSavedViewError": "Could not delete saved view, please try again", "errorMessageDeleteSavedViewError": "Could not delete saved view, please try again",
"@errorMessageDeleteSavedViewError": {}, "@errorMessageDeleteSavedViewError": {},
"errorMessageDeviceOffline": "Could not fetch data: You are not connected to the internet.", "errorMessageDeviceOffline": "Could not fetch data: You are not connected to the internet.",
"@errorMessageDeviceOffline": {}, "@errorMessageDeviceOffline": {},
"errorMessageDocumentAsnQueryFailed": "Could not assign archive serial number.", "errorMessageDocumentAsnQueryFailed": "Could not assign archive serial number.",
"@errorMessageDocumentAsnQueryFailed": {}, "@errorMessageDocumentAsnQueryFailed": {},
"errorMessageDocumentDeleteFailed": "Could not delete document, please try again.", "errorMessageDocumentDeleteFailed": "Could not delete document, please try again.",
"@errorMessageDocumentDeleteFailed": {}, "@errorMessageDocumentDeleteFailed": {},
"errorMessageDocumentLoadFailed": "Could not load documents, please try again.", "errorMessageDocumentLoadFailed": "Could not load documents, please try again.",
"@errorMessageDocumentLoadFailed": {}, "@errorMessageDocumentLoadFailed": {},
"errorMessageDocumentPreviewFailed": "Could not load document preview.", "errorMessageDocumentPreviewFailed": "Could not load document preview.",
"@errorMessageDocumentPreviewFailed": {}, "@errorMessageDocumentPreviewFailed": {},
"errorMessageDocumentTypeCreateFailed": "Could not create document, please try again.", "errorMessageDocumentTypeCreateFailed": "Could not create document, please try again.",
"@errorMessageDocumentTypeCreateFailed": {}, "@errorMessageDocumentTypeCreateFailed": {},
"errorMessageDocumentTypeLoadFailed": "Could not load document types, please try again.", "errorMessageDocumentTypeLoadFailed": "Could not load document types, please try again.",
"@errorMessageDocumentTypeLoadFailed": {}, "@errorMessageDocumentTypeLoadFailed": {},
"errorMessageDocumentUpdateFailed": "Could not update document, please try again.", "errorMessageDocumentUpdateFailed": "Could not update document, please try again.",
"@errorMessageDocumentUpdateFailed": {}, "@errorMessageDocumentUpdateFailed": {},
"errorMessageDocumentUploadFailed": "Could not upload document, please try again.", "errorMessageDocumentUploadFailed": "Could not upload document, please try again.",
"@errorMessageDocumentUploadFailed": {}, "@errorMessageDocumentUploadFailed": {},
"errorMessageInvalidClientCertificateConfiguration": "Invalid certificate or missing passphrase, please try again", "errorMessageInvalidClientCertificateConfiguration": "Invalid certificate or missing passphrase, please try again",
"@errorMessageInvalidClientCertificateConfiguration": {}, "@errorMessageInvalidClientCertificateConfiguration": {},
"errorMessageLoadSavedViewsError": "Could not load saved views.", "errorMessageLoadSavedViewsError": "Could not load saved views.",
"@errorMessageLoadSavedViewsError": {}, "@errorMessageLoadSavedViewsError": {},
"errorMessageMissingClientCertificate": "A client certificate was expected but not sent. Please provide a valid client certificate.", "errorMessageMissingClientCertificate": "A client certificate was expected but not sent. Please provide a valid client certificate.",
"@errorMessageMissingClientCertificate": {}, "@errorMessageMissingClientCertificate": {},
"errorMessageNotAuthenticated": "User is not authenticated.", "errorMessageNotAuthenticated": "User is not authenticated.",
"@errorMessageNotAuthenticated": {}, "@errorMessageNotAuthenticated": {},
"errorMessageRequestTimedOut": "The request to the server timed out.", "errorMessageRequestTimedOut": "The request to the server timed out.",
"@errorMessageRequestTimedOut": {}, "@errorMessageRequestTimedOut": {},
"errorMessageScanRemoveFailed": "An error occurred removing the scans.", "errorMessageScanRemoveFailed": "An error occurred removing the scans.",
"@errorMessageScanRemoveFailed": {}, "@errorMessageScanRemoveFailed": {},
"errorMessageServerUnreachable": "Could not reach your Paperless server, is it up and running?", "errorMessageServerUnreachable": "Could not reach your Paperless server, is it up and running?",
"@errorMessageServerUnreachable": {}, "@errorMessageServerUnreachable": {},
"errorMessageSimilarQueryError": "Could not load similar documents.", "errorMessageSimilarQueryError": "Could not load similar documents.",
"@errorMessageSimilarQueryError": {}, "@errorMessageSimilarQueryError": {},
"errorMessageStoragePathCreateFailed": "Could not create storage path, please try again.", "errorMessageStoragePathCreateFailed": "Could not create storage path, please try again.",
"@errorMessageStoragePathCreateFailed": {}, "@errorMessageStoragePathCreateFailed": {},
"errorMessageStoragePathLoadFailed": "Could not load storage paths.", "errorMessageStoragePathLoadFailed": "Could not load storage paths.",
"@errorMessageStoragePathLoadFailed": {}, "@errorMessageStoragePathLoadFailed": {},
"errorMessageTagCreateFailed": "Could not create tag, please try again.", "errorMessageTagCreateFailed": "Could not create tag, please try again.",
"@errorMessageTagCreateFailed": {}, "@errorMessageTagCreateFailed": {},
"errorMessageTagLoadFailed": "Could not load tags.", "errorMessageTagLoadFailed": "Could not load tags.",
"@errorMessageTagLoadFailed": {}, "@errorMessageTagLoadFailed": {},
"errorMessageUnknonwnError": "An unknown error occurred.", "errorMessageUnknonwnError": "An unknown error occurred.",
"@errorMessageUnknonwnError": {}, "@errorMessageUnknonwnError": {},
"errorMessageUnsupportedFileFormat": "This file format is not supported.", "errorMessageUnsupportedFileFormat": "This file format is not supported.",
"@errorMessageUnsupportedFileFormat": {}, "@errorMessageUnsupportedFileFormat": {},
"errorReportLabel": "REPORT", "errorReportLabel": "REPORT",
"@errorReportLabel": {}, "@errorReportLabel": {},
"genericActionCancelLabel": "Cancel", "genericActionCancelLabel": "Cancel",
"@genericActionCancelLabel": {}, "@genericActionCancelLabel": {},
"genericActionCreateLabel": "Create", "genericActionCreateLabel": "Create",
"@genericActionCreateLabel": {}, "@genericActionCreateLabel": {},
"genericActionDeleteLabel": "Delete", "genericActionDeleteLabel": "Delete",
"@genericActionDeleteLabel": {}, "@genericActionDeleteLabel": {},
"genericActionEditLabel": "Edit", "genericActionEditLabel": "Edit",
"@genericActionEditLabel": {}, "@genericActionEditLabel": {},
"genericActionOkLabel": "Ok", "genericActionOkLabel": "Ok",
"@genericActionOkLabel": {}, "@genericActionOkLabel": {},
"genericActionSaveLabel": "Save", "genericActionSaveLabel": "Save",
"@genericActionSaveLabel": {}, "@genericActionSaveLabel": {},
"genericActionSelectText": "Select", "genericActionSelectText": "Select",
"@genericActionSelectText": {}, "@genericActionSelectText": {},
"genericActionUpdateLabel": "Update", "genericActionUpdateLabel": "Update",
"@genericActionUpdateLabel": {}, "@genericActionUpdateLabel": {},
"genericActionUploadLabel": "Upload", "genericActionUploadLabel": "Upload",
"@genericActionUploadLabel": {}, "@genericActionUploadLabel": {},
"genericMessageOfflineText": "You're offline. Check your connection.", "genericMessageOfflineText": "You're offline. Check your connection.",
"@genericMessageOfflineText": {}, "@genericMessageOfflineText": {},
"inboxPageDocumentRemovedMessageText": "Document removed from inbox.", "inboxPageDocumentRemovedMessageText": "Document removed from inbox.",
"@inboxPageDocumentRemovedMessageText": {}, "@inboxPageDocumentRemovedMessageText": {},
"inboxPageMarkAllAsSeenConfirmationDialogText": "Are you sure you want to mark all documents as seen? This will perform a bulk edit operation removing all inbox tags from the documents.\nThis action is not reversible! Are you sure you want to continue?", "inboxPageMarkAllAsSeenConfirmationDialogText": "Are you sure you want to mark all documents as seen? This will perform a bulk edit operation removing all inbox tags from the documents.\nThis action is not reversible! Are you sure you want to continue?",
"@inboxPageMarkAllAsSeenConfirmationDialogText": {}, "@inboxPageMarkAllAsSeenConfirmationDialogText": {},
"inboxPageMarkAllAsSeenConfirmationDialogTitleText": "Mark all as seen?", "inboxPageMarkAllAsSeenConfirmationDialogTitleText": "Mark all as seen?",
"@inboxPageMarkAllAsSeenConfirmationDialogTitleText": {}, "@inboxPageMarkAllAsSeenConfirmationDialogTitleText": {},
"inboxPageMarkAllAsSeenLabel": "Mark all as seen", "inboxPageMarkAllAsSeenLabel": "Mark all as seen",
"@inboxPageMarkAllAsSeenLabel": {}, "@inboxPageMarkAllAsSeenLabel": {},
"inboxPageMarkAsSeenText": "Mark as seen", "inboxPageMarkAsSeenText": "Mark as seen",
"@inboxPageMarkAsSeenText": {}, "@inboxPageMarkAsSeenText": {},
"inboxPageTodayText": "Today", "inboxPageTodayText": "Today",
"@inboxPageTodayText": {}, "@inboxPageTodayText": {},
"inboxPageUndoRemoveText": "UNDO", "inboxPageUndoRemoveText": "UNDO",
"@inboxPageUndoRemoveText": {}, "@inboxPageUndoRemoveText": {},
"inboxPageUnseenText": "unseen", "inboxPageUnseenText": "unseen",
"@inboxPageUnseenText": {}, "@inboxPageUnseenText": {},
"inboxPageUsageHintText": "Hint: Swipe left to mark a document as seen and remove all inbox tags from the document.", "inboxPageUsageHintText": "Hint: Swipe left to mark a document as seen and remove all inbox tags from the document.",
"@inboxPageUsageHintText": {}, "@inboxPageUsageHintText": {},
"inboxPageYesterdayText": "Yesterday", "inboxPageYesterdayText": "Yesterday",
"@inboxPageYesterdayText": {}, "@inboxPageYesterdayText": {},
"labelAnyAssignedText": "Any assigned", "labelAnyAssignedText": "Any assigned",
"@labelAnyAssignedText": {}, "@labelAnyAssignedText": {},
"labelFormFieldNoItemsFoundText": "No items found!", "labelFormFieldNoItemsFoundText": "No items found!",
"@labelFormFieldNoItemsFoundText": {}, "@labelFormFieldNoItemsFoundText": {},
"labelIsInsensivitePropertyLabel": "Case Irrelevant", "labelIsInsensivitePropertyLabel": "Case Irrelevant",
"@labelIsInsensivitePropertyLabel": {}, "@labelIsInsensivitePropertyLabel": {},
"labelMatchingAlgorithmPropertyLabel": "Matching Algorithm", "labelMatchingAlgorithmPropertyLabel": "Matching Algorithm",
"@labelMatchingAlgorithmPropertyLabel": {}, "@labelMatchingAlgorithmPropertyLabel": {},
"labelMatchPropertyLabel": "Match", "labelMatchPropertyLabel": "Match",
"@labelMatchPropertyLabel": {}, "@labelMatchPropertyLabel": {},
"labelNamePropertyLabel": "Name", "labelNamePropertyLabel": "Name",
"@labelNamePropertyLabel": {}, "@labelNamePropertyLabel": {},
"labelNotAssignedText": "Not assigned", "labelNotAssignedText": "Not assigned",
"@labelNotAssignedText": {}, "@labelNotAssignedText": {},
"labelsPageCorrespondentEmptyStateAddNewLabel": "Add new correspondent", "labelsPageCorrespondentEmptyStateAddNewLabel": "Add new correspondent",
"@labelsPageCorrespondentEmptyStateAddNewLabel": {}, "@labelsPageCorrespondentEmptyStateAddNewLabel": {},
"labelsPageCorrespondentEmptyStateDescriptionText": "You don't seem to have any correspondents set up.", "labelsPageCorrespondentEmptyStateDescriptionText": "You don't seem to have any correspondents set up.",
"@labelsPageCorrespondentEmptyStateDescriptionText": {}, "@labelsPageCorrespondentEmptyStateDescriptionText": {},
"labelsPageCorrespondentsTitleText": "Correspondents", "labelsPageCorrespondentsTitleText": "Correspondents",
"@labelsPageCorrespondentsTitleText": {}, "@labelsPageCorrespondentsTitleText": {},
"labelsPageDocumentTypeEmptyStateAddNewLabel": "Add new document type", "labelsPageDocumentTypeEmptyStateAddNewLabel": "Add new document type",
"@labelsPageDocumentTypeEmptyStateAddNewLabel": {}, "@labelsPageDocumentTypeEmptyStateAddNewLabel": {},
"labelsPageDocumentTypeEmptyStateDescriptionText": "You don't seem to have any document types set up.", "labelsPageDocumentTypeEmptyStateDescriptionText": "You don't seem to have any document types set up.",
"@labelsPageDocumentTypeEmptyStateDescriptionText": {}, "@labelsPageDocumentTypeEmptyStateDescriptionText": {},
"labelsPageDocumentTypesTitleText": "Document Types", "labelsPageDocumentTypesTitleText": "Document Types",
"@labelsPageDocumentTypesTitleText": {}, "@labelsPageDocumentTypesTitleText": {},
"labelsPageStoragePathEmptyStateAddNewLabel": "Add new storage path", "labelsPageStoragePathEmptyStateAddNewLabel": "Add new storage path",
"@labelsPageStoragePathEmptyStateAddNewLabel": {}, "@labelsPageStoragePathEmptyStateAddNewLabel": {},
"labelsPageStoragePathEmptyStateDescriptionText": "You don't seem to have any storage paths set up.", "labelsPageStoragePathEmptyStateDescriptionText": "You don't seem to have any storage paths set up.",
"@labelsPageStoragePathEmptyStateDescriptionText": {}, "@labelsPageStoragePathEmptyStateDescriptionText": {},
"labelsPageStoragePathTitleText": "Storage Paths", "labelsPageStoragePathTitleText": "Storage Paths",
"@labelsPageStoragePathTitleText": {}, "@labelsPageStoragePathTitleText": {},
"labelsPageTagsEmptyStateAddNewLabel": "Add new tag", "labelsPageTagsEmptyStateAddNewLabel": "Add new tag",
"@labelsPageTagsEmptyStateAddNewLabel": {}, "@labelsPageTagsEmptyStateAddNewLabel": {},
"labelsPageTagsEmptyStateDescriptionText": "You don't seem to have any tags set up.", "labelsPageTagsEmptyStateDescriptionText": "You don't seem to have any tags set up.",
"@labelsPageTagsEmptyStateDescriptionText": {}, "@labelsPageTagsEmptyStateDescriptionText": {},
"labelsPageTagsTitleText": "Tags", "labelsPageTagsTitleText": "Tags",
"@labelsPageTagsTitleText": {}, "@labelsPageTagsTitleText": {},
"linkedDocumentsPageTitle": "Linked Documents", "linkedDocumentsPageTitle": "Linked Documents",
"@linkedDocumentsPageTitle": {}, "@linkedDocumentsPageTitle": {},
"loginPageAdvancedLabel": "Advanced Settings", "loginPageAdvancedLabel": "Advanced Settings",
"@loginPageAdvancedLabel": {}, "@loginPageAdvancedLabel": {},
"loginPageClientCertificatePassphraseLabel": "Passphrase", "loginPageClientCertificatePassphraseLabel": "Passphrase",
"@loginPageClientCertificatePassphraseLabel": {}, "@loginPageClientCertificatePassphraseLabel": {},
"loginPageClientCertificateSettingDescriptionText": "Configure Mutual TLS Authentication", "loginPageClientCertificateSettingDescriptionText": "Configure Mutual TLS Authentication",
"@loginPageClientCertificateSettingDescriptionText": {}, "@loginPageClientCertificateSettingDescriptionText": {},
"loginPageClientCertificateSettingInvalidFileFormatValidationText": "Invalid certificate format, only .pfx is allowed", "loginPageClientCertificateSettingInvalidFileFormatValidationText": "Invalid certificate format, only .pfx is allowed",
"@loginPageClientCertificateSettingInvalidFileFormatValidationText": {}, "@loginPageClientCertificateSettingInvalidFileFormatValidationText": {},
"loginPageClientCertificateSettingLabel": "Client Certificate", "loginPageClientCertificateSettingLabel": "Client Certificate",
"@loginPageClientCertificateSettingLabel": {}, "@loginPageClientCertificateSettingLabel": {},
"loginPageClientCertificateSettingSelectFileText": "Select file...", "loginPageClientCertificateSettingSelectFileText": "Select file...",
"@loginPageClientCertificateSettingSelectFileText": {}, "@loginPageClientCertificateSettingSelectFileText": {},
"loginPageIncorrectOrMissingCertificatePassphraseErrorMessageText": "Incorrect or missing certificate passphrase.", "loginPageIncorrectOrMissingCertificatePassphraseErrorMessageText": "Incorrect or missing certificate passphrase.",
"@loginPageIncorrectOrMissingCertificatePassphraseErrorMessageText": {}, "@loginPageIncorrectOrMissingCertificatePassphraseErrorMessageText": {},
"loginPageLoginButtonLabel": "Connect", "loginPageLoginButtonLabel": "Connect",
"@loginPageLoginButtonLabel": {}, "@loginPageLoginButtonLabel": {},
"loginPagePasswordFieldLabel": "Password", "loginPagePasswordFieldLabel": "Password",
"@loginPagePasswordFieldLabel": {}, "@loginPagePasswordFieldLabel": {},
"loginPagePasswordValidatorMessageText": "Password must not be empty.", "loginPagePasswordValidatorMessageText": "Password must not be empty.",
"@loginPagePasswordValidatorMessageText": {}, "@loginPagePasswordValidatorMessageText": {},
"loginPageServerUrlFieldLabel": "Server Address", "loginPageServerUrlFieldLabel": "Server Address",
"@loginPageServerUrlFieldLabel": {}, "@loginPageServerUrlFieldLabel": {},
"loginPageServerUrlValidatorMessageText": "Server address must not be empty.", "loginPageServerUrlValidatorMessageText": "Server address must not be empty.",
"@loginPageServerUrlValidatorMessageText": {}, "@loginPageServerUrlValidatorMessageText": {},
"loginPageTitle": "Connect to Paperless", "loginPageTitle": "Connect to Paperless",
"@loginPageTitle": {}, "@loginPageTitle": {},
"loginPageUsernameLabel": "Username", "loginPageUsernameLabel": "Username",
"@loginPageUsernameLabel": {}, "@loginPageUsernameLabel": {},
"loginPageUsernameValidatorMessageText": "Username must not be empty.", "loginPageUsernameValidatorMessageText": "Username must not be empty.",
"@loginPageUsernameValidatorMessageText": {}, "@loginPageUsernameValidatorMessageText": {},
"offlineWidgetText": "An internet connection could not be established.", "offlineWidgetText": "An internet connection could not be established.",
"@offlineWidgetText": {}, "@offlineWidgetText": {},
"onboardingDoneButtonLabel": "Done", "onboardingDoneButtonLabel": "Done",
"@onboardingDoneButtonLabel": {}, "@onboardingDoneButtonLabel": {},
"onboardingNextButtonLabel": "Next", "onboardingNextButtonLabel": "Next",
"@onboardingNextButtonLabel": {}, "@onboardingNextButtonLabel": {},
"referencedDocumentsReadOnlyHintText": "This is a read-only view! You cannot edit or remove documents. A maximum of 100 referenced documents will be loaded.", "referencedDocumentsReadOnlyHintText": "This is a read-only view! You cannot edit or remove documents. A maximum of 100 referenced documents will be loaded.",
"@referencedDocumentsReadOnlyHintText": {}, "@referencedDocumentsReadOnlyHintText": {},
"savedViewCreateNewLabel": "New View", "savedViewCreateNewLabel": "New View",
"@savedViewCreateNewLabel": {}, "@savedViewCreateNewLabel": {},
"savedViewCreateTooltipText": "Creates a new view based on the current filter criteria.", "savedViewCreateTooltipText": "Creates a new view based on the current filter criteria.",
"@savedViewCreateTooltipText": {}, "@savedViewCreateTooltipText": {},
"savedViewNameLabel": "Name", "savedViewNameLabel": "Name",
"@savedViewNameLabel": {}, "@savedViewNameLabel": {},
"savedViewsEmptyStateText": "Create views to quickly filter your documents.", "savedViewsEmptyStateText": "Create views to quickly filter your documents.",
"@savedViewsEmptyStateText": {}, "@savedViewsEmptyStateText": {},
"savedViewShowInSidebarLabel": "Show in sidebar", "savedViewShowInSidebarLabel": "Show in sidebar",
"@savedViewShowInSidebarLabel": {}, "@savedViewShowInSidebarLabel": {},
"savedViewShowOnDashboardLabel": "Show on dashboard", "savedViewShowOnDashboardLabel": "Show on dashboard",
"@savedViewShowOnDashboardLabel": {}, "@savedViewShowOnDashboardLabel": {},
"savedViewsLabel": "Saved Views", "savedViewsLabel": "Saved Views",
"@savedViewsLabel": {}, "@savedViewsLabel": {},
"serverInformationPaperlessVersionText": "Paperless server version", "serverInformationPaperlessVersionText": "Paperless server version",
"@serverInformationPaperlessVersionText": {}, "@serverInformationPaperlessVersionText": {},
"settingsPageAppearanceSettingDarkThemeLabel": "Dark Theme", "settingsPageAppearanceSettingDarkThemeLabel": "Dark Theme",
"@settingsPageAppearanceSettingDarkThemeLabel": {}, "@settingsPageAppearanceSettingDarkThemeLabel": {},
"settingsPageAppearanceSettingLightThemeLabel": "Light Theme", "settingsPageAppearanceSettingLightThemeLabel": "Light Theme",
"@settingsPageAppearanceSettingLightThemeLabel": {}, "@settingsPageAppearanceSettingLightThemeLabel": {},
"settingsPageAppearanceSettingSystemThemeLabel": "Use system theme", "settingsPageAppearanceSettingSystemThemeLabel": "Use system theme",
"@settingsPageAppearanceSettingSystemThemeLabel": {}, "@settingsPageAppearanceSettingSystemThemeLabel": {},
"settingsPageAppearanceSettingTitle": "Appearance", "settingsPageAppearanceSettingTitle": "Appearance",
"@settingsPageAppearanceSettingTitle": {}, "@settingsPageAppearanceSettingTitle": {},
"settingsPageApplicationSettingsDescriptionText": "Language and visual appearance", "settingsPageApplicationSettingsDescriptionText": "Language and visual appearance",
"@settingsPageApplicationSettingsDescriptionText": {}, "@settingsPageApplicationSettingsDescriptionText": {},
"settingsPageApplicationSettingsLabel": "Application", "settingsPageApplicationSettingsLabel": "Application",
"@settingsPageApplicationSettingsLabel": {}, "@settingsPageApplicationSettingsLabel": {},
"settingsPageLanguageSettingLabel": "Language", "settingsPageLanguageSettingLabel": "Language",
"@settingsPageLanguageSettingLabel": {}, "@settingsPageLanguageSettingLabel": {},
"settingsPageSecuritySettingsDescriptionText": "Biometric authentication", "settingsPageSecuritySettingsDescriptionText": "Biometric authentication",
"@settingsPageSecuritySettingsDescriptionText": {}, "@settingsPageSecuritySettingsDescriptionText": {},
"settingsPageSecuritySettingsLabel": "Security", "settingsPageSecuritySettingsLabel": "Security",
"@settingsPageSecuritySettingsLabel": {}, "@settingsPageSecuritySettingsLabel": {},
"settingsPageStorageSettingsDescriptionText": "Manage files and storage space", "settingsPageStorageSettingsDescriptionText": "Manage files and storage space",
"@settingsPageStorageSettingsDescriptionText": {}, "@settingsPageStorageSettingsDescriptionText": {},
"settingsPageStorageSettingsLabel": "Storage", "settingsPageStorageSettingsLabel": "Storage",
"@settingsPageStorageSettingsLabel": {}, "@settingsPageStorageSettingsLabel": {},
"settingsThemeModeDarkLabel": "Dark", "settingsThemeModeDarkLabel": "Dark",
"@settingsThemeModeDarkLabel": {}, "@settingsThemeModeDarkLabel": {},
"settingsThemeModeLightLabel": "Light", "settingsThemeModeLightLabel": "Light",
"@settingsThemeModeLightLabel": {}, "@settingsThemeModeLightLabel": {},
"settingsThemeModeSystemLabel": "System", "settingsThemeModeSystemLabel": "System",
"@settingsThemeModeSystemLabel": {}, "@settingsThemeModeSystemLabel": {},
"storagePathParameterDayLabel": "day", "storagePathParameterDayLabel": "day",
"@storagePathParameterDayLabel": {}, "@storagePathParameterDayLabel": {},
"storagePathParameterMonthLabel": "month", "storagePathParameterMonthLabel": "month",
"@storagePathParameterMonthLabel": {}, "@storagePathParameterMonthLabel": {},
"storagePathParameterYearLabel": "year", "storagePathParameterYearLabel": "year",
"@storagePathParameterYearLabel": {}, "@storagePathParameterYearLabel": {},
"tagColorPropertyLabel": "Color", "tagColorPropertyLabel": "Color",
"@tagColorPropertyLabel": {}, "@tagColorPropertyLabel": {},
"tagFormFieldSearchHintText": "Filter tags...", "tagFormFieldSearchHintText": "Filter tags...",
"@tagFormFieldSearchHintText": {}, "@tagFormFieldSearchHintText": {},
"tagInboxTagPropertyLabel": "Inbox-Tag", "tagInboxTagPropertyLabel": "Inbox-Tag",
"@tagInboxTagPropertyLabel": {}, "@tagInboxTagPropertyLabel": {},
"uploadPageAutomaticallInferredFieldsHintText": "If you specify values for these fields, your paperless instance will not automatically derive a value. If you want these values to be automatically populated by your server, leave the fields blank.", "uploadPageAutomaticallInferredFieldsHintText": "If you specify values for these fields, your paperless instance will not automatically derive a value. If you want these values to be automatically populated by your server, leave the fields blank.",
"@uploadPageAutomaticallInferredFieldsHintText": {} "@uploadPageAutomaticallInferredFieldsHintText": {},
} "inboxPageNoNewDocumentsText": "You do not have unseen documents.",
"inboxPageNoNewDocumentsRefreshLabel": "Refresh"
}

View File

@@ -1,4 +1,3 @@
import 'dart:developer';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@@ -11,15 +10,14 @@ import 'package:form_builder_validators/form_builder_validators.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:intl/intl_standalone.dart'; import 'package:intl/intl_standalone.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/bloc/bloc_changes_observer.dart'; import 'package:paperless_mobile/core/bloc/bloc_changes_observer.dart';
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart'; import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart'; import 'package:paperless_mobile/features/labels/bloc/global_state_bloc_provider.dart';
import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart'; import 'package:paperless_mobile/core/bloc/paperless_server_information_cubit.dart';
import 'package:paperless_mobile/core/global/asset_images.dart';
import 'package:paperless_mobile/core/global/constants.dart'; import 'package:paperless_mobile/core/global/constants.dart';
import 'package:paperless_mobile/core/global/http_self_signed_certificate_override.dart'; import 'package:paperless_mobile/core/global/http_self_signed_certificate_override.dart';
import 'package:paperless_mobile/core/logic/error_code_localization_mapper.dart'; import 'package:paperless_mobile/core/logic/error_code_localization_mapper.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:paperless_mobile/core/service/file_service.dart'; import 'package:paperless_mobile/core/service/file_service.dart';
import 'package:paperless_mobile/di_initializer.dart'; import 'package:paperless_mobile/di_initializer.dart';
import 'package:paperless_mobile/features/app_intro/application_intro_slideshow.dart'; import 'package:paperless_mobile/features/app_intro/application_intro_slideshow.dart';
@@ -119,15 +117,16 @@ class _PaperlessMobileEntrypointState extends State<PaperlessMobileEntrypoint> {
supportedLocales: const [ supportedLocales: const [
Locale('en'), // Default if system locale is not available Locale('en'), // Default if system locale is not available
Locale('de'), Locale('de'),
Locale('cs'),
], ],
locale: Locale.fromSubtags( locale: Locale.fromSubtags(
languageCode: settings.preferredLocaleSubtag), languageCode: settings.preferredLocaleSubtag),
localizationsDelegates: const [ localizationsDelegates: const [
S.delegate, S.delegate,
GlobalMaterialLocalizations.delegate, GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate, GlobalWidgetsLocalizations.delegate,
FormBuilderLocalizations.delegate, FormBuilderLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
], ],
home: const AuthenticationWrapper(), home: const AuthenticationWrapper(),
); );

View File

@@ -1,21 +1,16 @@
import 'dart:async'; import 'dart:async';
import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'dart:io';
import 'dart:typed_data';
import 'dart:ui'; import 'dart:ui';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:paperless_mobile/core/logic/error_code_localization_mapper.dart';
import 'package:paperless_mobile/core/model/error_message.dart';
import 'package:intl/intl.dart'; import 'package:intl/intl.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/logic/error_code_localization_mapper.dart';
import 'package:paperless_mobile/core/service/github_issue_service.dart'; import 'package:paperless_mobile/core/service/github_issue_service.dart';
import 'package:paperless_mobile/generated/intl/messages_de.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
import 'package:path_provider/path_provider.dart';
final dateFormat = DateFormat("yyyy-MM-dd"); final dateFormat = DateFormat("yyyy-MM-dd");
final GlobalKey<ScaffoldState> rootScaffoldKey = GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> rootScaffoldKey = GlobalKey<ScaffoldState>();
@@ -65,7 +60,7 @@ void showGenericError(
void showErrorMessage( void showErrorMessage(
BuildContext context, BuildContext context,
ErrorMessage error, [ PaperlessServerException error, [
StackTrace? stackTrace, StackTrace? stackTrace,
]) { ]) {
showSnackBar( showSnackBar(

30
packages/paperless_api/.gitignore vendored Normal file
View File

@@ -0,0 +1,30 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.packages
build/

View File

@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849
channel: stable
project_type: package

View File

@@ -0,0 +1,3 @@
## 0.0.1
* TODO: Describe initial release.

View File

@@ -0,0 +1 @@
TODO: Add your license here.

View File

@@ -0,0 +1,39 @@
<!--
This README describes the package. If you publish this package to pub.dev,
this README's contents appear on the landing page for your package.
For information about how to write a good package README, see the guide for
[writing package pages](https://dart.dev/guides/libraries/writing-package-pages).
For general information about developing packages, see the Dart guide for
[creating packages](https://dart.dev/guides/libraries/create-library-packages)
and the Flutter guide for
[developing packages and plugins](https://flutter.dev/developing-packages).
-->
TODO: Put a short description of the package here that helps potential users
know whether this package might be useful for them.
## Features
TODO: List what your package can do. Maybe include images, gifs, or videos.
## Getting started
TODO: List prerequisites and provide or point to information on how to
start using the package.
## Usage
TODO: Include short and useful examples for package users. Add longer examples
to `/example` folder.
```dart
const like = 'sample';
```
## Additional information
TODO: Tell users more about the package: where to find more information, how to
contribute to the package, how to file issues, what response they can expect
from the package authors, and more.

View File

@@ -0,0 +1,4 @@
include: package:flutter_lints/flutter.yaml
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

View File

@@ -0,0 +1,4 @@
library paperless_api;
export 'src/models/models.dart';
export 'src/modules/modules.dart';

View File

@@ -0,0 +1,3 @@
import 'package:intl/intl.dart';
final DateFormat apiDateFormat = DateFormat('yyyy-MM-dd');

View File

@@ -1,18 +1,16 @@
import 'package:paperless_mobile/core/type/types.dart';
abstract class BulkAction { abstract class BulkAction {
final Iterable<int> documentIds; final Iterable<int> documentIds;
BulkAction(this.documentIds); BulkAction(this.documentIds);
JSON toJson(); Map<String, dynamic> toJson();
} }
class BulkDeleteAction extends BulkAction { class BulkDeleteAction extends BulkAction {
BulkDeleteAction(super.documents); BulkDeleteAction(super.documents);
@override @override
JSON toJson() { Map<String, dynamic> toJson() {
return { return {
'documents': documentIds.toList(), 'documents': documentIds.toList(),
'method': 'delete', 'method': 'delete',
@@ -39,7 +37,7 @@ class BulkModifyTagsAction extends BulkAction {
removeTags = tags; removeTags = tags;
@override @override
JSON toJson() { Map<String, dynamic> toJson() {
return { return {
'documents': documentIds.toList(), 'documents': documentIds.toList(),
'method': 'modify_tags', 'method': 'modify_tags',

Some files were not shown because too many files have changed in this diff Show More