feat: Renamed translation strings

This commit is contained in:
Anton Stubenbord
2023-02-16 20:55:10 +01:00
parent fb6f79f017
commit d1a49ac73d
80 changed files with 3281 additions and 3974 deletions
+2 -2
View File
@@ -121,7 +121,7 @@
// password: testPassword, // password: testPassword,
// )); // ));
// expect( // expect(
// find.textContaining(t.translations.loginPagePasswordValidatorMessageText), // find.textContaining(t.translations.passwordMustNotBeEmpty),
// findsOneWidget, // findsOneWidget,
// ); // );
// }); // });
@@ -169,7 +169,7 @@
// password: testPassword, // password: testPassword,
// )); // ));
// expect( // expect(
// find.textContaining(t.translations.loginPageUsernameValidatorMessageText), // find.textContaining(t.translations.usernameMustNotBeEmpty),
// findsOneWidget, // findsOneWidget,
// ); // );
// }); // });
@@ -6,8 +6,8 @@ String translateColorSchemeOption(
BuildContext context, ColorSchemeOption option) { BuildContext context, ColorSchemeOption option) {
switch (option) { switch (option) {
case ColorSchemeOption.classic: case ColorSchemeOption.classic:
return S.of(context).colorSchemeOptionClassic; return S.of(context).classic;
case ColorSchemeOption.dynamic: case ColorSchemeOption.dynamic:
return S.of(context).colorSchemeOptionDynamic; return S.of(context).dynamic;
} }
} }
@@ -5,72 +5,72 @@ import 'package:paperless_mobile/generated/l10n.dart';
String translateError(BuildContext context, ErrorCode code) { String translateError(BuildContext context, ErrorCode code) {
switch (code) { switch (code) {
case ErrorCode.unknown: case ErrorCode.unknown:
return S.of(context).errorMessageUnknonwnError; return S.of(context).anUnknownErrorOccurred;
case ErrorCode.authenticationFailed: case ErrorCode.authenticationFailed:
return S.of(context).errorMessageAuthenticationFailed; return S.of(context).authenticationFailedPleaseTryAgain;
case ErrorCode.notAuthenticated: case ErrorCode.notAuthenticated:
return S.of(context).errorMessageNotAuthenticated; return S.of(context).userIsNotAuthenticated;
case ErrorCode.documentUploadFailed: case ErrorCode.documentUploadFailed:
return S.of(context).errorMessageDocumentUploadFailed; return S.of(context).couldNotUploadDocument;
case ErrorCode.documentUpdateFailed: case ErrorCode.documentUpdateFailed:
return S.of(context).errorMessageDocumentUpdateFailed; return S.of(context).couldNotUpdateDocument;
case ErrorCode.documentLoadFailed: case ErrorCode.documentLoadFailed:
return S.of(context).errorMessageDocumentLoadFailed; return S.of(context).couldNotLoadDocuments;
case ErrorCode.documentDeleteFailed: case ErrorCode.documentDeleteFailed:
return S.of(context).errorMessageDocumentDeleteFailed; return S.of(context).couldNotDeleteDocument;
case ErrorCode.documentPreviewFailed: case ErrorCode.documentPreviewFailed:
return S.of(context).errorMessageDocumentPreviewFailed; return S.of(context).couldNotLoadDocumentPreview;
case ErrorCode.documentAsnQueryFailed: case ErrorCode.documentAsnQueryFailed:
return S.of(context).errorMessageDocumentAsnQueryFailed; return S.of(context).couldNotAssignArchiveSerialNumber;
case ErrorCode.tagCreateFailed: case ErrorCode.tagCreateFailed:
return S.of(context).errorMessageTagCreateFailed; return S.of(context).couldNotCreateTag;
case ErrorCode.tagLoadFailed: case ErrorCode.tagLoadFailed:
return S.of(context).errorMessageTagLoadFailed; return S.of(context).couldNotLoadTags;
case ErrorCode.documentTypeCreateFailed: case ErrorCode.documentTypeCreateFailed:
return S.of(context).errorMessageDocumentTypeCreateFailed; return S.of(context).couldNotCreateDocument;
case ErrorCode.documentTypeLoadFailed: case ErrorCode.documentTypeLoadFailed:
return S.of(context).errorMessageDocumentTypeLoadFailed; return S.of(context).couldNotLoadDocumentTypes;
case ErrorCode.correspondentCreateFailed: case ErrorCode.correspondentCreateFailed:
return S.of(context).errorMessageCorrespondentCreateFailed; return S.of(context).couldNotCreateCorrespondent;
case ErrorCode.correspondentLoadFailed: case ErrorCode.correspondentLoadFailed:
return S.of(context).errorMessageCorrespondentLoadFailed; return S.of(context).couldNotLoadCorrespondents;
case ErrorCode.scanRemoveFailed: case ErrorCode.scanRemoveFailed:
return S.of(context).errorMessageScanRemoveFailed; return S.of(context).anErrorOccurredRemovingTheScans;
case ErrorCode.invalidClientCertificateConfiguration: case ErrorCode.invalidClientCertificateConfiguration:
return S.of(context).errorMessageInvalidClientCertificateConfiguration; return S.of(context).invalidCertificateOrMissingPassphrase;
case ErrorCode.documentBulkActionFailed: case ErrorCode.documentBulkActionFailed:
return S.of(context).errorMessageBulkActionFailed; return S.of(context).couldNotBulkEditDocuments;
case ErrorCode.biometricsNotSupported: case ErrorCode.biometricsNotSupported:
return S.of(context).errorMessageBiotmetricsNotSupported; return S.of(context).biometricAuthenticationNotSupported;
case ErrorCode.biometricAuthenticationFailed: case ErrorCode.biometricAuthenticationFailed:
return S.of(context).errorMessageBiometricAuthenticationFailed; return S.of(context).biometricAuthenticationFailed;
case ErrorCode.deviceOffline: case ErrorCode.deviceOffline:
return S.of(context).errorMessageDeviceOffline; return S.of(context).youAreCurrentlyOffline;
case ErrorCode.serverUnreachable: case ErrorCode.serverUnreachable:
return S.of(context).errorMessageServerUnreachable; return S.of(context).couldNotReachYourPaperlessServer;
case ErrorCode.similarQueryError: case ErrorCode.similarQueryError:
return S.of(context).errorMessageSimilarQueryError; return S.of(context).couldNotLoadSimilarDocuments;
case ErrorCode.autocompleteQueryError: case ErrorCode.autocompleteQueryError:
return S.of(context).errorMessageAutocompleteQueryError; return S.of(context).anErrorOccurredWhileTryingToAutocompleteYourQuery;
case ErrorCode.storagePathLoadFailed: case ErrorCode.storagePathLoadFailed:
return S.of(context).errorMessageStoragePathLoadFailed; return S.of(context).couldNotLoadStoragePaths;
case ErrorCode.storagePathCreateFailed: case ErrorCode.storagePathCreateFailed:
return S.of(context).errorMessageStoragePathCreateFailed; return S.of(context).couldNotCreateStoragePath;
case ErrorCode.loadSavedViewsError: case ErrorCode.loadSavedViewsError:
return S.of(context).errorMessageLoadSavedViewsError; return S.of(context).couldNotLoadSavedViews;
case ErrorCode.createSavedViewError: case ErrorCode.createSavedViewError:
return S.of(context).errorMessageCreateSavedViewError; return S.of(context).couldNotCreateSavedView;
case ErrorCode.deleteSavedViewError: case ErrorCode.deleteSavedViewError:
return S.of(context).errorMessageDeleteSavedViewError; return S.of(context).couldNotDeleteSavedView;
case ErrorCode.requestTimedOut: case ErrorCode.requestTimedOut:
return S.of(context).errorMessageRequestTimedOut; return S.of(context).requestTimedOut;
case ErrorCode.unsupportedFileFormat: case ErrorCode.unsupportedFileFormat:
return S.of(context).errorMessageUnsupportedFileFormat; return S.of(context).fileFormatNotSupported;
case ErrorCode.missingClientCertificate: case ErrorCode.missingClientCertificate:
return S.of(context).errorMessageMissingClientCertificate; return S.of(context).aClientCertificateWasExpectedButNotSent;
case ErrorCode.suggestionsQueryError: case ErrorCode.suggestionsQueryError:
return S.of(context).errorMessageSuggestionsQueryError; return S.of(context).couldNotLoadSuggestions;
case ErrorCode.acknowledgeTasksError: case ErrorCode.acknowledgeTasksError:
return S.of(context).errorMessageAcknowledgeTasksError; return S.of(context).couldNotAcknowledgeTasks;
} }
} }
@@ -8,17 +8,17 @@ String translateMatchingAlgorithmDescription(
) { ) {
switch (algorithm) { switch (algorithm) {
case MatchingAlgorithm.anyWord: case MatchingAlgorithm.anyWord:
return S.of(context).matchingAlgorithmAnyDescription; return S.of(context).documentContainsAnyOfTheseWords;
case MatchingAlgorithm.allWords: case MatchingAlgorithm.allWords:
return S.of(context).matchingAlgorithmAllDescription; return S.of(context).documentContainsAllOfTheseWords;
case MatchingAlgorithm.exactMatch: case MatchingAlgorithm.exactMatch:
return S.of(context).matchingAlgorithmExactDescription; return S.of(context).documentContainsThisString;
case MatchingAlgorithm.regex: case MatchingAlgorithm.regex:
return S.of(context).matchingAlgorithmRegexDescription; return S.of(context).documentMatchesThisRegularExpression;
case MatchingAlgorithm.fuzzy: case MatchingAlgorithm.fuzzy:
return S.of(context).matchingAlgorithmFuzzyDescription; return S.of(context).documentContainsAWordSimilarToThisWord;
case MatchingAlgorithm.auto: case MatchingAlgorithm.auto:
return S.of(context).matchingAlgorithmAutoDescription; return S.of(context).learnMatchingAutomatically;
} }
} }
@@ -28,16 +28,16 @@ String translateMatchingAlgorithmName(
) { ) {
switch (algorithm) { switch (algorithm) {
case MatchingAlgorithm.anyWord: case MatchingAlgorithm.anyWord:
return S.of(context).matchingAlgorithmAnyName; return S.of(context).any;
case MatchingAlgorithm.allWords: case MatchingAlgorithm.allWords:
return S.of(context).matchingAlgorithmAllName; return S.of(context).all;
case MatchingAlgorithm.exactMatch: case MatchingAlgorithm.exactMatch:
return S.of(context).matchingAlgorithmExactName; return S.of(context).exact;
case MatchingAlgorithm.regex: case MatchingAlgorithm.regex:
return S.of(context).matchingAlgorithmRegexName; return S.of(context).regularExpression;
case MatchingAlgorithm.fuzzy: case MatchingAlgorithm.fuzzy:
return S.of(context).matchingAlgorithmFuzzyName; return S.of(context).fuzzy;
case MatchingAlgorithm.auto: case MatchingAlgorithm.auto:
return S.of(context).matchingAlgorithmAutoName; return S.of(context).auto;
} }
} }
@@ -5,19 +5,19 @@ import 'package:paperless_mobile/generated/l10n.dart';
String translateSortField(BuildContext context, SortField? sortField) { String translateSortField(BuildContext context, SortField? sortField) {
switch (sortField) { switch (sortField) {
case SortField.archiveSerialNumber: case SortField.archiveSerialNumber:
return S.of(context).documentArchiveSerialNumberPropertyShortLabel; return S.of(context).asn;
case SortField.correspondentName: case SortField.correspondentName:
return S.of(context).documentCorrespondentPropertyLabel; return S.of(context).correspondent;
case SortField.title: case SortField.title:
return S.of(context).documentTitlePropertyLabel; return S.of(context).title;
case SortField.documentType: case SortField.documentType:
return S.of(context).documentDocumentTypePropertyLabel; return S.of(context).documentType;
case SortField.created: case SortField.created:
return S.of(context).documentCreatedPropertyLabel; return S.of(context).createdAt;
case SortField.added: case SortField.added:
return S.of(context).documentAddedPropertyLabel; return S.of(context).addedAt;
case SortField.modified: case SortField.modified:
return S.of(context).documentModifiedPropertyLabel; return S.of(context).modifiedAt;
default: default:
return ''; return '';
} }
+4 -4
View File
@@ -74,7 +74,7 @@
// padding: EdgeInsets.zero, // padding: EdgeInsets.zero,
// child: ListTile( // child: ListTile(
// leading: const Icon(Icons.bug_report), // leading: const Icon(Icons.bug_report),
// title: Text(S.of(context).appDrawerReportBugLabel), // title: Text(S.of(context).reportABug),
// ), // ),
// ); // );
// } // }
@@ -85,7 +85,7 @@
// value: AppPopupMenuEntries.openSettings, // value: AppPopupMenuEntries.openSettings,
// child: ListTile( // child: ListTile(
// leading: const Icon(Icons.settings_outlined), // leading: const Icon(Icons.settings_outlined),
// title: Text(S.of(context).appDrawerSettingsLabel), // title: Text(S.of(context).settings),
// ), // ),
// ); // );
// } // }
@@ -96,7 +96,7 @@
// value: AppPopupMenuEntries.openAboutThisAppDialog, // value: AppPopupMenuEntries.openAboutThisAppDialog,
// child: ListTile( // child: ListTile(
// leading: const Icon(Icons.info_outline), // leading: const Icon(Icons.info_outline),
// title: Text(S.of(context).appDrawerAboutLabel), // title: Text(S.of(context).aboutThisApp),
// ), // ),
// ); // );
// } // }
@@ -146,7 +146,7 @@
// applicationName: 'Paperless Mobile', // applicationName: 'Paperless Mobile',
// applicationVersion: packageInfo.version + '+' + packageInfo.buildNumber, // applicationVersion: packageInfo.version + '+' + packageInfo.buildNumber,
// children: [ // children: [
// Text(S.of(context).aboutDialogDevelopedByText('Anton Stubenbord')), // Text(S.of(context).developedBy('Anton Stubenbord')),
// Link( // Link(
// uri: Uri.parse('https://github.com/astubenbord/paperless-mobile'), // uri: Uri.parse('https://github.com/astubenbord/paperless-mobile'),
// builder: (context, followLink) => GestureDetector( // builder: (context, followLink) => GestureDetector(
@@ -10,7 +10,7 @@ class DialogCancelButton extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return TextButton( return TextButton(
child: Text(S.of(context).genericActionCancelLabel), child: Text(S.of(context).cancel),
onPressed: onTap ?? () => Navigator.pop(context), onPressed: onTap ?? () => Navigator.pop(context),
); );
} }
@@ -47,7 +47,7 @@ class _ExtendedDateRangeDialogState extends State<ExtendedDateRangeDialog> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( return AlertDialog(
insetPadding: const EdgeInsets.all(24.0), insetPadding: const EdgeInsets.all(24.0),
title: Text(S.of(context).extendedDateRangeDialogTitle), title: Text(S.of(context).selectDateRange),
content: FormBuilder( content: FormBuilder(
key: _formKey, key: _formKey,
child: Column( child: Column(
@@ -56,7 +56,7 @@ class _ExtendedDateRangeDialogState extends State<ExtendedDateRangeDialog> {
children: [ children: [
_buildDateRangeQueryTypeSelection(), _buildDateRangeQueryTypeSelection(),
Text( Text(
S.of(context).extendedDateRangeDialogHintText, S.of(context).hintYouCanAlsoSpecifyRelativeValues,
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
).paddedOnly(top: 8, bottom: 16), ).paddedOnly(top: 8, bottom: 16),
Builder( Builder(
@@ -83,11 +83,11 @@ class _ExtendedDateRangeDialogState extends State<ExtendedDateRangeDialog> {
), ),
actions: [ actions: [
TextButton( TextButton(
child: Text(S.of(context).genericActionCancelLabel), child: Text(S.of(context).cancel),
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
), ),
TextButton( TextButton(
child: Text(S.of(context).genericActionSaveLabel), child: Text(S.of(context).save),
onPressed: () { onPressed: () {
_formKey.currentState?.save(); _formKey.currentState?.save();
if (_formKey.currentState?.validate() ?? false) { if (_formKey.currentState?.validate() ?? false) {
@@ -110,12 +110,12 @@ class _ExtendedDateRangeDialogState extends State<ExtendedDateRangeDialog> {
ButtonSegment( ButtonSegment(
value: DateRangeType.absolute, value: DateRangeType.absolute,
enabled: true, enabled: true,
label: Text(S.of(context).extendedDateRangeDialogAbsoluteLabel), label: Text(S.of(context).absolute),
), ),
ButtonSegment( ButtonSegment(
value: DateRangeType.relative, value: DateRangeType.relative,
enabled: true, enabled: true,
label: Text(S.of(context).extendedDateRangeDialogRelativeLabel), label: Text(S.of(context).relative),
), ),
], ],
selected: {_selectedDateRangeType}, selected: {_selectedDateRangeType},
@@ -133,7 +133,7 @@ class _ExtendedDateRangeDialogState extends State<ExtendedDateRangeDialog> {
: null, : null,
initialDate: _before?.subtract(const Duration(days: 1)), initialDate: _before?.subtract(const Duration(days: 1)),
decoration: InputDecoration( decoration: InputDecoration(
labelText: S.of(context).extendedDateRangePickerAfterLabel, labelText: S.of(context).after,
prefixIcon: const Icon(Icons.date_range), prefixIcon: const Icon(Icons.date_range),
suffixIcon: _after != null suffixIcon: _after != null
? IconButton( ? IconButton(
@@ -161,7 +161,7 @@ class _ExtendedDateRangeDialogState extends State<ExtendedDateRangeDialog> {
: null, : null,
inputType: InputType.date, inputType: InputType.date,
decoration: InputDecoration( decoration: InputDecoration(
labelText: S.of(context).extendedDateRangePickerBeforeLabel, labelText: S.of(context).before,
prefixIcon: const Icon(Icons.date_range), prefixIcon: const Icon(Icons.date_range),
suffixIcon: _before != null suffixIcon: _before != null
? IconButton( ? IconButton(
@@ -90,29 +90,21 @@ class _FormBuilderExtendedDateRangePickerState
return '${df.format(query.after!)} ${df.format(query.before!)}'; return '${df.format(query.after!)} ${df.format(query.before!)}';
} }
if (query.before != null) { if (query.before != null) {
return '${S.of(context).extendedDateRangePickerBeforeLabel} ${df.format(query.before!)}'; return '${S.of(context).before} ${df.format(query.before!)}';
} }
if (query.after != null) { if (query.after != null) {
return '${S.of(context).extendedDateRangePickerAfterLabel} ${df.format(query.after!)}'; return '${S.of(context).after} ${df.format(query.after!)}';
} }
} else if (query is RelativeDateRangeQuery) { } else if (query is RelativeDateRangeQuery) {
switch (query.unit) { switch (query.unit) {
case DateRangeUnit.day: case DateRangeUnit.day:
return S return S.of(context).lastNDays(query.offset);
.of(context)
.extendedDateRangePickerLastDaysLabel(query.offset);
case DateRangeUnit.week: case DateRangeUnit.week:
return S return S.of(context).lastNWeeks(query.offset);
.of(context)
.extendedDateRangePickerLastWeeksLabel(query.offset);
case DateRangeUnit.month: case DateRangeUnit.month:
return S return S.of(context).lastNMonths(query.offset);
.of(context)
.extendedDateRangePickerLastMonthsLabel(query.offset);
case DateRangeUnit.year: case DateRangeUnit.year:
return S return S.of(context).lastNYears(query.offset);
.of(context)
.extendedDateRangePickerLastYearsLabel(query.offset);
default: default:
} }
} }
@@ -46,14 +46,12 @@ class _FormBuilderRelativeDateRangePickerState
Row( Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(S.of(context).extendedDateRangeDialogRelativeLastLabel), Text(S.of(context).last),
SizedBox( SizedBox(
width: 80, width: 80,
child: TextFormField( child: TextFormField(
decoration: InputDecoration( decoration: InputDecoration(
labelText: S labelText: S.of(context).amount,
.of(context)
.extendedDateRangeDialogRelativeAmountLabel,
), ),
inputFormatters: [ inputFormatters: [
FilteringTextInputFormatter.digitsOnly, FilteringTextInputFormatter.digitsOnly,
@@ -92,9 +90,7 @@ class _FormBuilderRelativeDateRangePickerState
onChanged: (value) => onChanged: (value) =>
field.didChange(field.value!.copyWith(unit: value)), field.didChange(field.value!.copyWith(unit: value)),
decoration: InputDecoration( decoration: InputDecoration(
labelText: S labelText: S.of(context).timeUnit,
.of(context)
.extendedDateRangeDialogRelativeTimeUnitLabel,
), ),
), ),
), ),
@@ -117,13 +113,13 @@ class _FormBuilderRelativeDateRangePickerState
String _dateRangeUnitToLocalizedString(DateRangeUnit unit, int? count) { String _dateRangeUnitToLocalizedString(DateRangeUnit unit, int? count) {
switch (unit) { switch (unit) {
case DateRangeUnit.day: case DateRangeUnit.day:
return S.of(context).extendedDateRangePickerDayText(count ?? 1); return S.of(context).days(count ?? 1);
case DateRangeUnit.week: case DateRangeUnit.week:
return S.of(context).extendedDateRangePickerWeekText(count ?? 1); return S.of(context).weeks(count ?? 1);
case DateRangeUnit.month: case DateRangeUnit.month:
return S.of(context).extendedDateRangePickerMonthText(count ?? 1); return S.of(context).months(count ?? 1);
case DateRangeUnit.year: case DateRangeUnit.year:
return S.of(context).extendedDateRangePickerYearText(count ?? 1); return S.of(context).years(count ?? 1);
} }
} }
} }
@@ -49,19 +49,19 @@ class _RelativeDateRangePickerHelperState
List<_ExtendedDateRangeQueryOption> get _options => [ List<_ExtendedDateRangeQueryOption> get _options => [
_ExtendedDateRangeQueryOption( _ExtendedDateRangeQueryOption(
S.of(context).extendedDateRangePickerLastWeeksLabel(1), S.of(context).lastNWeeks(1),
const RelativeDateRangeQuery(1, DateRangeUnit.week), const RelativeDateRangeQuery(1, DateRangeUnit.week),
), ),
_ExtendedDateRangeQueryOption( _ExtendedDateRangeQueryOption(
S.of(context).extendedDateRangePickerLastMonthsLabel(1), S.of(context).lastNMonths(1),
const RelativeDateRangeQuery(1, DateRangeUnit.month), const RelativeDateRangeQuery(1, DateRangeUnit.month),
), ),
_ExtendedDateRangeQueryOption( _ExtendedDateRangeQueryOption(
S.of(context).extendedDateRangePickerLastMonthsLabel(3), S.of(context).lastNMonths(3),
const RelativeDateRangeQuery(3, DateRangeUnit.month), const RelativeDateRangeQuery(3, DateRangeUnit.month),
), ),
_ExtendedDateRangeQueryOption( _ExtendedDateRangeQueryOption(
S.of(context).extendedDateRangePickerLastYearsLabel(1), S.of(context).lastNYears(1),
const RelativeDateRangeQuery(1, DateRangeUnit.year), const RelativeDateRangeQuery(1, DateRangeUnit.year),
), ),
]; ];
+1 -1
View File
@@ -52,7 +52,7 @@ class HintCard extends StatelessWidget {
Align( Align(
alignment: Alignment.bottomRight, alignment: Alignment.bottomRight,
child: TextButton( child: TextButton(
child: Text(S.of(context).genericAcknowledgeLabel), child: Text(S.of(context).gotIt),
onPressed: onHintAcknowledged, onPressed: onHintAcknowledged,
), ),
) )
+1 -1
View File
@@ -21,7 +21,7 @@ class OfflineBanner extends StatelessWidget with PreferredSizeWidget {
), ),
), ),
Text( Text(
S.of(context).genericMessageOfflineText, S.of(context).youreOffline,
style: TextStyle( style: TextStyle(
color: Theme.of(context).colorScheme.onErrorContainer, color: Theme.of(context).colorScheme.onErrorContainer,
), ),
+1 -1
View File
@@ -15,7 +15,7 @@ class OfflineWidget extends StatelessWidget {
color: Theme.of(context).disabledColor, color: Theme.of(context).disabledColor,
size: (Theme.of(context).iconTheme.size ?? 24) * 3), size: (Theme.of(context).iconTheme.size ?? 24) * 3),
Text( Text(
S.of(context).offlineWidgetText, S.of(context).anInternetConnectionCouldNotBeEstablished,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
], ],
+4 -4
View File
@@ -31,14 +31,14 @@ class AppDrawer extends StatelessWidget {
const Divider(), const Divider(),
ListTile( ListTile(
dense: true, dense: true,
title: Text(S.of(context).appDrawerAboutLabel), title: Text(S.of(context).aboutThisApp),
leading: const Icon(Icons.info_outline), leading: const Icon(Icons.info_outline),
onTap: () => _showAboutDialog(context), onTap: () => _showAboutDialog(context),
), ),
ListTile( ListTile(
dense: true, dense: true,
leading: const Icon(Icons.bug_report_outlined), leading: const Icon(Icons.bug_report_outlined),
title: Text(S.of(context).appDrawerReportBugLabel), title: Text(S.of(context).reportABug),
onTap: () { onTap: () {
launchUrlString( launchUrlString(
'https://github.com/astubenbord/paperless-mobile/issues/new'); 'https://github.com/astubenbord/paperless-mobile/issues/new');
@@ -48,7 +48,7 @@ class AppDrawer extends StatelessWidget {
dense: true, dense: true,
leading: const Icon(Icons.settings_outlined), leading: const Icon(Icons.settings_outlined),
title: Text( title: Text(
S.of(context).appDrawerSettingsLabel, S.of(context).settings,
), ),
onTap: () => Navigator.of(context).push( onTap: () => Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
@@ -74,7 +74,7 @@ class AppDrawer extends StatelessWidget {
applicationName: 'Paperless Mobile', applicationName: 'Paperless Mobile',
applicationVersion: packageInfo.version + '+' + packageInfo.buildNumber, applicationVersion: packageInfo.version + '+' + packageInfo.buildNumber,
children: [ children: [
Text(S.of(context).aboutDialogDevelopedByText('Anton Stubenbord')), Text(S.of(context).developedBy('Anton Stubenbord')),
Link( Link(
uri: Uri.parse('https://github.com/astubenbord/paperless-mobile'), uri: Uri.parse('https://github.com/astubenbord/paperless-mobile'),
builder: (context, followLink) => GestureDetector( builder: (context, followLink) => GestureDetector(
@@ -26,8 +26,8 @@ class _ApplicationIntroSlideshowState extends State<ApplicationIntroSlideshow> {
child: IntroductionScreen( child: IntroductionScreen(
globalBackgroundColor: Theme.of(context).canvasColor, globalBackgroundColor: Theme.of(context).canvasColor,
showDoneButton: true, showDoneButton: true,
next: Text(S.of(context).onboardingNextButtonLabel), next: Text(S.of(context).next),
done: Text(S.of(context).onboardingDoneButtonLabel), done: Text(S.of(context).done),
onDone: () => Navigator.pop(context), onDone: () => Navigator.pop(context),
dotsDecorator: DotsDecorator( dotsDecorator: DotsDecorator(
color: Theme.of(context).colorScheme.onBackground, color: Theme.of(context).colorScheme.onBackground,
@@ -102,7 +102,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
tabs: [ tabs: [
Tab( Tab(
child: Text( child: Text(
S.of(context).documentDetailsPageTabOverviewLabel, S.of(context).overview,
style: TextStyle( style: TextStyle(
color: Theme.of(context) color: Theme.of(context)
.colorScheme .colorScheme
@@ -112,7 +112,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
), ),
Tab( Tab(
child: Text( child: Text(
S.of(context).documentDetailsPageTabContentLabel, S.of(context).content,
style: TextStyle( style: TextStyle(
color: Theme.of(context) color: Theme.of(context)
.colorScheme .colorScheme
@@ -122,7 +122,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
), ),
Tab( Tab(
child: Text( child: Text(
S.of(context).documentDetailsPageTabMetaDataLabel, S.of(context).metaData,
style: TextStyle( style: TextStyle(
color: Theme.of(context) color: Theme.of(context)
.colorScheme .colorScheme
@@ -132,9 +132,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
), ),
Tab( Tab(
child: Text( child: Text(
S S.of(context).similarDocuments,
.of(context)
.documentDetailsPageTabSimilarDocumentsLabel,
style: TextStyle( style: TextStyle(
color: Theme.of(context) color: Theme.of(context)
.colorScheme .colorScheme
@@ -200,7 +198,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
position: b.BadgePosition.topEnd(top: -12, end: -6), position: b.BadgePosition.topEnd(top: -12, end: -6),
showBadge: _filteredSuggestions.hasSuggestions, showBadge: _filteredSuggestions.hasSuggestions,
child: Tooltip( child: Tooltip(
message: S.of(context).documentDetailsPageEditTooltip, message: S.of(context).editDocumentTooltip,
preferBelow: false, preferBelow: false,
verticalOffset: 40, verticalOffset: 40,
child: FloatingActionButton( child: FloatingActionButton(
@@ -233,14 +231,14 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
IconButton( IconButton(
tooltip: S.of(context).documentDetailsPageDeleteTooltip, tooltip: S.of(context).deleteDocumentTooltip,
icon: const Icon(Icons.delete), icon: const Icon(Icons.delete),
onPressed: widget.allowEdit && isConnected onPressed: widget.allowEdit && isConnected
? () => _onDelete(state.document) ? () => _onDelete(state.document)
: null, : null,
).paddedSymmetrically(horizontal: 4), ).paddedSymmetrically(horizontal: 4),
Tooltip( Tooltip(
message: S.of(context).documentDetailsPageDownloadTooltip, message: S.of(context).downloadDocumentTooltip,
child: DocumentDownloadButton( child: DocumentDownloadButton(
document: state.document, document: state.document,
enabled: isConnected, enabled: isConnected,
@@ -248,20 +246,18 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
), ),
), ),
IconButton( IconButton(
tooltip: S.of(context).documentDetailsPagePreviewTooltip, tooltip: S.of(context).previewTooltip,
icon: const Icon(Icons.visibility), icon: const Icon(Icons.visibility),
onPressed: onPressed:
isConnected ? () => _onOpen(state.document) : null, isConnected ? () => _onOpen(state.document) : null,
).paddedOnly(right: 4.0), ).paddedOnly(right: 4.0),
IconButton( IconButton(
tooltip: S tooltip: S.of(context).openInSystemViewer,
.of(context)
.documentDetailsPageOpenInSystemViewerTooltip,
icon: const Icon(Icons.open_in_new), icon: const Icon(Icons.open_in_new),
onPressed: isConnected ? _onOpenFileInSystemViewer : null, onPressed: isConnected ? _onOpenFileInSystemViewer : null,
).paddedOnly(right: 4.0), ).paddedOnly(right: 4.0),
IconButton( IconButton(
tooltip: S.of(context).documentDetailsPageShareTooltip, tooltip: S.of(context).shareTooltip,
icon: const Icon(Icons.share), icon: const Icon(Icons.share),
onPressed: isConnected onPressed: isConnected
? () => ? () =>
@@ -326,15 +322,13 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
await context.read<DocumentDetailsCubit>().openDocumentInSystemViewer(); await context.read<DocumentDetailsCubit>().openDocumentInSystemViewer();
if (status == ResultType.done) return; if (status == ResultType.done) return;
if (status == ResultType.noAppToOpen) { if (status == ResultType.noAppToOpen) {
showGenericError(context, showGenericError(context, S.of(context).noAppToDisplayPDFFilesFound);
S.of(context).documentDetailsPageNoPdfViewerFoundErrorMessage);
} }
if (status == ResultType.fileNotFound) { if (status == ResultType.fileNotFound) {
showGenericError(context, translateError(context, ErrorCode.unknown)); showGenericError(context, translateError(context, ErrorCode.unknown));
} }
if (status == ResultType.permissionDenied) { if (status == ResultType.permissionDenied) {
showGenericError(context, showGenericError(context, S.of(context).couldNotOpenFilePermissionDenied);
S.of(context).documentDetailsPageOpenPdfPermissionDeniedErrorMessage);
} }
} }
@@ -348,7 +342,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
if (delete) { if (delete) {
try { try {
await context.read<DocumentDetailsCubit>().delete(document); await context.read<DocumentDetailsCubit>().delete(document);
showSnackBar(context, S.of(context).documentDeleteSuccessMessage); showSnackBar(context, S.of(context).documentSuccessfullyDeleted);
} on PaperlessServerException catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} finally { } finally {
@@ -38,8 +38,7 @@ class DocumentContentWidget extends StatelessWidget {
Align( Align(
alignment: Alignment.bottomCenter, alignment: Alignment.bottomCenter,
child: TextButton( child: TextButton(
child: child: Text(S.of(context).loadFullContent),
Text(S.of(context).documentDetailsPageLoadFullContentLabel),
onPressed: () { onPressed: () {
context.read<DocumentDetailsCubit>().loadFullContent(); context.read<DocumentDetailsCubit>().loadFullContent();
}, },
@@ -53,15 +53,15 @@ class _DocumentDownloadButtonState extends State<DocumentDownloadButton> {
final downloadOriginal = await showDialog<bool>( final downloadOriginal = await showDialog<bool>(
context: context, context: context,
builder: (context) => RadioSettingsDialog( builder: (context) => RadioSettingsDialog(
titleText: S.of(context).documentDownloadDialogChooseFiletype, titleText: S.of(context).chooseFiletype,
options: [ options: [
RadioOption( RadioOption(
value: true, value: true,
label: S.of(context).documentDownloadDialogOriginalOption + label: S.of(context).original +
" (${meta.originalMimeType.split("/").last})"), " (${meta.originalMimeType.split("/").last})"),
RadioOption( RadioOption(
value: false, value: false,
label: S.of(context).documentDownloadDialogArchivedOption, label: S.of(context).archivedPdf,
), ),
], ],
initialValue: false, initialValue: false,
@@ -91,7 +91,7 @@ class _DocumentDownloadButtonState extends State<DocumentDownloadButton> {
createdFile.createSync(recursive: true); createdFile.createSync(recursive: true);
createdFile.writeAsBytesSync(bytes); createdFile.writeAsBytesSync(bytes);
debugPrint("Downloaded file to $filePath"); debugPrint("Downloaded file to $filePath");
showSnackBar(context, S.of(context).documentDownloadSuccessMessage); showSnackBar(context, S.of(context).documentSuccessfullyDownloaded);
} on PaperlessServerException catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} catch (error) { } catch (error) {
@@ -44,48 +44,39 @@ class DocumentMetaDataWidget extends StatelessWidget {
), ),
children: [ children: [
DetailsItem( DetailsItem(
label: S label: S.of(context).archiveSerialNumber,
.of(context)
.documentArchiveSerialNumberPropertyLongLabel,
content: document.archiveSerialNumber != null content: document.archiveSerialNumber != null
? Text(document.archiveSerialNumber.toString()) ? Text(document.archiveSerialNumber.toString())
: TextButton.icon( : TextButton.icon(
icon: const Icon(Icons.archive_outlined), icon: const Icon(Icons.archive_outlined),
label: Text(S label: Text(S.of(context).AssignAsn),
.of(context)
.documentDetailsPageAssignAsnButtonLabel),
onPressed: connectivity.isConnected onPressed: connectivity.isConnected
? () => _assignAsn(context) ? () => _assignAsn(context)
: null, : null,
), ),
).paddedOnly(bottom: itemSpacing), ).paddedOnly(bottom: itemSpacing),
DetailsItem.text(DateFormat().format(document.modified), DetailsItem.text(DateFormat().format(document.modified),
label: S.of(context).documentModifiedPropertyLabel, label: S.of(context).modifiedAt, context: context)
context: context)
.paddedOnly(bottom: itemSpacing), .paddedOnly(bottom: itemSpacing),
DetailsItem.text(DateFormat().format(document.added), DetailsItem.text(DateFormat().format(document.added),
label: S.of(context).documentAddedPropertyLabel, label: S.of(context).addedAt, context: context)
context: context)
.paddedOnly(bottom: itemSpacing), .paddedOnly(bottom: itemSpacing),
DetailsItem.text( DetailsItem.text(
meta.mediaFilename, meta.mediaFilename,
context: context, context: context,
label: label: S.of(context).mediaFilename,
S.of(context).documentMetaDataMediaFilenamePropertyLabel,
).paddedOnly(bottom: itemSpacing), ).paddedOnly(bottom: itemSpacing),
DetailsItem.text( DetailsItem.text(
meta.originalChecksum, meta.originalChecksum,
context: context, context: context,
label: S.of(context).documentMetaDataChecksumLabel, label: S.of(context).originalMD5Checksum,
).paddedOnly(bottom: itemSpacing), ).paddedOnly(bottom: itemSpacing),
DetailsItem.text(formatBytes(meta.originalSize, 2), DetailsItem.text(formatBytes(meta.originalSize, 2),
label: label: S.of(context).originalFileSize, context: context)
S.of(context).documentMetaDataOriginalFileSizeLabel,
context: context)
.paddedOnly(bottom: itemSpacing), .paddedOnly(bottom: itemSpacing),
DetailsItem.text( DetailsItem.text(
meta.originalMimeType, meta.originalMimeType,
label: S.of(context).documentMetaDataOriginalMimeTypeLabel, label: S.of(context).originalMIMEType,
context: context, context: context,
).paddedOnly(bottom: itemSpacing), ).paddedOnly(bottom: itemSpacing),
], ],
@@ -29,7 +29,7 @@ class DocumentOverviewWidget extends StatelessWidget {
), ),
children: [ children: [
DetailsItem( DetailsItem(
label: S.of(context).documentTitlePropertyLabel, label: S.of(context).title,
content: HighlightedText( content: HighlightedText(
text: document.title, text: document.title,
highlights: queryString?.split(" ") ?? [], highlights: queryString?.split(" ") ?? [],
@@ -39,12 +39,12 @@ class DocumentOverviewWidget extends StatelessWidget {
DetailsItem.text( DetailsItem.text(
DateFormat.yMMMMd().format(document.created), DateFormat.yMMMMd().format(document.created),
context: context, context: context,
label: S.of(context).documentCreatedPropertyLabel, label: S.of(context).createdAt,
).paddedOnly(bottom: itemSpacing), ).paddedOnly(bottom: itemSpacing),
Visibility( Visibility(
visible: document.documentType != null, visible: document.documentType != null,
child: DetailsItem( child: DetailsItem(
label: S.of(context).documentDocumentTypePropertyLabel, label: S.of(context).documentType,
content: LabelText<DocumentType>( content: LabelText<DocumentType>(
style: Theme.of(context).textTheme.bodyLarge, style: Theme.of(context).textTheme.bodyLarge,
id: document.documentType, id: document.documentType,
@@ -54,7 +54,7 @@ class DocumentOverviewWidget extends StatelessWidget {
Visibility( Visibility(
visible: document.correspondent != null, visible: document.correspondent != null,
child: DetailsItem( child: DetailsItem(
label: S.of(context).documentCorrespondentPropertyLabel, label: S.of(context).correspondent,
content: LabelText<Correspondent>( content: LabelText<Correspondent>(
style: Theme.of(context).textTheme.bodyLarge, style: Theme.of(context).textTheme.bodyLarge,
id: document.correspondent, id: document.correspondent,
@@ -64,7 +64,7 @@ class DocumentOverviewWidget extends StatelessWidget {
Visibility( Visibility(
visible: document.storagePath != null, visible: document.storagePath != null,
child: DetailsItem( child: DetailsItem(
label: S.of(context).documentStoragePathPropertyLabel, label: S.of(context).storagePath,
content: StoragePathWidget( content: StoragePathWidget(
pathId: document.storagePath, pathId: document.storagePath,
), ),
@@ -73,7 +73,7 @@ class DocumentOverviewWidget extends StatelessWidget {
Visibility( Visibility(
visible: document.tags.isNotEmpty, visible: document.tags.isNotEmpty,
child: DetailsItem( child: DetailsItem(
label: S.of(context).documentTagsPropertyLabel, label: S.of(context).tags,
content: Padding( content: Padding(
padding: const EdgeInsets.only(top: 8.0), padding: const EdgeInsets.only(top: 8.0),
child: TagsWidget( child: TagsWidget(
@@ -59,10 +59,10 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
floatingActionButton: FloatingActionButton.extended( floatingActionButton: FloatingActionButton.extended(
onPressed: () => _onSubmit(state.document), onPressed: () => _onSubmit(state.document),
icon: const Icon(Icons.save), icon: const Icon(Icons.save),
label: Text(S.of(context).genericActionUpdateLabel), label: Text(S.of(context).saveChanges),
), ),
appBar: AppBar( appBar: AppBar(
title: Text(S.of(context).documentEditPageTitle), title: Text(S.of(context).editDocument),
bottom: _isSubmitLoading bottom: _isSubmitLoading
? const PreferredSize( ? const PreferredSize(
preferredSize: Size.fromHeight(4), preferredSize: Size.fromHeight(4),
@@ -159,7 +159,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
create: (context) => context.read<LabelRepository<StoragePath>>(), create: (context) => context.read<LabelRepository<StoragePath>>(),
child: AddStoragePathPage(initalValue: initialValue), child: AddStoragePathPage(initalValue: initialValue),
), ),
textFieldLabel: S.of(context).documentStoragePathPropertyLabel, textFieldLabel: S.of(context).storagePath,
labelOptions: options, labelOptions: options,
initialValue: IdQueryParameter.fromId(initialId), initialValue: IdQueryParameter.fromId(initialId),
name: fkStoragePath, name: fkStoragePath,
@@ -180,7 +180,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
create: (context) => context.read<LabelRepository<Correspondent>>(), create: (context) => context.read<LabelRepository<Correspondent>>(),
child: AddCorrespondentPage(initialName: initialValue), child: AddCorrespondentPage(initialName: initialValue),
), ),
textFieldLabel: S.of(context).documentCorrespondentPropertyLabel, textFieldLabel: S.of(context).correspondent,
labelOptions: options, labelOptions: options,
initialValue: IdQueryParameter.fromId(initialId), initialValue: IdQueryParameter.fromId(initialId),
name: fkCorrespondent, name: fkCorrespondent,
@@ -214,7 +214,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
initialName: currentInput, initialName: currentInput,
), ),
), ),
textFieldLabel: S.of(context).documentDocumentTypePropertyLabel, textFieldLabel: S.of(context).documentType,
initialValue: IdQueryParameter.fromId(initialId), initialValue: IdQueryParameter.fromId(initialId),
labelOptions: options, labelOptions: options,
name: fkDocumentType, name: fkDocumentType,
@@ -249,7 +249,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
}); });
try { try {
await context.read<DocumentEditCubit>().updateDocument(mergedDocument); await context.read<DocumentEditCubit>().updateDocument(mergedDocument);
showSnackBar(context, S.of(context).documentUpdateSuccessMessage); showSnackBar(context, S.of(context).documentSuccessfullyUpdated);
} on PaperlessServerException catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
} finally { } finally {
@@ -266,7 +266,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
name: fkTitle, name: fkTitle,
validator: FormBuilderValidators.required(), validator: FormBuilderValidators.required(),
decoration: InputDecoration( decoration: InputDecoration(
label: Text(S.of(context).documentTitlePropertyLabel), label: Text(S.of(context).title),
), ),
initialValue: initialTitle, initialValue: initialTitle,
); );
@@ -281,7 +281,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
name: fkCreatedDate, name: fkCreatedDate,
decoration: InputDecoration( decoration: InputDecoration(
prefixIcon: const Icon(Icons.calendar_month_outlined), prefixIcon: const Icon(Icons.calendar_month_outlined),
label: Text(S.of(context).documentCreatedPropertyLabel), label: Text(S.of(context).createdAt),
), ),
initialValue: initialCreatedAtDate, initialValue: initialCreatedAtDate,
format: DateFormat.yMMMMd(), format: DateFormat.yMMMMd(),
@@ -311,7 +311,7 @@ class _DocumentEditPageState extends State<DocumentEditPage> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
S.of(context).documentEditPageSuggestionsLabel, S.of(context).suggestions,
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
), ),
SizedBox( SizedBox(
@@ -72,7 +72,7 @@ class _ScannerPageState extends State<ScannerPage>
state.isEmpty ? const NeverScrollableScrollPhysics() : null, state.isEmpty ? const NeverScrollableScrollPhysics() : null,
slivers: [ slivers: [
SearchAppBar( SearchAppBar(
hintText: S.of(context).documentSearchSearchDocuments, hintText: S.of(context).searchDocuments,
onOpenSearch: showDocumentSearchPage, onOpenSearch: showDocumentSearchPage,
bottom: PreferredSize( bottom: PreferredSize(
child: _buildActions(connectedState.isConnected), child: _buildActions(connectedState.isConnected),
@@ -97,7 +97,7 @@ class _ScannerPageState extends State<ScannerPage>
floatHeaderSlivers: false, floatHeaderSlivers: false,
headerSliverBuilder: (context, innerBoxIsScrolled) => [ headerSliverBuilder: (context, innerBoxIsScrolled) => [
SearchAppBar( SearchAppBar(
hintText: S.of(context).documentSearchSearchDocuments, hintText: S.of(context).searchDocuments,
onOpenSearch: showDocumentSearchPage, onOpenSearch: showDocumentSearchPage,
bottom: PreferredSize( bottom: PreferredSize(
child: _buildActions(connectedState.isConnected), child: _buildActions(connectedState.isConnected),
@@ -134,7 +134,7 @@ class _ScannerPageState extends State<ScannerPage>
BlocBuilder<DocumentScannerCubit, List<File>>( BlocBuilder<DocumentScannerCubit, List<File>>(
builder: (context, state) { builder: (context, state) {
return TextButton.icon( return TextButton.icon(
label: Text(S.of(context).scannerPagePreviewLabel), label: Text(S.of(context).previewScan),
onPressed: state.isNotEmpty onPressed: state.isNotEmpty
? () => Navigator.of(context).push( ? () => Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
@@ -154,7 +154,7 @@ class _ScannerPageState extends State<ScannerPage>
BlocBuilder<DocumentScannerCubit, List<File>>( BlocBuilder<DocumentScannerCubit, List<File>>(
builder: (context, state) { builder: (context, state) {
return TextButton.icon( return TextButton.icon(
label: Text(S.of(context).scannerPageClearAllLabel), label: Text(S.of(context).clearAll),
onPressed: state.isEmpty ? null : () => _reset(context), onPressed: state.isEmpty ? null : () => _reset(context),
icon: const Icon(Icons.delete_sweep_outlined), icon: const Icon(Icons.delete_sweep_outlined),
); );
@@ -163,7 +163,7 @@ class _ScannerPageState extends State<ScannerPage>
BlocBuilder<DocumentScannerCubit, List<File>>( BlocBuilder<DocumentScannerCubit, List<File>>(
builder: (context, state) { builder: (context, state) {
return TextButton.icon( return TextButton.icon(
label: Text(S.of(context).scannerPageUploadLabel), label: Text(S.of(context).upload),
onPressed: state.isEmpty || !isConnected onPressed: state.isEmpty || !isConnected
? null ? null
: () => _onPrepareDocumentUpload(context), : () => _onPrepareDocumentUpload(context),
@@ -176,55 +176,6 @@ class _ScannerPageState extends State<ScannerPage>
); );
} }
AppBar _buildAppBar(BuildContext context, bool isConnected) {
return AppBar(
title: Text(S.of(context).documentScannerPageTitle),
bottom: !isConnected ? const OfflineBanner() : null,
actions: [
BlocBuilder<DocumentScannerCubit, List<File>>(
builder: (context, state) {
return IconButton(
onPressed: state.isNotEmpty
? () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DocumentView(
documentBytes: _assembleFileBytes(
state,
forcePdf: true,
).then((file) => file.bytes),
),
),
)
: null,
icon: const Icon(Icons.visibility),
tooltip: S.of(context).documentScannerPageResetButtonTooltipText,
);
},
),
BlocBuilder<DocumentScannerCubit, List<File>>(
builder: (context, state) {
return IconButton(
onPressed: state.isEmpty ? null : () => _reset(context),
icon: const Icon(Icons.delete_sweep),
tooltip: S.of(context).documentScannerPageResetButtonTooltipText,
);
},
),
BlocBuilder<DocumentScannerCubit, List<File>>(
builder: (context, state) {
return IconButton(
onPressed: state.isEmpty || !isConnected
? null
: () => _onPrepareDocumentUpload(context),
icon: const Icon(Icons.done),
tooltip: S.of(context).documentScannerPageUploadButtonTooltip,
);
},
),
],
);
}
void _openDocumentScanner(BuildContext context) async { void _openDocumentScanner(BuildContext context) async {
final isGranted = await askForPermission(Permission.camera); final isGranted = await askForPermission(Permission.camera);
if (!isGranted) { if (!isGranted) {
@@ -296,19 +247,16 @@ class _ScannerPageState extends State<ScannerPage>
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text( Text(
S.of(context).documentScannerPageEmptyStateText, S.of(context).noDocumentsScannedYet,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
TextButton( TextButton(
child: child: Text(S.of(context).scanADocument),
Text(S.of(context).documentScannerPageAddScanButtonLabel),
onPressed: () => _openDocumentScanner(context), onPressed: () => _openDocumentScanner(context),
), ),
Text(S.of(context).documentScannerPageOrText), Text(S.of(context).or),
TextButton( TextButton(
child: Text(S child: Text(S.of(context).uploadADocumentFromThisDevice),
.of(context)
.documentScannerPageUploadFromThisDeviceButtonLabel),
onPressed: isConnected ? _onUploadFromFilesystem : null, onPressed: isConnected ? _onUploadFromFilesystem : null,
), ),
], ],
@@ -112,7 +112,7 @@ class _ScannedImageItemState extends State<ScannedImageItem> {
builder: (context) => Scaffold( builder: (context) => Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text( title: Text(
"${S.of(context).scannerPageImagePreviewTitle} ${widget.index + 1}/${widget.totalNumberOfFiles}"), "${S.of(context).scan} ${widget.index + 1}/${widget.totalNumberOfFiles}"),
), ),
body: PhotoView(imageProvider: FileImage(widget.file)), body: PhotoView(imageProvider: FileImage(widget.file)),
), ),
@@ -60,7 +60,7 @@ class _DocumentSearchPageState extends State<DocumentSearchPage> {
hintStyle: theme.textTheme.bodyLarge?.apply( hintStyle: theme.textTheme.bodyLarge?.apply(
color: theme.colorScheme.onSurfaceVariant, color: theme.colorScheme.onSurfaceVariant,
), ),
hintText: S.of(context).documentSearchSearchDocuments, hintText: S.of(context).searchDocuments,
border: InputBorder.none, border: InputBorder.none,
), ),
controller: _queryController, controller: _queryController,
@@ -181,7 +181,7 @@ class _DocumentSearchPageState extends State<DocumentSearchPage> {
Widget _buildResultsView(DocumentSearchState state) { Widget _buildResultsView(DocumentSearchState state) {
final header = Text( final header = Text(
S.of(context).documentSearchResults, S.of(context).results,
style: Theme.of(context).textTheme.labelSmall, style: Theme.of(context).textTheme.labelSmall,
).padded(); ).padded();
return CustomScrollView( return CustomScrollView(
@@ -190,7 +190,7 @@ class _DocumentSearchPageState extends State<DocumentSearchPage> {
if (state.hasLoaded && !state.isLoading && state.documents.isEmpty) if (state.hasLoaded && !state.isLoading && state.documents.isEmpty)
SliverToBoxAdapter( SliverToBoxAdapter(
child: Center( child: Center(
child: Text(S.of(context).documentSearchNoMatchesFound), child: Text(S.of(context).noMatchesFound),
), ),
) )
else else
@@ -10,11 +10,11 @@ class RemoveHistoryEntryDialog extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( return AlertDialog(
title: Text(entry), title: Text(entry),
content: Text(S.of(context).documentSearchRemoveHistoryEntryText), content: Text(S.of(context).removeQueryFromSearchHistory),
actions: [ actions: [
const DialogCancelButton(), const DialogCancelButton(),
TextButton( TextButton(
child: Text(S.of(context).genericActionRemoveLabel), child: Text(S.of(context).remove),
onPressed: () { onPressed: () {
Navigator.pop(context, true); Navigator.pop(context, true);
}, },
@@ -62,7 +62,7 @@ class _DocumentUploadPreparationPageState
return Scaffold( return Scaffold(
resizeToAvoidBottomInset: true, resizeToAvoidBottomInset: true,
appBar: AppBar( appBar: AppBar(
title: Text(S.of(context).documentsUploadPageTitle), title: Text(S.of(context).prepareDocument),
bottom: _isUploadLoading bottom: _isUploadLoading
? const PreferredSize( ? const PreferredSize(
child: LinearProgressIndicator(), child: LinearProgressIndicator(),
@@ -73,7 +73,7 @@ class _DocumentUploadPreparationPageState
visible: MediaQuery.of(context).viewInsets.bottom == 0, visible: MediaQuery.of(context).viewInsets.bottom == 0,
child: FloatingActionButton.extended( child: FloatingActionButton.extended(
onPressed: _onSubmit, onPressed: _onSubmit,
label: Text(S.of(context).genericActionUploadLabel), label: Text(S.of(context).upload),
icon: const Icon(Icons.upload), icon: const Icon(Icons.upload),
), ),
), ),
@@ -91,7 +91,7 @@ class _DocumentUploadPreparationPageState
widget.title ?? "scan_${fileNameDateFormat.format(_now)}", widget.title ?? "scan_${fileNameDateFormat.format(_now)}",
validator: FormBuilderValidators.required(), validator: FormBuilderValidators.required(),
decoration: InputDecoration( decoration: InputDecoration(
labelText: S.of(context).documentTitlePropertyLabel, labelText: S.of(context).title,
suffixIcon: IconButton( suffixIcon: IconButton(
icon: const Icon(Icons.close), icon: const Icon(Icons.close),
onPressed: () { onPressed: () {
@@ -121,7 +121,7 @@ class _DocumentUploadPreparationPageState
enabled: !_syncTitleAndFilename, enabled: !_syncTitleAndFilename,
name: fkFileName, name: fkFileName,
decoration: InputDecoration( decoration: InputDecoration(
labelText: S.of(context).documentUploadFileNameLabel, labelText: S.of(context).fileName,
suffixText: widget.fileExtension, suffixText: widget.fileExtension,
suffixIcon: IconButton( suffixIcon: IconButton(
icon: const Icon(Icons.clear), icon: const Icon(Icons.clear),
@@ -151,9 +151,7 @@ class _DocumentUploadPreparationPageState
} }
}, },
title: Text( title: Text(
S S.of(context).synchronizeTitleAndFilename,
.of(context)
.documentUploadPageSynchronizeTitleAndFilenameLabel,
), ),
), ),
// Created at // Created at
@@ -168,8 +166,7 @@ class _DocumentUploadPreparationPageState
}, },
decoration: InputDecoration( decoration: InputDecoration(
prefixIcon: const Icon(Icons.calendar_month_outlined), prefixIcon: const Icon(Icons.calendar_month_outlined),
labelText: labelText: S.of(context).createdAt + " *",
S.of(context).documentCreatedPropertyLabel + " *",
suffixIcon: _showDatePickerDeleteIcon suffixIcon: _showDatePickerDeleteIcon
? IconButton( ? IconButton(
icon: const Icon(Icons.close), icon: const Icon(Icons.close),
@@ -192,8 +189,7 @@ class _DocumentUploadPreparationPageState
context.read<LabelRepository<Correspondent>>(), context.read<LabelRepository<Correspondent>>(),
child: AddCorrespondentPage(initialName: initialName), child: AddCorrespondentPage(initialName: initialName),
), ),
textFieldLabel: textFieldLabel: S.of(context).correspondent + " *",
S.of(context).documentCorrespondentPropertyLabel + " *",
name: DocumentModel.correspondentKey, name: DocumentModel.correspondentKey,
labelOptions: state.correspondents, labelOptions: state.correspondents,
prefixIcon: const Icon(Icons.person_outline), prefixIcon: const Icon(Icons.person_outline),
@@ -208,8 +204,7 @@ class _DocumentUploadPreparationPageState
context.read<LabelRepository<DocumentType>>(), context.read<LabelRepository<DocumentType>>(),
child: AddDocumentTypePage(initialName: initialName), child: AddDocumentTypePage(initialName: initialName),
), ),
textFieldLabel: textFieldLabel: S.of(context).documentType + " *",
S.of(context).documentDocumentTypePropertyLabel + " *",
name: DocumentModel.documentTypeKey, name: DocumentModel.documentTypeKey,
labelOptions: state.documentTypes, labelOptions: state.documentTypes,
prefixIcon: const Icon(Icons.description_outlined), prefixIcon: const Icon(Icons.description_outlined),
@@ -223,10 +218,7 @@ class _DocumentUploadPreparationPageState
//Label: "Tags" + " *", //Label: "Tags" + " *",
), ),
Text( Text(
"* " + "* " + S.of(context).uploadInferValuesHint,
S
.of(context)
.uploadPageAutomaticallInferredFieldsHintText,
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
), ),
SizedBox(height: 300), SizedBox(height: 300),
@@ -265,7 +257,8 @@ class _DocumentUploadPreparationPageState
tags: tags.ids, tags: tags.ids,
createdAt: createdAt, createdAt: createdAt,
); );
showSnackBar(context, S.of(context).documentUploadSuccessText); showSnackBar(
context, S.of(context).documentSuccessfullyUploadedProcessing);
Navigator.pop(context, taskId); Navigator.pop(context, taskId);
} on PaperlessServerException catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
showErrorMessage(context, error, stackTrace); showErrorMessage(context, error, stackTrace);
@@ -32,7 +32,7 @@ class _DocumentViewState extends State<DocumentView> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(S.of(context).documentPreviewPageTitle), title: Text(S.of(context).preview),
), ),
body: PdfView( body: PdfView(
builders: PdfViewBuilders<DefaultBuilderOptions>( builders: PdfViewBuilders<DefaultBuilderOptions>(
@@ -112,11 +112,9 @@ class _DocumentsPageState extends State<DocumentsPage>
listener: (context, state) { listener: (context, state) {
showSnackBar( showSnackBar(
context, context,
S.of(context).documentsPageNewDocumentAvailableText, S.of(context).newDocumentAvailable,
action: SnackBarActionConfig( action: SnackBarActionConfig(
label: S label: S.of(context).reload,
.of(context)
.documentUploadProcessingSuccessfulReloadActionText,
onPressed: () { onPressed: () {
context.read<TaskStatusCubit>().acknowledgeCurrentTask(); context.read<TaskStatusCubit>().acknowledgeCurrentTask();
context.read<DocumentsCubit>().reload(); context.read<DocumentsCubit>().reload();
@@ -202,7 +200,7 @@ class _DocumentsPageState extends State<DocumentsPage>
.resetSelection(), .resetSelection(),
), ),
title: Text( title: Text(
"${state.selection.length} ${S.of(context).documentsSelectedText}", "${state.selection.length} ${S.of(context).countSelected}",
), ),
actions: [ actions: [
IconButton( IconButton(
@@ -213,14 +211,13 @@ class _DocumentsPageState extends State<DocumentsPage>
); );
} }
return SearchAppBar( return SearchAppBar(
hintText: hintText: S.of(context).searchDocuments,
S.of(context).documentSearchSearchDocuments,
onOpenSearch: showDocumentSearchPage, onOpenSearch: showDocumentSearchPage,
bottom: TabBar( bottom: TabBar(
controller: _tabController, controller: _tabController,
tabs: [ tabs: [
Tab(text: S.of(context).documentsPageTitle), Tab(text: S.of(context).documents),
Tab(text: S.of(context).savedViewsLabel), Tab(text: S.of(context).views),
], ],
), ),
); );
@@ -296,7 +293,7 @@ class _DocumentsPageState extends State<DocumentsPage>
_nestedScrollViewKey.currentState?.outerController.jumpTo(0); _nestedScrollViewKey.currentState?.outerController.jumpTo(0);
}, },
label: Text( label: Text(
S.of(context).scrollToTopLabel, S.of(context).scrollToTop,
style: DefaultTextStyle.of(context).style.apply( style: DefaultTextStyle.of(context).style.apply(
color: Theme.of(context).colorScheme.onPrimary, color: Theme.of(context).colorScheme.onPrimary,
), ),
@@ -411,7 +408,7 @@ class _DocumentsPageState extends State<DocumentsPage>
.bulkDelete(documentsState.selection); .bulkDelete(documentsState.selection);
showSnackBar( showSnackBar(
context, context,
S.of(context).documentsPageBulkDeleteSuccessfulText, S.of(context).documentsSuccessfullyDeleted,
); );
context.read<DocumentsCubit>().resetSelection(); context.read<DocumentsCubit>().resetSelection();
} on PaperlessServerException catch (error, stackTrace) { } on PaperlessServerException catch (error, stackTrace) {
@@ -9,12 +9,12 @@ class DeleteDocumentConfirmationDialog extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( return AlertDialog(
title: Text(S.of(context).documentsPageSelectionBulkDeleteDialogTitle), title: Text(S.of(context).confirmDeletion),
content: Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
S.of(context).documentsPageSelectionBulkDeleteDialogWarningTextOne, S.of(context).areYouSureYouWantToDeleteTheFollowingDocuments(1),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Text( Text(
@@ -26,14 +26,13 @@ class DeleteDocumentConfirmationDialog extends StatelessWidget {
), ),
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
Text( Text(S.of(context).thisActionIsIrreversibleDoYouWishToProceedAnyway),
S.of(context).documentsPageSelectionBulkDeleteDialogContinueText),
], ],
), ),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(context, false), onPressed: () => Navigator.pop(context, false),
child: Text(S.of(context).genericActionCancelLabel), child: Text(S.of(context).cancel),
), ),
TextButton( TextButton(
style: ButtonStyle( style: ButtonStyle(
@@ -43,7 +42,7 @@ class DeleteDocumentConfirmationDialog extends StatelessWidget {
onPressed: () { onPressed: () {
Navigator.pop(context, true); Navigator.pop(context, true);
}, },
child: Text(S.of(context).genericActionDeleteLabel), child: Text(S.of(context).delete),
), ),
], ],
); );
@@ -18,13 +18,13 @@ class DocumentsEmptyState extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Center( return Center(
child: EmptyState( child: EmptyState(
title: S.of(context).documentsPageEmptyStateOopsText, title: S.of(context).oops,
subtitle: S.of(context).documentsPageEmptyStateNothingHereText, subtitle: S.of(context).thereSeemsToBeNothingHere,
bottomChild: state.filter != DocumentFilter.initial && onReset != null bottomChild: state.filter != DocumentFilter.initial && onReset != null
? TextButton( ? TextButton(
onPressed: onReset, onPressed: onReset,
child: Text( child: Text(
S.of(context).documentsEmptyStateResetFilterLabel, S.of(context).resetFilter,
), ),
).padded() ).padded()
: null, : null,
@@ -96,14 +96,14 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
Align( Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: Text( child: Text(
S.of(context).documentFilterAdvancedLabel, S.of(context).advanced,
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
), ),
), ),
FormBuilderExtendedDateRangePicker( FormBuilderExtendedDateRangePicker(
name: DocumentFilterForm.fkCreatedAt, name: DocumentFilterForm.fkCreatedAt,
initialValue: widget.initialFilter.created, initialValue: widget.initialFilter.created,
labelText: S.of(context).documentCreatedPropertyLabel, labelText: S.of(context).createdAt,
onChanged: (_) { onChanged: (_) {
_checkQueryConstraints(); _checkQueryConstraints();
}, },
@@ -111,7 +111,7 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
FormBuilderExtendedDateRangePicker( FormBuilderExtendedDateRangePicker(
name: DocumentFilterForm.fkAddedAt, name: DocumentFilterForm.fkAddedAt,
initialValue: widget.initialFilter.added, initialValue: widget.initialFilter.added,
labelText: S.of(context).documentAddedPropertyLabel, labelText: S.of(context).addedAt,
onChanged: (_) { onChanged: (_) {
_checkQueryConstraints(); _checkQueryConstraints();
}, },
@@ -151,7 +151,7 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
formBuilderState: widget.formKey.currentState, formBuilderState: widget.formKey.currentState,
name: DocumentFilterForm.fkDocumentType, name: DocumentFilterForm.fkDocumentType,
labelOptions: state.labels, labelOptions: state.labels,
textFieldLabel: S.of(context).documentDocumentTypePropertyLabel, textFieldLabel: S.of(context).documentType,
initialValue: widget.initialFilter.documentType, initialValue: widget.initialFilter.documentType,
prefixIcon: const Icon(Icons.description_outlined), prefixIcon: const Icon(Icons.description_outlined),
); );
@@ -166,7 +166,7 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
formBuilderState: widget.formKey.currentState, formBuilderState: widget.formKey.currentState,
name: DocumentFilterForm.fkCorrespondent, name: DocumentFilterForm.fkCorrespondent,
labelOptions: state.labels, labelOptions: state.labels,
textFieldLabel: S.of(context).documentCorrespondentPropertyLabel, textFieldLabel: S.of(context).correspondent,
initialValue: widget.initialFilter.correspondent, initialValue: widget.initialFilter.correspondent,
prefixIcon: const Icon(Icons.person_outline), prefixIcon: const Icon(Icons.person_outline),
); );
@@ -181,7 +181,7 @@ class _DocumentFilterFormState extends State<DocumentFilterForm> {
formBuilderState: widget.formKey.currentState, formBuilderState: widget.formKey.currentState,
name: DocumentFilterForm.fkStoragePath, name: DocumentFilterForm.fkStoragePath,
labelOptions: state.labels, labelOptions: state.labels,
textFieldLabel: S.of(context).documentStoragePathPropertyLabel, textFieldLabel: S.of(context).storagePath,
initialValue: widget.initialFilter.storagePath, initialValue: widget.initialFilter.storagePath,
prefixIcon: const Icon(Icons.folder_outlined), prefixIcon: const Icon(Icons.folder_outlined),
); );
@@ -74,7 +74,7 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
visible: MediaQuery.of(context).viewInsets.bottom == 0, visible: MediaQuery.of(context).viewInsets.bottom == 0,
child: FloatingActionButton.extended( child: FloatingActionButton.extended(
icon: const Icon(Icons.done), icon: const Icon(Icons.done),
label: Text(S.of(context).documentFilterApplyFilterLabel), label: Text(S.of(context).apply),
onPressed: _onApplyFilter, onPressed: _onApplyFilter,
), ),
), ),
@@ -85,7 +85,7 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
TextButton.icon( TextButton.icon(
onPressed: _resetFilter, onPressed: _resetFilter,
icon: const Icon(Icons.refresh), icon: const Icon(Icons.refresh),
label: Text(S.of(context).documentFilterResetLabel), label: Text(S.of(context).reset),
), ),
], ],
), ),
@@ -133,7 +133,7 @@ class _DocumentFilterPanelState extends State<DocumentFilterPanel> {
), ),
Padding( Padding(
padding: EdgeInsets.only(left: _heightAnimationValue * 48), padding: EdgeInsets.only(left: _heightAnimationValue * 48),
child: Text(S.of(context).documentFilterTitle), child: Text(S.of(context).filterDocuments),
), ),
], ],
), ),
@@ -48,12 +48,12 @@ class _SortFieldSelectionBottomSheetState
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text( Text(
S.of(context).documentsPageOrderByLabel, S.of(context).orderBy,
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
textAlign: TextAlign.start, textAlign: TextAlign.start,
), ),
TextButton( TextButton(
child: Text(S.of(context).documentFilterApplyFilterLabel), child: Text(S.of(context).apply),
onPressed: () { onPressed: () {
widget.onSubmit( widget.onSubmit(
_currentSortField, _currentSortField,
@@ -105,12 +105,12 @@ class _SortFieldSelectionBottomSheetState
ButtonSegment( ButtonSegment(
icon: const FaIcon(FontAwesomeIcons.arrowDownAZ), icon: const FaIcon(FontAwesomeIcons.arrowDownAZ),
value: SortOrder.descending, value: SortOrder.descending,
label: Text(S.of(context).sortDocumentDescending), label: Text(S.of(context).descending),
), ),
ButtonSegment( ButtonSegment(
icon: const FaIcon(FontAwesomeIcons.arrowUpZA), icon: const FaIcon(FontAwesomeIcons.arrowUpZA),
value: SortOrder.ascending, value: SortOrder.ascending,
label: Text(S.of(context).sortDocumentAscending), label: Text(S.of(context).ascending),
), ),
], ],
emptySelectionAllowed: false, emptySelectionAllowed: false,
@@ -63,20 +63,19 @@ class TextQueryFormField extends StatelessWidget {
itemBuilder: (context) => [ itemBuilder: (context) => [
PopupMenuItem( PopupMenuItem(
child: ListTile( child: ListTile(
title: Text( title: Text(S.of(context).titleAndContent),
S.of(context).documentFilterQueryOptionsTitleAndContentLabel),
), ),
value: QueryType.titleAndContent, value: QueryType.titleAndContent,
), ),
PopupMenuItem( PopupMenuItem(
child: ListTile( child: ListTile(
title: Text(S.of(context).documentFilterQueryOptionsTitleLabel), title: Text(S.of(context).title),
), ),
value: QueryType.title, value: QueryType.title,
), ),
PopupMenuItem( PopupMenuItem(
child: ListTile( child: ListTile(
title: Text(S.of(context).documentFilterQueryOptionsExtendedLabel), title: Text(S.of(context).extended),
), ),
value: QueryType.extended, value: QueryType.extended,
), ),
@@ -90,11 +89,11 @@ class TextQueryFormField extends StatelessWidget {
String _buildLabelText(BuildContext context, QueryType queryType) { String _buildLabelText(BuildContext context, QueryType queryType) {
switch (queryType) { switch (queryType) {
case QueryType.title: case QueryType.title:
return S.of(context).documentFilterQueryOptionsTitleLabel; return S.of(context).title;
case QueryType.titleAndContent: case QueryType.titleAndContent:
return S.of(context).documentFilterQueryOptionsTitleAndContentLabel; return S.of(context).titleAndContent;
case QueryType.extended: case QueryType.extended:
return S.of(context).documentFilterQueryOptionsExtendedLabel; return S.of(context).extended;
default: default:
return ''; return '';
} }
@@ -14,31 +14,24 @@ class BulkDeleteConfirmationDialog extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
assert(state.selection.isNotEmpty); assert(state.selection.isNotEmpty);
return AlertDialog( return AlertDialog(
title: Text(S.of(context).documentsPageSelectionBulkDeleteDialogTitle), title: Text(S.of(context).confirmDeletion),
content: Column( content: Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
//TODO: use plurals, didn't use because of crash... investigate later. S.of(context).areYouSureYouWantToDeleteTheFollowingDocuments(
state.selection.length == 1 state.selection.length),
? S
.of(context)
.documentsPageSelectionBulkDeleteDialogWarningTextOne
: S
.of(context)
.documentsPageSelectionBulkDeleteDialogWarningTextMany,
), ),
const SizedBox(height: 16), const SizedBox(height: 16),
...state.selection.map(_buildBulletPoint).toList(), ...state.selection.map(_buildBulletPoint).toList(),
const SizedBox(height: 16), const SizedBox(height: 16),
Text( Text(S.of(context).thisActionIsIrreversibleDoYouWishToProceedAnyway),
S.of(context).documentsPageSelectionBulkDeleteDialogContinueText),
], ],
), ),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(context, false), onPressed: () => Navigator.pop(context, false),
child: Text(S.of(context).genericActionCancelLabel), child: Text(S.of(context).cancel),
), ),
TextButton( TextButton(
style: ButtonStyle( style: ButtonStyle(
@@ -48,7 +41,7 @@ class BulkDeleteConfirmationDialog extends StatelessWidget {
onPressed: () { onPressed: () {
Navigator.pop(context, true); Navigator.pop(context, true);
}, },
child: Text(S.of(context).genericActionDeleteLabel), child: Text(S.of(context).delete),
), ),
], ],
); );
@@ -14,18 +14,18 @@ class ConfirmDeleteSavedViewDialog extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( return AlertDialog(
title: Text( title: Text(
S.of(context).deleteViewDialogTitleText + view.name + "?", S.of(context).deleteView + view.name + "?",
softWrap: true, softWrap: true,
), ),
content: Text(S.of(context).deleteViewDialogContentText), content: Text(S.of(context).doYouReallyWantToDeleteThisView),
actions: [ actions: [
TextButton( TextButton(
child: Text(S.of(context).genericActionCancelLabel), child: Text(S.of(context).cancel),
onPressed: () => Navigator.pop(context, false), onPressed: () => Navigator.pop(context, false),
), ),
TextButton( TextButton(
child: Text( child: Text(
S.of(context).genericActionDeleteLabel, S.of(context).delete,
style: TextStyle(color: Theme.of(context).colorScheme.error), style: TextStyle(color: Theme.of(context).colorScheme.error),
), ),
onPressed: () => Navigator.pop(context, true), onPressed: () => Navigator.pop(context, true),
@@ -34,19 +34,19 @@ class ViewTypeSelectionWidget extends StatelessWidget {
_buildViewTypeOption( _buildViewTypeOption(
context, context,
type: ViewType.list, type: ViewType.list,
label: S.of(context).viewTypeListOption, label: S.of(context).list,
icon: Icons.list, icon: Icons.list,
), ),
_buildViewTypeOption( _buildViewTypeOption(
context, context,
type: ViewType.grid, type: ViewType.grid,
label: S.of(context).viewTypeGridOption, label: S.of(context).grid,
icon: Icons.grid_view_rounded, icon: Icons.grid_view_rounded,
), ),
_buildViewTypeOption( _buildViewTypeOption(
context, context,
type: ViewType.detailed, type: ViewType.detailed,
label: S.of(context).viewTypeDetailedOption, label: S.of(context).detailed,
icon: Icons.article_outlined, icon: Icons.article_outlined,
), ),
], ],
@@ -62,7 +62,7 @@ class AddLabelFormWidget<T extends Label> extends StatelessWidget {
fromJsonT: fromJsonT, fromJsonT: fromJsonT,
submitButtonConfig: SubmitButtonConfig<T>( submitButtonConfig: SubmitButtonConfig<T>(
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
label: Text(S.of(context).genericActionCreateLabel), label: Text(S.of(context).create),
onSubmit: context.read<EditLabelCubit<T>>().create, onSubmit: context.read<EditLabelCubit<T>>().create,
), ),
additionalFields: additionalFields, additionalFields: additionalFields,
@@ -55,7 +55,7 @@ class EditLabelForm<T extends Label> extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(S.of(context).genericActionEditLabel), title: Text(S.of(context).edit),
actions: [ actions: [
IconButton( IconButton(
onPressed: () => _onDelete(context), onPressed: () => _onDelete(context),
@@ -68,7 +68,7 @@ class EditLabelForm<T extends Label> extends StatelessWidget {
fromJsonT: fromJsonT, fromJsonT: fromJsonT,
submitButtonConfig: SubmitButtonConfig<T>( submitButtonConfig: SubmitButtonConfig<T>(
icon: const Icon(Icons.save), icon: const Icon(Icons.save),
label: Text(S.of(context).genericActionUpdateLabel), label: Text(S.of(context).saveChanges),
onSubmit: context.read<EditLabelCubit<T>>().update, onSubmit: context.read<EditLabelCubit<T>>().update,
), ),
additionalFields: additionalFields, additionalFields: additionalFields,
@@ -81,22 +81,21 @@ class EditLabelForm<T extends Label> extends StatelessWidget {
final shouldDelete = await showDialog<bool>( final shouldDelete = await showDialog<bool>(
context: context, context: context,
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
title: title: Text(S.of(context).confirmDeletion),
Text(S.of(context).editLabelPageConfirmDeletionDialogTitle),
content: Text( content: Text(
S.of(context).editLabelPageDeletionDialogText, S.of(context).deleteLabelWarningText,
), ),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.pop(context, false), onPressed: () => Navigator.pop(context, false),
child: Text(S.of(context).genericActionCancelLabel), child: Text(S.of(context).cancel),
), ),
TextButton( TextButton(
onPressed: () { onPressed: () {
Navigator.pop(context, true); Navigator.pop(context, true);
}, },
child: Text( child: Text(
S.of(context).genericActionDeleteLabel, S.of(context).delete,
style: style:
TextStyle(color: Theme.of(context).colorScheme.error), TextStyle(color: Theme.of(context).colorScheme.error),
), ),
@@ -18,7 +18,7 @@ class AddCorrespondentPage extends StatelessWidget {
context.read<LabelRepository<Correspondent>>(), context.read<LabelRepository<Correspondent>>(),
), ),
child: AddLabelPage<Correspondent>( child: AddLabelPage<Correspondent>(
pageTitle: Text(S.of(context).addCorrespondentPageTitle), pageTitle: Text(S.of(context).addCorrespondent),
fromJsonT: Correspondent.fromJson, fromJsonT: Correspondent.fromJson,
initialName: initialName, initialName: initialName,
), ),
@@ -21,7 +21,7 @@ class AddDocumentTypePage extends StatelessWidget {
context.read<LabelRepository<DocumentType>>(), context.read<LabelRepository<DocumentType>>(),
), ),
child: AddLabelPage<DocumentType>( child: AddLabelPage<DocumentType>(
pageTitle: Text(S.of(context).addDocumentTypePageTitle), pageTitle: Text(S.of(context).addDocumentType),
fromJsonT: DocumentType.fromJson, fromJsonT: DocumentType.fromJson,
initialName: initialName, initialName: initialName,
), ),
@@ -19,7 +19,7 @@ class AddStoragePathPage extends StatelessWidget {
context.read<LabelRepository<StoragePath>>(), context.read<LabelRepository<StoragePath>>(),
), ),
child: AddLabelPage<StoragePath>( child: AddLabelPage<StoragePath>(
pageTitle: Text(S.of(context).addStoragePathPageTitle), pageTitle: Text(S.of(context).addStoragePath),
fromJsonT: StoragePath.fromJson, fromJsonT: StoragePath.fromJson,
initialName: initalValue, initialName: initalValue,
additionalFields: const [ additionalFields: const [
@@ -22,7 +22,7 @@ class AddTagPage extends StatelessWidget {
context.read<LabelRepository<Tag>>(), context.read<LabelRepository<Tag>>(),
), ),
child: AddLabelPage<Tag>( child: AddLabelPage<Tag>(
pageTitle: Text(S.of(context).addTagPageTitle), pageTitle: Text(S.of(context).addTag),
fromJsonT: Tag.fromJson, fromJsonT: Tag.fromJson,
initialName: initialValue, initialName: initialValue,
additionalFields: [ additionalFields: [
@@ -30,7 +30,7 @@ class AddTagPage extends StatelessWidget {
name: Tag.colorKey, name: Tag.colorKey,
valueTransformer: (color) => "#${color?.value.toRadixString(16)}", valueTransformer: (color) => "#${color?.value.toRadixString(16)}",
decoration: InputDecoration( decoration: InputDecoration(
label: Text(S.of(context).tagColorPropertyLabel), label: Text(S.of(context).color),
), ),
colorPickerType: ColorPickerType.materialPicker, colorPickerType: ColorPickerType.materialPicker,
initialValue: Color((Random().nextDouble() * 0xFFFFFF).toInt()) initialValue: Color((Random().nextDouble() * 0xFFFFFF).toInt())
@@ -38,7 +38,7 @@ class AddTagPage extends StatelessWidget {
), ),
FormBuilderCheckbox( FormBuilderCheckbox(
name: Tag.isInboxTagKey, name: Tag.isInboxTagKey,
title: Text(S.of(context).tagInboxTagPropertyLabel), title: Text(S.of(context).inboxTag),
), ),
], ],
), ),
@@ -28,14 +28,14 @@ class EditTagPage extends StatelessWidget {
initialValue: tag.color, initialValue: tag.color,
name: Tag.colorKey, name: Tag.colorKey,
decoration: InputDecoration( decoration: InputDecoration(
label: Text(S.of(context).tagColorPropertyLabel), label: Text(S.of(context).color),
), ),
colorPickerType: ColorPickerType.blockPicker, colorPickerType: ColorPickerType.blockPicker,
), ),
FormBuilderCheckbox( FormBuilderCheckbox(
initialValue: tag.isInboxTag, initialValue: tag.isInboxTag,
name: Tag.isInboxTagKey, name: Tag.isInboxTagKey,
title: Text(S.of(context).tagInboxTagPropertyLabel), title: Text(S.of(context).inboxTag),
), ),
], ],
), ),
+4 -4
View File
@@ -75,7 +75,7 @@ class _LabelFormState<T extends Label> extends State<LabelForm<T>> {
FormBuilderTextField( FormBuilderTextField(
name: Label.nameKey, name: Label.nameKey,
decoration: InputDecoration( decoration: InputDecoration(
labelText: S.of(context).labelNamePropertyLabel, labelText: S.of(context).name,
errorText: _errors[Label.nameKey], errorText: _errors[Label.nameKey],
), ),
validator: FormBuilderValidators.required(), validator: FormBuilderValidators.required(),
@@ -88,7 +88,7 @@ class _LabelFormState<T extends Label> extends State<LabelForm<T>> {
MatchingAlgorithm.defaultValue) MatchingAlgorithm.defaultValue)
.value, .value,
decoration: InputDecoration( decoration: InputDecoration(
labelText: S.of(context).labelMatchingAlgorithmPropertyLabel, labelText: S.of(context).matchingAlgorithm,
errorText: _errors[Label.matchingAlgorithmKey], errorText: _errors[Label.matchingAlgorithmKey],
), ),
onChanged: (val) { onChanged: (val) {
@@ -112,7 +112,7 @@ class _LabelFormState<T extends Label> extends State<LabelForm<T>> {
FormBuilderTextField( FormBuilderTextField(
name: Label.matchKey, name: Label.matchKey,
decoration: InputDecoration( decoration: InputDecoration(
labelText: S.of(context).labelMatchPropertyLabel, labelText: S.of(context).match,
errorText: _errors[Label.matchKey], errorText: _errors[Label.matchKey],
), ),
initialValue: widget.initialValue?.match, initialValue: widget.initialValue?.match,
@@ -121,7 +121,7 @@ class _LabelFormState<T extends Label> extends State<LabelForm<T>> {
FormBuilderCheckbox( FormBuilderCheckbox(
name: Label.isInsensitiveKey, name: Label.isInsensitiveKey,
initialValue: widget.initialValue?.isInsensitive ?? true, initialValue: widget.initialValue?.isInsensitive ?? true,
title: Text(S.of(context).labelIsInsensivitePropertyLabel), title: Text(S.of(context).caseIrrelevant),
), ),
...widget.additionalFields, ...widget.additionalFields,
].padded(), ].padded(),
+6 -13
View File
@@ -153,7 +153,6 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
} }
final filename = extractFilenameFromPath(mediaFile.path); final filename = extractFilenameFromPath(mediaFile.path);
final extension = p.extension(mediaFile.path); final extension = p.extension(mediaFile.path);
try {
if (await File(mediaFile.path).exists()) { if (await File(mediaFile.path).exists()) {
final bytes = File(mediaFile.path).readAsBytesSync(); final bytes = File(mediaFile.path).readAsBytesSync();
final success = await Navigator.push<bool>( final success = await Navigator.push<bool>(
@@ -178,23 +177,17 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
false; false;
if (success) { if (success) {
await Fluttertoast.showToast( await Fluttertoast.showToast(
msg: S.of(context).documentUploadSuccessText, msg: S.of(context).documentSuccessfullyUploadedProcessing,
); );
SystemNavigator.pop(); SystemNavigator.pop();
} }
} else { } else {
Fluttertoast.showToast( Fluttertoast.showToast(
msg: S.of(context).receiveSharedFilePermissionDeniedMessage, msg: S.of(context).couldNotAccessReceivedFile,
toastLength: Toast.LENGTH_LONG, toastLength: Toast.LENGTH_LONG,
); );
} }
} catch (e) {
Fluttertoast.showToast(
msg: S.of(context).receiveSharedFilePermissionDeniedMessage,
toastLength: Toast.LENGTH_LONG,
);
} }
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@@ -205,7 +198,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
Icons.description, Icons.description,
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
label: S.of(context).bottomNavDocumentsPageLabel, label: S.of(context).documents,
), ),
RouteDescription( RouteDescription(
icon: const Icon(Icons.document_scanner_outlined), icon: const Icon(Icons.document_scanner_outlined),
@@ -213,7 +206,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
Icons.document_scanner, Icons.document_scanner,
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
label: S.of(context).bottomNavScannerPageLabel, label: S.of(context).scanner,
), ),
RouteDescription( RouteDescription(
icon: const Icon(Icons.sell_outlined), icon: const Icon(Icons.sell_outlined),
@@ -221,7 +214,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
Icons.sell, Icons.sell,
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
label: S.of(context).bottomNavLabelsPageLabel, label: S.of(context).labels,
), ),
RouteDescription( RouteDescription(
icon: const Icon(Icons.inbox_outlined), icon: const Icon(Icons.inbox_outlined),
@@ -229,7 +222,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
Icons.inbox, Icons.inbox,
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
label: S.of(context).bottomNavInboxPageLabel, label: S.of(context).inbox,
badgeBuilder: (icon) => BlocBuilder<InboxCubit, InboxState>( badgeBuilder: (icon) => BlocBuilder<InboxCubit, InboxState>(
bloc: _inboxCubit, bloc: _inboxCubit,
builder: (context, state) { builder: (context, state) {
@@ -1,320 +0,0 @@
// import 'package:flutter/material.dart';
// import 'package:flutter_bloc/flutter_bloc.dart';
// import 'package:hydrated_bloc/hydrated_bloc.dart';
// import 'package:package_info_plus/package_info_plus.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_state.dart';
// import 'package:paperless_mobile/core/repository/label_repository.dart';
// import 'package:paperless_mobile/core/repository/provider/label_repositories_provider.dart';
// import 'package:paperless_mobile/core/repository/saved_view_repository.dart';
// import 'package:paperless_mobile/core/repository/state/impl/correspondent_repository_state.dart';
// import 'package:paperless_mobile/core/repository/state/impl/document_type_repository_state.dart';
// import 'package:paperless_mobile/core/repository/state/impl/storage_path_repository_state.dart';
// import 'package:paperless_mobile/core/repository/state/impl/tag_repository_state.dart';
// import 'package:paperless_mobile/extensions/flutter_extensions.dart';
// import 'package:paperless_mobile/features/inbox/cubit/inbox_cubit.dart';
// import 'package:paperless_mobile/features/inbox/view/pages/inbox_page.dart';
// import 'package:paperless_mobile/features/login/bloc/authentication_cubit.dart';
// import 'package:paperless_mobile/features/settings/bloc/application_settings_cubit.dart';
// import 'package:paperless_mobile/features/settings/view/settings_page.dart';
// import 'package:paperless_mobile/generated/l10n.dart';
// import 'package:paperless_mobile/helpers/message_helpers.dart';
// import 'package:paperless_mobile/constants.dart';
// import 'package:url_launcher/link.dart';
// import 'package:url_launcher/url_launcher_string.dart';
// class AppDrawer extends StatefulWidget {
// final VoidCallback? afterInboxClosed;
// const AppDrawer({Key? key, this.afterInboxClosed}) : super(key: key);
// @override
// State<AppDrawer> createState() => _AppDrawerState();
// }
// // enum NavigationDestinations {
// // inbox,
// // settings,
// // reportBug,
// // about,
// // logout;
// // }
// class _AppDrawerState extends State<AppDrawer> {
// @override
// void initState() {
// super.initState();
// }
// @override
// Widget build(BuildContext context) {
// final listtTileShape = RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(32),
// );
// // return NavigationDrawer(
// // selectedIndex: -1,
// // children: [
// // Text(
// // "",
// // style: Theme.of(context).textTheme.titleSmall,
// // ).padded(16),
// // NavigationDrawerDestination(
// // icon: const Icon(Icons.inbox),
// // label: Text(S.of(context).bottomNavInboxPageLabel),
// // ),
// // NavigationDrawerDestination(
// // icon: const Icon(Icons.settings),
// // label: Text(S.of(context).appDrawerSettingsLabel),
// // ),
// // const Divider(
// // indent: 16,
// // ),
// // NavigationDrawerDestination(
// // icon: const Icon(Icons.bug_report),
// // label: Text(S.of(context).appDrawerReportBugLabel),
// // ),
// // NavigationDrawerDestination(
// // icon: const Icon(Icons.info_outline),
// // label: Text(S.of(context).appDrawerAboutLabel),
// // ),
// // ],
// // onDestinationSelected: (idx) {
// // final val = NavigationDestinations.values[idx - 1];
// // switch (val) {
// // case NavigationDestinations.inbox:
// // _onOpenInbox();
// // break;
// // case NavigationDestinations.settings:
// // _onOpenSettings();
// // break;
// // case NavigationDestinations.reportBug:
// // launchUrlString(
// // 'https://github.com/astubenbord/paperless-mobile/issues/new',
// // );
// // break;
// // case NavigationDestinations.about:
// // _onShowAboutDialog();
// // break;
// // case NavigationDestinations.logout:
// // _onLogout();
// // break;
// // }
// // },
// // );
// return SafeArea(
// top: true,
// child: ClipRRect(
// borderRadius: const BorderRadius.only(
// topRight: Radius.circular(16.0),
// bottomRight: Radius.circular(16.0),
// ),
// child: Drawer(
// shape: const RoundedRectangleBorder(
// borderRadius: BorderRadius.only(
// topRight: Radius.circular(16.0),
// bottomRight: Radius.circular(16.0),
// ),
// ),
// child: ListView(
// children: [
// DrawerHeader(
// decoration: BoxDecoration(
// color: Theme.of(context).colorScheme.secondaryContainer,
// ),
// padding: const EdgeInsets.only(
// top: 8,
// left: 8,
// bottom: 0,
// right: 8,
// ),
// child: Column(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// children: [
// Image.asset(
// 'assets/logos/paperless_logo_white.png',
// height: 32,
// width: 32,
// color:
// Theme.of(context).colorScheme.onPrimaryContainer,
// ).paddedOnly(right: 8.0),
// Text(
// S.of(context).appTitleText,
// style: Theme.of(context)
// .textTheme
// .headlineSmall
// ?.copyWith(
// color: Theme.of(context)
// .colorScheme
// .onPrimaryContainer,
// ),
// ),
// ],
// ),
// Align(
// alignment: Alignment.bottomRight,
// child: BlocBuilder<PaperlessServerInformationCubit,
// PaperlessServerInformationState>(
// builder: (context, state) {
// if (!state.isLoaded) {
// return Container();
// }
// final info = state.information!;
// return Column(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// ListTile(
// contentPadding: EdgeInsets.zero,
// dense: true,
// title: Text(
// S.of(context).appDrawerHeaderLoggedInAsText +
// (info.username ?? '?'),
// style: Theme.of(context).textTheme.bodyMedium,
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.end,
// maxLines: 1,
// ),
// subtitle: Column(
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// Text(
// state.information!.host ?? '',
// style: Theme.of(context)
// .textTheme
// .bodyMedium,
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.end,
// maxLines: 1,
// ),
// Text(
// '${S.of(context).serverInformationPaperlessVersionText} ${info.version} (API v${info.apiVersion})',
// style:
// Theme.of(context).textTheme.bodySmall,
// overflow: TextOverflow.ellipsis,
// textAlign: TextAlign.end,
// maxLines: 1,
// ),
// ],
// ),
// isThreeLine: true,
// ),
// ],
// );
// },
// ),
// ),
// ],
// ),
// ),
// ...[
// ListTile(
// title: Text(S.of(context).bottomNavInboxPageLabel),
// leading: const Icon(Icons.inbox),
// onTap: () => _onOpenInbox(),
// shape: listtTileShape,
// ),
// ListTile(
// leading: const Icon(Icons.settings),
// shape: listtTileShape,
// title: Text(
// S.of(context).appDrawerSettingsLabel,
// ),
// onTap: () => Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) => BlocProvider.value(
// value: context.read<ApplicationSettingsCubit>(),
// child: const SettingsPage(),
// ),
// ),
// ),
// ),
// const Divider(
// indent: 16,
// endIndent: 16,
// ),
// ListTile(
// leading: const Icon(Icons.bug_report),
// title: Text(S.of(context).appDrawerReportBugLabel),
// onTap: () {
// launchUrlString(
// 'https://github.com/astubenbord/paperless-mobile/issues/new');
// },
// shape: listtTileShape,
// ),
// ListTile(
// title: Text(S.of(context).appDrawerAboutLabel),
// leading: Icon(Icons.info_outline_rounded),
// onTap: _onShowAboutDialog,
// shape: listtTileShape,
// ),
// ListTile(
// leading: const Icon(Icons.logout),
// title: Text(S.of(context).appDrawerLogoutLabel),
// shape: listtTileShape,
// onTap: () {
// _onLogout();
// },
// )
// ],
// ],
// ),
// ),
// ),
// );
// }
// void _onLogout() async {
// try {
// await context.read<AuthenticationCubit>().logout();
// await context.read<ApplicationSettingsCubit>().clear();
// await context.read<LabelRepository<Tag, TagRepositoryState>>().clear();
// await context
// .read<LabelRepository<Correspondent, CorrespondentRepositoryState>>()
// .clear();
// await context
// .read<LabelRepository<DocumentType, DocumentTypeRepositoryState>>()
// .clear();
// await context
// .read<LabelRepository<StoragePath, StoragePathRepositoryState>>()
// .clear();
// await context.read<SavedViewRepository>().clear();
// await HydratedBloc.storage.clear();
// } on PaperlessServerException catch (error, stackTrace) {
// showErrorMessage(context, error, stackTrace);
// }
// }
// Future<void> _onOpenInbox() async {
// await Navigator.of(context).push(
// MaterialPageRoute(
// builder: (_) => LabelRepositoriesProvider(
// child: BlocProvider(
// create: (context) => InboxCubit(
// context.read(),
// context.read(),
// context.read(),
// context.read(),
// )..initializeInbox(),
// child: const InboxPage(),
// ),
// ),
// ),
// );
// widget.afterInboxClosed?.call();
// }
// void _onOpenSettings() {
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (context) => BlocProvider.value(
// value: context.read<ApplicationSettingsCubit>(),
// child: const SettingsPage(),
// ),
// ),
// );
// }
// void _onShowAboutDialog() {}
// }
@@ -19,12 +19,12 @@ class VerifyIdentityPage extends StatelessWidget {
appBar: AppBar( appBar: AppBar(
elevation: 0, elevation: 0,
backgroundColor: Theme.of(context).colorScheme.background, backgroundColor: Theme.of(context).colorScheme.background,
title: Text(S.of(context).verifyIdentityPageTitle), title: Text(S.of(context).verifyYourIdentity),
), ),
body: Column( body: Column(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(S.of(context).verifyIdentityPageDescriptionText) Text(S.of(context).useTheConfiguredBiometricFactorToAuthenticate)
.paddedSymmetrically(horizontal: 16), .paddedSymmetrically(horizontal: 16),
const Icon( const Icon(
Icons.fingerprint, Icons.fingerprint,
@@ -39,7 +39,7 @@ class VerifyIdentityPage extends StatelessWidget {
TextButton( TextButton(
onPressed: () => _logout(context), onPressed: () => _logout(context),
child: Text( child: Text(
S.of(context).verifyIdentityPageLogoutButtonLabel, S.of(context).disconnect,
style: TextStyle( style: TextStyle(
color: Theme.of(context).colorScheme.error, color: Theme.of(context).colorScheme.error,
), ),
@@ -52,9 +52,7 @@ class VerifyIdentityPage extends StatelessWidget {
.read<ApplicationSettingsCubit>() .read<ApplicationSettingsCubit>()
.state .state
.isLocalAuthenticationEnabled), .isLocalAuthenticationEnabled),
child: Text(S child: Text(S.of(context).verifyIdentity),
.of(context)
.verifyIdentityPageVerifyIdentityButtonLabel),
), ),
], ],
).padded(16), ).padded(16),
+13 -14
View File
@@ -52,7 +52,7 @@ class _InboxPageState extends State<InboxPage>
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return FloatingActionButton.extended( return FloatingActionButton.extended(
label: Text(S.of(context).inboxPageMarkAllAsSeenLabel), label: Text(S.of(context).allSeen),
icon: const Icon(Icons.done_all), icon: const Icon(Icons.done_all),
onPressed: state.hasLoaded && state.documents.isNotEmpty onPressed: state.hasLoaded && state.documents.isNotEmpty
? () => _onMarkAllAsSeen( ? () => _onMarkAllAsSeen(
@@ -128,7 +128,7 @@ class _InboxPageState extends State<InboxPage>
controller: pagingScrollController, controller: pagingScrollController,
slivers: [ slivers: [
SearchAppBar( SearchAppBar(
hintText: S.of(context).documentSearchSearchDocuments, hintText: S.of(context).searchDocuments,
onOpenSearch: showDocumentSearchPage, onOpenSearch: showDocumentSearchPage,
), ),
if (state.documents.isEmpty) if (state.documents.isEmpty)
@@ -149,7 +149,8 @@ class _InboxPageState extends State<InboxPage>
SliverToBoxAdapter( SliverToBoxAdapter(
child: HintCard( child: HintCard(
show: !state.isHintAcknowledged, show: !state.isHintAcknowledged,
hintText: S.of(context).inboxPageUsageHintText, hintText:
S.of(context).swipeLeftToMarkADocumentAsSeen,
onHintAcknowledged: () => onHintAcknowledged: () =>
context.read<InboxCubit>().acknowledgeHint(), context.read<InboxCubit>().acknowledgeHint(),
), ),
@@ -177,7 +178,7 @@ class _InboxPageState extends State<InboxPage>
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
).padded(), ).padded(),
Text( Text(
S.of(context).inboxPageMarkAsSeenText, S.of(context).markAsSeen,
style: TextStyle( style: TextStyle(
color: Theme.of(context).colorScheme.primary, color: Theme.of(context).colorScheme.primary,
), ),
@@ -197,21 +198,19 @@ class _InboxPageState extends State<InboxPage>
final isActionConfirmed = await showDialog( final isActionConfirmed = await showDialog(
context: context, context: context,
builder: (context) => AlertDialog( builder: (context) => AlertDialog(
title: Text(S title: Text(S.of(context).markAllAsSeen),
.of(context)
.inboxPageMarkAllAsSeenConfirmationDialogTitleText),
content: Text( content: Text(
S.of(context).inboxPageMarkAllAsSeenConfirmationDialogText, S.of(context).areYouSureYouWantToMarkAllDocumentsAsSeen,
), ),
actions: [ actions: [
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(false), onPressed: () => Navigator.of(context).pop(false),
child: Text(S.of(context).genericActionCancelLabel), child: Text(S.of(context).cancel),
), ),
TextButton( TextButton(
onPressed: () => Navigator.of(context).pop(true), onPressed: () => Navigator.of(context).pop(true),
child: Text( child: Text(
S.of(context).genericActionOkLabel, S.of(context).ok,
style: TextStyle(color: Theme.of(context).colorScheme.error), style: TextStyle(color: Theme.of(context).colorScheme.error),
), ),
), ),
@@ -229,9 +228,9 @@ class _InboxPageState extends State<InboxPage>
final removedTags = await context.read<InboxCubit>().removeFromInbox(doc); final removedTags = await context.read<InboxCubit>().removeFromInbox(doc);
showSnackBar( showSnackBar(
context, context,
S.of(context).inboxPageDocumentRemovedMessageText, S.of(context).removeDocumentFromInbox,
action: SnackBarActionConfig( action: SnackBarActionConfig(
label: S.of(context).inboxPageUndoRemoveText, label: S.of(context).undo,
onPressed: () => _onUndoMarkAsSeen(doc, removedTags), onPressed: () => _onUndoMarkAsSeen(doc, removedTags),
), ),
); );
@@ -268,10 +267,10 @@ class _InboxPageState extends State<InboxPage>
documents, documents,
(doc) { (doc) {
if (doc.added.isToday) { if (doc.added.isToday) {
return S.of(context).inboxPageTodayText; return S.of(context).today;
} }
if (doc.added.isYesterday) { if (doc.added.isYesterday) {
return S.of(context).inboxPageYesterdayText; return S.of(context).yesterday;
} }
return DateFormat.yMMMMd().format(doc.added); return DateFormat.yMMMMd().format(doc.added);
}, },
@@ -23,11 +23,11 @@ class InboxEmptyWidget extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Text(S.of(context).inboxPageNoNewDocumentsText), Text(S.of(context).youDoNotHaveUnseenDocuments),
TextButton( TextButton(
onPressed: () => onPressed: () =>
_emptyStateRefreshIndicatorKey.currentState?.show(), _emptyStateRefreshIndicatorKey.currentState?.show(),
child: Text(S.of(context).inboxPageNoNewDocumentsRefreshLabel), child: Text(S.of(context).refresh),
), ),
], ],
), ),
@@ -99,7 +99,7 @@ class _InboxItemState extends State<InboxItem> {
child: ActionChip( child: ActionChip(
avatar: const Icon(Icons.delete_outline), avatar: const Icon(Icons.delete_outline),
shape: chipShape, shape: chipShape,
label: Text(S.of(context).inboxActionDeleteDocument), label: Text(S.of(context).deleteDocument),
onPressed: () async { onPressed: () async {
final shouldDelete = await showDialog<bool>( final shouldDelete = await showDialog<bool>(
context: context, context: context,
@@ -147,7 +147,7 @@ class _InboxItemState extends State<InboxItem> {
maxWidth: 50, maxWidth: 50,
), ),
child: Text( child: Text(
S.of(context).inboxPageQuickActionsLabel, S.of(context).quickAction,
textAlign: TextAlign.center, textAlign: TextAlign.center,
maxLines: 3, maxLines: 3,
style: Theme.of(context).textTheme.labelSmall, style: Theme.of(context).textTheme.labelSmall,
@@ -190,9 +190,9 @@ class _InboxItemState extends State<InboxItem> {
shape: chipShape, shape: chipShape,
label: hasAsn label: hasAsn
? Text( ? Text(
'${S.of(context).documentArchiveSerialNumberPropertyShortLabel} #${widget.document.archiveSerialNumber}', '${S.of(context).asn} #${widget.document.archiveSerialNumber}',
) )
: Text(S.of(context).inboxActionAssignAsn), : Text(S.of(context).assignASN),
onPressed: !hasAsn onPressed: !hasAsn
? () { ? () {
setState(() { setState(() {
@@ -294,7 +294,7 @@ class _InboxItemState extends State<InboxItem> {
// context, // context,
// S // S
// .of(context) // .of(context)
// .inboxPageSuggestionSuccessfullyAppliedMessage)); // .suggestionSuccessfullyApplied));
// }, // },
// ), // ),
// ) // )
@@ -316,7 +316,7 @@ class _InboxItemState extends State<InboxItem> {
// context, // context,
// S // S
// .of(context) // .of(context)
// .inboxPageSuggestionSuccessfullyAppliedMessage)), // .suggestionSuccessfullyApplied)),
// ), // ),
// ) // )
// .toList(), // .toList(),
@@ -340,7 +340,7 @@ class _InboxItemState extends State<InboxItem> {
// context, // context,
// S // S
// .of(context) // .of(context)
// .inboxPageSuggestionSuccessfullyAppliedMessage)); // .suggestionSuccessfullyApplied));
// }, // },
// ), // ),
// ) // )
@@ -352,7 +352,7 @@ class _InboxItemState extends State<InboxItem> {
// avatar: const Icon(Icons.calendar_today_outlined), // avatar: const Icon(Icons.calendar_today_outlined),
// shape: chipShape, // shape: chipShape,
// label: Text( // label: Text(
// "${S.of(context).documentCreatedPropertyLabel}: ${DateFormat.yMd().format(e)}", // "${S.of(context).createdAt}: ${DateFormat.yMd().format(e)}",
// ), // ),
// onPressed: () => context // onPressed: () => context
// .read<InboxCubit>() // .read<InboxCubit>()
@@ -364,7 +364,7 @@ class _InboxItemState extends State<InboxItem> {
// context, // context,
// S // S
// .of(context) // .of(context)
// .inboxPageSuggestionSuccessfullyAppliedMessage)), // .suggestionSuccessfullyApplied)),
// ), // ),
// ) // )
// .toList(), // .toList(),
@@ -48,7 +48,7 @@ class _StoragePathAutofillFormBuilderFieldState
controller: _textEditingController, controller: _textEditingController,
validator: FormBuilderValidators.required(), //TODO: INTL validator: FormBuilderValidators.required(), //TODO: INTL
decoration: InputDecoration( decoration: InputDecoration(
label: Text(S.of(context).documentStoragePathPropertyLabel), label: Text(S.of(context).storagePath),
suffixIcon: _showClearIcon suffixIcon: _showClearIcon
? IconButton( ? IconButton(
icon: const Icon(Icons.clear), icon: const Icon(Icons.clear),
@@ -69,67 +69,65 @@ class _StoragePathAutofillFormBuilderFieldState
runSpacing: 4.0, runSpacing: 4.0,
children: [ children: [
InputChip( InputChip(
label: Text(S label: Text(S.of(context).archiveSerialNumber),
.of(context)
.documentArchiveSerialNumberPropertyLongLabel),
onPressed: () => _addParameterToInput("{asn}", field), onPressed: () => _addParameterToInput("{asn}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentCorrespondentPropertyLabel), label: Text(S.of(context).correspondent),
onPressed: () => onPressed: () =>
_addParameterToInput("{correspondent}", field), _addParameterToInput("{correspondent}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentDocumentTypePropertyLabel), label: Text(S.of(context).documentType),
onPressed: () => onPressed: () =>
_addParameterToInput("{document_type}", field), _addParameterToInput("{document_type}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentTagsPropertyLabel), label: Text(S.of(context).tags),
onPressed: () => _addParameterToInput("{tag_list}", field), onPressed: () => _addParameterToInput("{tag_list}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentTitlePropertyLabel), label: Text(S.of(context).title),
onPressed: () => _addParameterToInput("{title}", field), onPressed: () => _addParameterToInput("{title}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentCreatedPropertyLabel), label: Text(S.of(context).createdAt),
onPressed: () => _addParameterToInput("{created}", field), onPressed: () => _addParameterToInput("{created}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentCreatedPropertyLabel + label: Text(S.of(context).createdAt +
" (${S.of(context).storagePathParameterYearLabel})"), " (${S.of(context).storagePathYear})"),
onPressed: () => onPressed: () =>
_addParameterToInput("{created_year}", field), _addParameterToInput("{created_year}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentCreatedPropertyLabel + label: Text(S.of(context).createdAt +
" (${S.of(context).storagePathParameterMonthLabel})"), " (${S.of(context).storagePathMonth})"),
onPressed: () => onPressed: () =>
_addParameterToInput("{created_month}", field), _addParameterToInput("{created_month}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentCreatedPropertyLabel + label: Text(S.of(context).createdAt +
" (${S.of(context).storagePathParameterDayLabel})"), " (${S.of(context).storagePathDay})"),
onPressed: () => _addParameterToInput("{created_day}", field), onPressed: () => _addParameterToInput("{created_day}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentCreatedPropertyLabel), label: Text(S.of(context).createdAt),
onPressed: () => _addParameterToInput("{added}", field), onPressed: () => _addParameterToInput("{added}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentCreatedPropertyLabel + label: Text(S.of(context).createdAt +
" (${S.of(context).storagePathParameterYearLabel})"), " (${S.of(context).storagePathYear})"),
onPressed: () => _addParameterToInput("{added_year}", field), onPressed: () => _addParameterToInput("{added_year}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentCreatedPropertyLabel + label: Text(S.of(context).createdAt +
" (${S.of(context).storagePathParameterMonthLabel})"), " (${S.of(context).storagePathMonth})"),
onPressed: () => _addParameterToInput("{added_month}", field), onPressed: () => _addParameterToInput("{added_month}", field),
), ),
InputChip( InputChip(
label: Text(S.of(context).documentCreatedPropertyLabel + label: Text(S.of(context).createdAt +
" (${S.of(context).storagePathParameterDayLabel})"), " (${S.of(context).storagePathDay})"),
onPressed: () => _addParameterToInput("{added_day}", field), onPressed: () => _addParameterToInput("{added_day}", field),
), ),
], ],
@@ -94,8 +94,8 @@ class _TagFormFieldState extends State<TagFormField> {
Icons.label_outline, Icons.label_outline,
), ),
suffixIcon: _buildSuffixIcon(context, field), suffixIcon: _buildSuffixIcon(context, field),
labelText: S.of(context).documentTagsPropertyLabel, labelText: S.of(context).tags,
hintText: S.of(context).tagFormFieldSearchHintText, hintText: S.of(context).filterTags,
), ),
controller: _textEditingController, controller: _textEditingController,
), ),
@@ -138,10 +138,10 @@ class _TagFormFieldState extends State<TagFormField> {
late String? title; late String? title;
switch (data) { switch (data) {
case _onlyNotAssignedId: case _onlyNotAssignedId:
title = S.of(context).labelNotAssignedText; title = S.of(context).notAssigned;
break; break;
case _anyAssignedId: case _anyAssignedId:
title = S.of(context).labelAnyAssignedText; title = S.of(context).anyAssigned;
break; break;
default: default:
title = widget.selectableOptions[data]?.name; title = widget.selectableOptions[data]?.name;
@@ -270,7 +270,7 @@ class _TagFormFieldState extends State<TagFormField> {
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
side: BorderSide.none, side: BorderSide.none,
label: Text( label: Text(
S.of(context).labelNotAssignedText, S.of(context).notAssigned,
), ),
backgroundColor: backgroundColor:
Theme.of(context).colorScheme.onSurface.withOpacity(0.12), Theme.of(context).colorScheme.onSurface.withOpacity(0.12),
@@ -323,7 +323,7 @@ class _TagFormFieldState extends State<TagFormField> {
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
side: BorderSide.none, side: BorderSide.none,
label: Text(S.of(context).labelAnyAssignedText), label: Text(S.of(context).anyAssigned),
backgroundColor: backgroundColor:
Theme.of(context).colorScheme.onSurfaceVariant.withOpacity(0.12), Theme.of(context).colorScheme.onSurfaceVariant.withOpacity(0.12),
onDeleted: () => field.didChange(const IdsTagsQuery()), onDeleted: () => field.didChange(const IdsTagsQuery()),
+17 -25
View File
@@ -72,7 +72,7 @@ class _LabelsPageState extends State<LabelsPage>
context, context,
), ),
sliver: SearchAppBar( sliver: SearchAppBar(
hintText: S.of(context).documentSearchSearchDocuments, hintText: S.of(context).searchDocuments,
onOpenSearch: showDocumentSearchPage, onOpenSearch: showDocumentSearchPage,
bottom: TabBar( bottom: TabBar(
controller: _tabController, controller: _tabController,
@@ -160,12 +160,10 @@ class _LabelsPageState extends State<LabelsPage>
pageSize: label.documentCount ?? 0, pageSize: label.documentCount ?? 0,
), ),
onEdit: _openEditCorrespondentPage, onEdit: _openEditCorrespondentPage,
emptyStateActionButtonLabel: S emptyStateActionButtonLabel:
.of(context) S.of(context).addNewCorrespondent,
.labelsPageCorrespondentEmptyStateAddNewLabel, emptyStateDescription:
emptyStateDescription: S S.of(context).noCorrespondentsSetUp,
.of(context)
.labelsPageCorrespondentEmptyStateDescriptionText,
onAddNew: _openAddCorrespondentPage, onAddNew: _openAddCorrespondentPage,
), ),
], ],
@@ -187,12 +185,10 @@ class _LabelsPageState extends State<LabelsPage>
pageSize: label.documentCount ?? 0, pageSize: label.documentCount ?? 0,
), ),
onEdit: _openEditDocumentTypePage, onEdit: _openEditDocumentTypePage,
emptyStateActionButtonLabel: S emptyStateActionButtonLabel:
.of(context) S.of(context).addNewDocumentType,
.labelsPageDocumentTypeEmptyStateAddNewLabel, emptyStateDescription:
emptyStateDescription: S S.of(context).noDocumentTypesSetUp,
.of(context)
.labelsPageDocumentTypeEmptyStateDescriptionText,
onAddNew: _openAddDocumentTypePage, onAddNew: _openAddDocumentTypePage,
), ),
], ],
@@ -222,12 +218,10 @@ class _LabelsPageState extends State<LabelsPage>
) )
: null, : null,
), ),
emptyStateActionButtonLabel: S emptyStateActionButtonLabel:
.of(context) S.of(context).addNewTag,
.labelsPageTagsEmptyStateAddNewLabel, emptyStateDescription:
emptyStateDescription: S S.of(context).noTagsSetUp,
.of(context)
.labelsPageTagsEmptyStateDescriptionText,
onAddNew: _openAddTagPage, onAddNew: _openAddTagPage,
), ),
], ],
@@ -250,12 +244,10 @@ class _LabelsPageState extends State<LabelsPage>
pageSize: label.documentCount ?? 0, pageSize: label.documentCount ?? 0,
), ),
contentBuilder: (path) => Text(path.path), contentBuilder: (path) => Text(path.path),
emptyStateActionButtonLabel: S emptyStateActionButtonLabel:
.of(context) S.of(context).addNewStoragePath,
.labelsPageStoragePathEmptyStateAddNewLabel, emptyStateDescription:
emptyStateDescription: S S.of(context).noStoragePathsSetUp,
.of(context)
.labelsPageStoragePathEmptyStateDescriptionText,
onAddNew: _openAddStoragePathPage, onAddNew: _openAddStoragePathPage,
), ),
], ],
@@ -79,7 +79,7 @@ class _LabelFormFieldState<T extends Label> extends State<LabelFormField<T>> {
noItemsFoundBuilder: (context) => Padding( noItemsFoundBuilder: (context) => Padding(
padding: const EdgeInsets.symmetric(vertical: 8), padding: const EdgeInsets.symmetric(vertical: 8),
child: Text( child: Text(
S.of(context).labelFormFieldNoItemsFoundText, S.of(context).noItemsFound,
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: style:
TextStyle(color: Theme.of(context).disabledColor, fontSize: 18.0), TextStyle(color: Theme.of(context).disabledColor, fontSize: 18.0),
@@ -97,8 +97,7 @@ class _LabelFormFieldState<T extends Label> extends State<LabelFormField<T>> {
), ),
itemBuilder: (context, suggestion) => ListTile( itemBuilder: (context, suggestion) => ListTile(
title: Text( title: Text(
widget.labelOptions[suggestion.id]?.name ?? widget.labelOptions[suggestion.id]?.name ?? S.of(context).notAssigned,
S.of(context).labelNotAssignedText,
maxLines: 1, maxLines: 1,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@@ -142,7 +141,7 @@ class _LabelFormFieldState<T extends Label> extends State<LabelFormField<T>> {
), ),
selectionToTextTransformer: (suggestion) { selectionToTextTransformer: (suggestion) {
if (suggestion == const IdQueryParameter.notAssigned()) { if (suggestion == const IdQueryParameter.notAssigned()) {
return S.of(context).labelNotAssignedText; return S.of(context).notAssigned;
} }
return widget.labelOptions[suggestion.id]?.name ?? ""; return widget.labelOptions[suggestion.id]?.name ?? "";
}, },
@@ -195,11 +194,11 @@ class _LabelFormFieldState<T extends Label> extends State<LabelFormField<T>> {
String _getLocalizedHint(BuildContext context) { String _getLocalizedHint(BuildContext context) {
if (T == Correspondent) { if (T == Correspondent) {
return S.of(context).correspondentFormFieldSearchHintText; return S.of(context).startTyping;
} else if (T == DocumentType) { } else if (T == DocumentType) {
return S.of(context).documentTypeFormFieldSearchHintText; return S.of(context).startTyping;
} else { } else {
return S.of(context).tagFormFieldSearchHintText; return S.of(context).filterTags;
} }
} }
} }
@@ -24,7 +24,7 @@ class _LinkedDocumentsPageState extends State<LinkedDocumentsPage>
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(S.of(context).linkedDocumentsPageTitle), title: Text(S.of(context).linkedDocuments),
actions: [ actions: [
BlocBuilder<LinkedDocumentsCubit, LinkedDocumentsState>( BlocBuilder<LinkedDocumentsCubit, LinkedDocumentsState>(
builder: (context, state) { builder: (context, state) {
@@ -40,9 +40,7 @@ class _ClientCertificateFormFieldState
} }
assert(_selectedFile != null); assert(_selectedFile != null);
if (_selectedFile?.path.split(".").last != 'pfx') { if (_selectedFile?.path.split(".").last != 'pfx') {
return S return S.of(context).invalidCertificateFormat;
.of(context)
.loginPageClientCertificateSettingInvalidFileFormatValidationText;
} }
return null; return null;
}, },
@@ -52,9 +50,8 @@ class _ClientCertificateFormFieldState
return Theme( return Theme(
data: theme, data: theme,
child: ExpansionTile( child: ExpansionTile(
title: Text(S.of(context).loginPageClientCertificateSettingLabel), title: Text(S.of(context).clientcertificate),
subtitle: Text( subtitle: Text(S.of(context).configureMutualTLSAuthentication),
S.of(context).loginPageClientCertificateSettingDescriptionText),
children: [ children: [
InputDecorator( InputDecorator(
decoration: InputDecoration( decoration: InputDecoration(
@@ -70,8 +67,7 @@ class _ClientCertificateFormFieldState
children: [ children: [
ElevatedButton( ElevatedButton(
onPressed: () => _onSelectFile(field), onPressed: () => _onSelectFile(field),
child: child: Text(S.of(context).select),
Text(S.of(context).genericActionSelectText),
), ),
_buildSelectedFileText(field).paddedOnly(left: 8), _buildSelectedFileText(field).paddedOnly(left: 8),
], ],
@@ -89,7 +85,7 @@ class _ClientCertificateFormFieldState
// ListTile( // ListTile(
// leading: ElevatedButton( // leading: ElevatedButton(
// onPressed: () => _onSelectFile(field), // onPressed: () => _onSelectFile(field),
// child: Text(S.of(context).genericActionSelectText), // child: Text(S.of(context).select),
// ), // ),
// title: _buildSelectedFileText(field), // title: _buildSelectedFileText(field),
// trailing: AbsorbPointer( // trailing: AbsorbPointer(
@@ -112,9 +108,7 @@ class _ClientCertificateFormFieldState
onChanged: (value) => field.didChange( onChanged: (value) => field.didChange(
field.value?.copyWith(passphrase: value), field.value?.copyWith(passphrase: value),
), ),
label: S label: S.of(context).passphrase,
.of(context)
.loginPageClientCertificatePassphraseLabel,
).padded(), ).padded(),
] else ] else
...[] ...[]
@@ -149,7 +143,7 @@ class _ClientCertificateFormFieldState
if (field.value == null) { if (field.value == null) {
assert(_selectedFile == null); assert(_selectedFile == null);
return Text( return Text(
S.of(context).loginPageClientCertificateSettingSelectFileText, S.of(context).selectFile,
style: Theme.of(context).textTheme.labelMedium?.apply( style: Theme.of(context).textTheme.labelMedium?.apply(
color: Theme.of(context).hintColor, color: Theme.of(context).hintColor,
), ),
@@ -44,18 +44,16 @@ class _ServerAddressFormFieldState extends State<ServerAddressFormField> {
autovalidateMode: AutovalidateMode.onUserInteraction, autovalidateMode: AutovalidateMode.onUserInteraction,
validator: FormBuilderValidators.compose([ validator: FormBuilderValidators.compose([
FormBuilderValidators.required( FormBuilderValidators.required(
errorText: errorText: S.of(context).serverAddressMustNotBeEmpty,
S.of(context).loginPageServerUrlValidatorMessageRequiredText,
), ),
FormBuilderValidators.match( FormBuilderValidators.match(
r"https?://.*", r"https?://.*",
errorText: errorText: S.of(context).serverAddressMustIncludeAScheme,
S.of(context).loginPageServerUrlValidatorMessageMissingSchemeText,
) )
]), ]),
decoration: InputDecoration( decoration: InputDecoration(
hintText: "http://192.168.1.50:8000", hintText: "http://192.168.1.50:8000",
labelText: S.of(context).loginPageServerUrlFieldLabel, labelText: S.of(context).serverAddress,
suffixIcon: _canClear suffixIcon: _canClear
? IconButton( ? IconButton(
icon: const Icon(Icons.clear), icon: const Icon(Icons.clear),
@@ -37,22 +37,22 @@ class _UserCredentialsFormFieldState extends State<UserCredentialsFormField> {
UserCredentials(username: username), UserCredentials(username: username),
), ),
validator: FormBuilderValidators.required( validator: FormBuilderValidators.required(
errorText: S.of(context).loginPageUsernameValidatorMessageText, errorText: S.of(context).usernameMustNotBeEmpty,
), ),
autofillHints: const [AutofillHints.username], autofillHints: const [AutofillHints.username],
decoration: InputDecoration( decoration: InputDecoration(
label: Text(S.of(context).loginPageUsernameLabel), label: Text(S.of(context).username),
), ),
), ),
ObscuredInputTextFormField( ObscuredInputTextFormField(
key: const ValueKey('login-password'), key: const ValueKey('login-password'),
label: S.of(context).loginPagePasswordFieldLabel, label: S.of(context).password,
onChanged: (password) => field.didChange( onChanged: (password) => field.didChange(
field.value?.copyWith(password: password) ?? field.value?.copyWith(password: password) ??
UserCredentials(password: password), UserCredentials(password: password),
), ),
validator: FormBuilderValidators.required( validator: FormBuilderValidators.required(
errorText: S.of(context).loginPagePasswordValidatorMessageText, errorText: S.of(context).passwordMustNotBeEmpty,
), ),
), ),
].map((child) => child.padded()).toList(), ].map((child) => child.padded()).toList(),
@@ -73,11 +73,11 @@ class _UserCredentialsFormFieldState extends State<UserCredentialsFormField> {
FocusScope.of(context).requestFocus(_focusNodes[fkPassword]); FocusScope.of(context).requestFocus(_focusNodes[fkPassword]);
}, },
validator: FormBuilderValidators.required( validator: FormBuilderValidators.required(
errorText: S.of(context).loginPageUsernameValidatorMessageText, errorText: S.of(context).usernameMustNotBeEmpty,
), ),
autofillHints: const [AutofillHints.username], autofillHints: const [AutofillHints.username],
decoration: InputDecoration( decoration: InputDecoration(
labelText: S.of(context).loginPageUsernameLabel, labelText: S.of(context).username,
), ),
).padded(), ).padded(),
FormBuilderTextField( FormBuilderTextField(
@@ -88,11 +88,11 @@ class _UserCredentialsFormFieldState extends State<UserCredentialsFormField> {
}, },
autofillHints: const [AutofillHints.password], autofillHints: const [AutofillHints.password],
validator: FormBuilderValidators.required( validator: FormBuilderValidators.required(
errorText: S.of(context).loginPagePasswordValidatorMessageText, errorText: S.of(context).passwordMustNotBeEmpty,
), ),
obscureText: true, obscureText: true,
decoration: InputDecoration( decoration: InputDecoration(
labelText: S.of(context).loginPagePasswordFieldLabel, labelText: S.of(context).password,
), ),
).padded(), ).padded(),
], ],
@@ -32,7 +32,7 @@ class _ServerConnectionPageState extends State<ServerConnectionPage> {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
toolbarHeight: kToolbarHeight - 4, toolbarHeight: kToolbarHeight - 4,
title: Text(S.of(context).loginPageTitle), title: Text(S.of(context).connectToPaperless),
bottom: PreferredSize( bottom: PreferredSize(
child: _isCheckingConnection child: _isCheckingConnection
? const LinearProgressIndicator() ? const LinearProgressIndicator()
@@ -61,11 +61,11 @@ class _ServerConnectionPageState extends State<ServerConnectionPage> {
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
TextButton( TextButton(
child: Text("Test connection"), child: Text("Test connection"), //TODO: INTL
onPressed: _updateReachability, onPressed: _updateReachability,
), ),
FilledButton( FilledButton(
child: Text(S.of(context).loginPageContinueLabel), child: Text(S.of(context).continueLabel),
onPressed: _reachabilityStatus == ReachabilityStatus.reachable onPressed: _reachabilityStatus == ReachabilityStatus.reachable
? widget.onContinue ? widget.onContinue
: null, : null,
@@ -108,19 +108,19 @@ class _ServerConnectionPageState extends State<ServerConnectionPage> {
case ReachabilityStatus.reachable: case ReachabilityStatus.reachable:
return _buildIconText( return _buildIconText(
Icons.done, Icons.done,
S.of(context).loginPageReachabilitySuccessText, S.of(context).connectionSuccessfulylEstablished,
Colors.green, Colors.green,
); );
case ReachabilityStatus.notReachable: case ReachabilityStatus.notReachable:
return _buildIconText( return _buildIconText(
Icons.close, Icons.close,
S.of(context).loginPageReachabilityNotReachableText, S.of(context).couldNotEstablishConnectionToTheServer,
errorColor, errorColor,
); );
case ReachabilityStatus.unknownHost: case ReachabilityStatus.unknownHost:
return _buildIconText( return _buildIconText(
Icons.close, Icons.close,
S.of(context).loginPageReachabilityUnresolvedHostText, S.of(context).hostCouldNotBeResolved,
errorColor, errorColor,
); );
case ReachabilityStatus.missingClientCertificate: case ReachabilityStatus.missingClientCertificate:
@@ -132,15 +132,13 @@ class _ServerConnectionPageState extends State<ServerConnectionPage> {
case ReachabilityStatus.invalidClientCertificateConfiguration: case ReachabilityStatus.invalidClientCertificateConfiguration:
return _buildIconText( return _buildIconText(
Icons.close, Icons.close,
S S.of(context).incorrectOrMissingCertificatePassphrase,
.of(context)
.loginPageReachabilityInvalidClientCertificateConfigurationText,
errorColor, errorColor,
); );
case ReachabilityStatus.connectionTimeout: case ReachabilityStatus.connectionTimeout:
return _buildIconText( return _buildIconText(
Icons.close, Icons.close,
S.of(context).loginPageReachabilityConnectionTimeoutText, S.of(context).connectionTimedOut,
errorColor, errorColor,
); );
} }
@@ -39,8 +39,7 @@ class _ServerLoginPageState extends State<ServerLoginPage> {
), ),
body: ListView( body: ListView(
children: [ children: [
Text(S.of(context).loginPageSignInToPrefixText(serverAddress)) Text(S.of(context).signInToServer(serverAddress)).padded(),
.padded(),
const UserCredentialsFormField(), const UserCredentialsFormField(),
], ],
), ),
@@ -54,7 +53,7 @@ class _ServerLoginPageState extends State<ServerLoginPage> {
await widget.onDone(); await widget.onDone();
setState(() => _isLoginLoading = false); setState(() => _isLoginLoading = false);
}, },
child: Text(S.of(context).loginPageSignInButtonLabel), child: Text(S.of(context).signIn),
) )
], ],
), ),
@@ -25,12 +25,12 @@ class _AddSavedViewPageState extends State<AddSavedViewPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(S.of(context).savedViewCreateNewLabel), title: Text(S.of(context).newView),
), ),
floatingActionButton: FloatingActionButton.extended( floatingActionButton: FloatingActionButton.extended(
icon: const Icon(Icons.add), icon: const Icon(Icons.add),
onPressed: () => _onCreate(context), onPressed: () => _onCreate(context),
label: Text(S.of(context).genericActionCreateLabel), label: Text(S.of(context).create),
), ),
body: Padding( body: Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
@@ -46,18 +46,18 @@ class _AddSavedViewPageState extends State<AddSavedViewPage> {
name: _AddSavedViewPageState.fkName, name: _AddSavedViewPageState.fkName,
validator: FormBuilderValidators.required(), validator: FormBuilderValidators.required(),
decoration: InputDecoration( decoration: InputDecoration(
label: Text(S.of(context).savedViewNameLabel), label: Text(S.of(context).name),
), ),
), ),
FormBuilderCheckbox( FormBuilderCheckbox(
name: _AddSavedViewPageState.fkShowOnDashboard, name: _AddSavedViewPageState.fkShowOnDashboard,
initialValue: false, initialValue: false,
title: Text(S.of(context).savedViewShowOnDashboardLabel), title: Text(S.of(context).showOnDashboard),
), ),
FormBuilderCheckbox( FormBuilderCheckbox(
name: _AddSavedViewPageState.fkShowInSidebar, name: _AddSavedViewPageState.fkShowInSidebar,
initialValue: false, initialValue: false,
title: Text(S.of(context).savedViewShowInSidebarLabel), title: Text(S.of(context).showInSidebar),
), ),
], ],
), ),
@@ -94,18 +94,18 @@ class _AddSavedViewPageState extends State<AddSavedViewPage> {
name: fkName, name: fkName,
validator: FormBuilderValidators.required(), validator: FormBuilderValidators.required(),
decoration: InputDecoration( decoration: InputDecoration(
label: Text(S.of(context).savedViewNameLabel), label: Text(S.of(context).name),
), ),
), ),
FormBuilderCheckbox( FormBuilderCheckbox(
name: fkShowOnDashboard, name: fkShowOnDashboard,
initialValue: false, initialValue: false,
title: Text(S.of(context).savedViewShowOnDashboardLabel), title: Text(S.of(context).showOnDashboard),
), ),
FormBuilderCheckbox( FormBuilderCheckbox(
name: fkShowInSidebar, name: fkShowInSidebar,
initialValue: false, initialValue: false,
title: Text(S.of(context).savedViewShowInSidebarLabel), title: Text(S.of(context).showInSidebar),
), ),
], ],
), ),
@@ -20,7 +20,8 @@ class SavedViewList extends StatelessWidget {
if (state.value.isEmpty) { if (state.value.isEmpty) {
return SliverToBoxAdapter( return SliverToBoxAdapter(
child: HintCard( child: HintCard(
hintText: S.of(context).savedViewsEmptyStateText, hintText:
S.of(context).createViewsToQuicklyFilterYourDocuments,
), ),
); );
} }
@@ -32,9 +33,7 @@ class SavedViewList extends StatelessWidget {
enabled: connectivity.isConnected, enabled: connectivity.isConnected,
title: Text(view.name), title: Text(view.name),
subtitle: Text( subtitle: Text(
S S.of(context).nFiltersSet(view.filterRules.length),
.of(context)
.savedViewsFiltersSetCount(view.filterRules.length),
), ),
onTap: () { onTap: () {
Navigator.of(context).push( Navigator.of(context).push(
@@ -24,7 +24,7 @@ class AccountSettingsDialog extends StatelessWidget {
title: Row( title: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text(S.of(context).accountSettingsTitle), Text(S.of(context).account),
const CloseButton(), const CloseButton(),
], ],
), ),
@@ -49,7 +49,7 @@ class AccountSettingsDialog extends StatelessWidget {
ListTile( ListTile(
dense: true, dense: true,
leading: const Icon(Icons.person_add_rounded), leading: const Icon(Icons.person_add_rounded),
title: Text(S.of(context).accountSettingsAddAnotherAccount), title: Text(S.of(context).addAnotherAccount),
onTap: () {}, onTap: () {},
), ),
const Divider(), const Divider(),
@@ -60,7 +60,7 @@ class AccountSettingsDialog extends StatelessWidget {
), ),
), ),
child: Text( child: Text(
S.of(context).appDrawerLogoutLabel, S.of(context).disconnect,
style: TextStyle( style: TextStyle(
color: Theme.of(context).colorScheme.onError, color: Theme.of(context).colorScheme.onError,
), ),
@@ -15,7 +15,7 @@ class ApplicationSettingsPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(S.of(context).settingsPageApplicationSettingsLabel), title: Text(S.of(context).applicationSettings),
), ),
body: ListView( body: ListView(
children: const [ children: const [
@@ -8,8 +8,7 @@ class SecuritySettingsPage extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: appBar: AppBar(title: Text(S.of(context).security)),
AppBar(title: Text(S.of(context).settingsPageSecuritySettingsLabel)),
body: ListView( body: ListView(
children: const [ children: const [
BiometricAuthenticationSetting(), BiometricAuthenticationSetting(),
@@ -9,7 +9,7 @@ class StorageSettingsPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(S.of(context).settingsPageStorageSettingsLabel), title: Text(S.of(context).storage),
), ),
body: ListView( body: ListView(
children: const [ children: const [
+9 -15
View File
@@ -5,7 +5,6 @@ import 'package:paperless_mobile/core/bloc/paperless_server_information_state.da
import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart'; import 'package:paperless_mobile/features/settings/cubit/application_settings_cubit.dart';
import 'package:paperless_mobile/features/settings/view/pages/application_settings_page.dart'; import 'package:paperless_mobile/features/settings/view/pages/application_settings_page.dart';
import 'package:paperless_mobile/features/settings/view/pages/security_settings_page.dart'; import 'package:paperless_mobile/features/settings/view/pages/security_settings_page.dart';
import 'package:paperless_mobile/features/settings/view/pages/storage_settings_page.dart';
import 'package:paperless_mobile/generated/l10n.dart'; import 'package:paperless_mobile/generated/l10n.dart';
class SettingsPage extends StatelessWidget { class SettingsPage extends StatelessWidget {
@@ -15,24 +14,21 @@ class SettingsPage extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
appBar: AppBar( appBar: AppBar(
title: Text(S.of(context).appDrawerSettingsLabel), title: Text(S.of(context).settings),
), ),
bottomNavigationBar: BlocBuilder<PaperlessServerInformationCubit, bottomNavigationBar: BlocBuilder<PaperlessServerInformationCubit,
PaperlessServerInformationState>( PaperlessServerInformationState>(
builder: (context, state) { builder: (context, state) {
final info = state.information!; final info = state.information!;
return ListTile( return ListTile(
title: Text( title: Text(
S.of(context).appDrawerHeaderLoggedInAsText + S.of(context).loggedInAs(info.username ?? 'unknown') +
" " +
(info.username ?? 'unknown') +
"@${info.host}", "@${info.host}",
style: Theme.of(context).textTheme.labelSmall, style: Theme.of(context).textTheme.labelSmall,
textAlign: TextAlign.center, textAlign: TextAlign.center,
), ),
subtitle: Text( subtitle: Text(
S.of(context).serverInformationPaperlessVersionText + S.of(context).paperlessServerVersion +
' ' + ' ' +
info.version.toString() + info.version.toString() +
' (API v${info.apiVersion})', ' (API v${info.apiVersion})',
@@ -46,23 +42,21 @@ class SettingsPage extends StatelessWidget {
children: [ children: [
ListTile( ListTile(
// leading: const Icon(Icons.style_outlined), // leading: const Icon(Icons.style_outlined),
title: Text(S.of(context).settingsPageApplicationSettingsLabel), title: Text(S.of(context).applicationSettings),
subtitle: Text( subtitle: Text(S.of(context).languageAndVisualAppearance),
S.of(context).settingsPageApplicationSettingsDescriptionText),
onTap: () => _goto(const ApplicationSettingsPage(), context), onTap: () => _goto(const ApplicationSettingsPage(), context),
), ),
ListTile( ListTile(
// leading: const Icon(Icons.security_outlined), // leading: const Icon(Icons.security_outlined),
title: Text(S.of(context).settingsPageSecuritySettingsLabel), title: Text(S.of(context).security),
subtitle: subtitle: Text(S.of(context).biometricAuthentication),
Text(S.of(context).settingsPageSecuritySettingsDescriptionText),
onTap: () => _goto(const SecuritySettingsPage(), context), onTap: () => _goto(const SecuritySettingsPage(), context),
), ),
// ListTile( // ListTile(
// // leading: const Icon(Icons.storage_outlined), // // leading: const Icon(Icons.storage_outlined),
// title: Text(S.of(context).settingsPageStorageSettingsLabel), // title: Text(S.of(context).storage),
// subtitle: // subtitle:
// Text(S.of(context).settingsPageStorageSettingsDescriptionText), // Text(S.of(context).mangeFilesAndStorageSpace),
// onTap: () => _goto(const StorageSettingsPage(), context), // onTap: () => _goto(const StorageSettingsPage(), context),
// ), // ),
], ],
@@ -12,21 +12,19 @@ class BiometricAuthenticationSetting extends StatelessWidget {
builder: (context, settings) { builder: (context, settings) {
return SwitchListTile( return SwitchListTile(
value: settings.isLocalAuthenticationEnabled, value: settings.isLocalAuthenticationEnabled,
title: Text(S.of(context).appSettingsBiometricAuthenticationLabel), title: Text(S.of(context).biometricAuthentication),
subtitle: Text( subtitle: Text(S.of(context).authenticateOnAppStart),
S.of(context).appSettingsBiometricAuthenticationDescriptionText),
onChanged: (val) async { onChanged: (val) async {
final String localizedReason = val final String localizedReason =
? S S.of(context).authenticateToToggleBiometricAuthentication(
.of(context) val ? 'enable' : 'disable',
.appSettingsEnableBiometricAuthenticationReasonText );
: S
.of(context)
.appSettingsDisableBiometricAuthenticationReasonText;
await context await context
.read<ApplicationSettingsCubit>() .read<ApplicationSettingsCubit>()
.setIsBiometricAuthenticationEnabled(val, .setIsBiometricAuthenticationEnabled(
localizedReason: localizedReason); val,
localizedReason: localizedReason,
);
}, },
); );
}, },
@@ -18,7 +18,7 @@ class ColorSchemeOptionSetting extends StatelessWidget {
return BlocBuilder<ApplicationSettingsCubit, ApplicationSettingsState>( return BlocBuilder<ApplicationSettingsCubit, ApplicationSettingsState>(
builder: (context, settings) { builder: (context, settings) {
return ListTile( return ListTile(
title: Text(S.of(context).settingsPageColorSchemeSettingLabel), title: Text(S.of(context).colors),
subtitle: Text( subtitle: Text(
translateColorSchemeOption( translateColorSchemeOption(
context, context,
@@ -28,9 +28,8 @@ class ColorSchemeOptionSetting extends StatelessWidget {
onTap: () => showDialog( onTap: () => showDialog(
context: context, context: context,
builder: (_) => RadioSettingsDialog<ColorSchemeOption>( builder: (_) => RadioSettingsDialog<ColorSchemeOption>(
titleText: S.of(context).settingsPageColorSchemeSettingLabel, titleText: S.of(context).colors,
descriptionText: descriptionText: S.of(context).colorSchemeHint,
S.of(context).settingsPageColorSchemeSettingDialogDescription,
options: [ options: [
RadioOption( RadioOption(
value: ColorSchemeOption.classic, value: ColorSchemeOption.classic,
@@ -47,9 +46,7 @@ class ColorSchemeOptionSetting extends StatelessWidget {
], ],
footer: _isBelowAndroid12() footer: _isBelowAndroid12()
? HintCard( ? HintCard(
hintText: S hintText: S.of(context).colorSchemeNotSupportedWarning,
.of(context)
.settingsPageColorSchemeSettingDynamicThemeingVersionMismatchWarning,
hintIcon: Icons.warning_amber, hintIcon: Icons.warning_amber,
) )
: null, : null,
@@ -25,7 +25,7 @@ class _LanguageSelectionSettingState extends State<LanguageSelectionSetting> {
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).language),
subtitle: Text(_languageOptions[settings.preferredLocaleSubtag]!), subtitle: Text(_languageOptions[settings.preferredLocaleSubtag]!),
onTap: () => showDialog<String>( onTap: () => showDialog<String>(
context: context, context: context,
@@ -33,7 +33,7 @@ class _LanguageSelectionSettingState extends State<LanguageSelectionSetting> {
footer: const Text( footer: const Text(
"* Work in progress, not fully translated yet. Some words may be displayed in English!", "* Work in progress, not fully translated yet. Some words may be displayed in English!",
), ),
titleText: S.of(context).settingsPageLanguageSettingLabel, titleText: S.of(context).language,
options: [ options: [
RadioOption( RadioOption(
value: 'en', value: 'en',
@@ -41,11 +41,11 @@ class _RadioSettingsDialogState<T> extends State<RadioSettingsDialog<T>> {
widget.confirmButton ?? widget.confirmButton ??
TextButton( TextButton(
onPressed: () => Navigator.pop(context), onPressed: () => Navigator.pop(context),
child: Text(S.of(context).genericActionCancelLabel)), child: Text(S.of(context).cancel)),
widget.confirmButton ?? widget.confirmButton ??
TextButton( TextButton(
onPressed: () => Navigator.pop(context, _groupValue), onPressed: () => Navigator.pop(context, _groupValue),
child: Text(S.of(context).genericActionOkLabel)), child: Text(S.of(context).ok)),
], ],
title: widget.titleText != null ? Text(widget.titleText!) : null, title: widget.titleText != null ? Text(widget.titleText!) : null,
content: Column( content: Column(
@@ -12,13 +12,13 @@ class ThemeModeSetting extends StatelessWidget {
return BlocBuilder<ApplicationSettingsCubit, ApplicationSettingsState>( return BlocBuilder<ApplicationSettingsCubit, ApplicationSettingsState>(
builder: (context, settings) { builder: (context, settings) {
return ListTile( return ListTile(
title: Text(S.of(context).settingsPageAppearanceSettingTitle), title: Text(S.of(context).appearance),
subtitle: Text(_mapThemeModeToLocalizedString( subtitle: Text(_mapThemeModeToLocalizedString(
settings.preferredThemeMode, context)), settings.preferredThemeMode, context)),
onTap: () => showDialog<ThemeMode>( onTap: () => showDialog<ThemeMode>(
context: context, context: context,
builder: (_) => RadioSettingsDialog<ThemeMode>( builder: (_) => RadioSettingsDialog<ThemeMode>(
titleText: S.of(context).settingsPageAppearanceSettingTitle, titleText: S.of(context).appearance,
initialValue: context initialValue: context
.read<ApplicationSettingsCubit>() .read<ApplicationSettingsCubit>()
.state .state
@@ -26,20 +26,15 @@ class ThemeModeSetting extends StatelessWidget {
options: [ options: [
RadioOption( RadioOption(
value: ThemeMode.system, value: ThemeMode.system,
label: S label: S.of(context).systemTheme,
.of(context)
.settingsPageAppearanceSettingSystemThemeLabel,
), ),
RadioOption( RadioOption(
value: ThemeMode.light, value: ThemeMode.light,
label: S label: S.of(context).lightTheme,
.of(context)
.settingsPageAppearanceSettingLightThemeLabel,
), ),
RadioOption( RadioOption(
value: ThemeMode.dark, value: ThemeMode.dark,
label: label: S.of(context).darkTheme,
S.of(context).settingsPageAppearanceSettingDarkThemeLabel,
) )
], ],
), ),
@@ -56,11 +51,11 @@ class ThemeModeSetting extends StatelessWidget {
String _mapThemeModeToLocalizedString(ThemeMode theme, BuildContext context) { String _mapThemeModeToLocalizedString(ThemeMode theme, BuildContext context) {
switch (theme) { switch (theme) {
case ThemeMode.system: case ThemeMode.system:
return S.of(context).settingsThemeModeSystemLabel; return S.of(context).system;
case ThemeMode.light: case ThemeMode.light:
return S.of(context).settingsThemeModeLightLabel; return S.of(context).light;
case ThemeMode.dark: case ThemeMode.dark:
return S.of(context).settingsThemeModeDarkLabel; return S.of(context).dark;
} }
} }
} }
+1 -1
View File
@@ -68,7 +68,7 @@ void showGenericError(
context, context,
error.toString(), error.toString(),
action: SnackBarActionConfig( action: SnackBarActionConfig(
label: S.of(context).errorReportLabel, label: S.of(context).report,
onPressed: () => GithubIssueService.createIssueFromError( onPressed: () => GithubIssueService.createIssueFromError(
context, context,
stackTrace: stackTrace, stackTrace: stackTrace,
+558 -620
View File
File diff suppressed because it is too large Load Diff
+564 -622
View File
File diff suppressed because it is too large Load Diff
+633 -622
View File
File diff suppressed because it is too large Load Diff
+564 -622
View File
File diff suppressed because it is too large Load Diff
+566 -622
View File
File diff suppressed because it is too large Load Diff