worldhopper/lib/l10n/app_localizations_en.dart
Felipe M. bb579719f9
All checks were successful
ci/woodpecker/pr/pr Pipeline was successful
fix: prevent double-save on exit, surface KOReader sync auth failures
- Add guard flag to prevent both onPopInvokedWithResult and dispose()
  from saving progress (double DB writes + double sync pushes)
- Capture ref-dependent values synchronously in _saveProgress before
  any await to prevent accessing disposed ref after super.dispose()
- Guard ref.invalidate() calls with mounted check for dispose safety
- Add KoreaderSyncAuthException so 401 errors in getProgress and
  updateProgress propagate instead of being silently swallowed
- Show a warning snackbar (once per session) when auth fails so the
  user knows sync credentials need updating

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 00:12:06 +01:00

854 lines
19 KiB
Dart

// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get appName => 'Worldhopper';
@override
String get navLibrary => 'Library';
@override
String get navServers => 'Servers';
@override
String get navSettings => 'Settings';
@override
String get settingsTitle => 'Settings';
@override
String get settingsAppearance => 'Appearance';
@override
String get settingsAppearanceSubtitle => 'Display options';
@override
String get settingsLanguage => 'Language';
@override
String get settingsLanguageSubtitle => 'App language';
@override
String get settingsReaders => 'Readers';
@override
String get settingsReadersSubtitle => 'Reader options';
@override
String get settingsAdvanced => 'Advanced';
@override
String get settingsAdvancedSubtitle => 'Developer and debugging';
@override
String get settingsAbout => 'About';
@override
String get settingsAboutSubtitle => 'Worldhopper';
@override
String get appearanceTitle => 'Appearance';
@override
String get appearanceTheme => 'Theme';
@override
String get themeLight => 'Light';
@override
String get themeDark => 'Dark';
@override
String get themeSystem => 'System';
@override
String get themeSystemSubtitle => 'Follow device theme';
@override
String get languageTitle => 'Language';
@override
String get languageSystem => 'System default';
@override
String get languageSystemSubtitle => 'Use device language';
@override
String get readersTitle => 'Readers';
@override
String get readersGeneralSection => 'General';
@override
String get readersEinkMode => 'E-ink mode';
@override
String get readersEinkModeSubtitle => 'Disable animations for e-ink displays';
@override
String get readersImageReaderSection => 'Image Reader';
@override
String get readersReadingDirection => 'Reading direction';
@override
String get readersFilterQuality => 'Filter quality';
@override
String get readersPrecachePages => 'Pre-cache pages';
@override
String get readersTwoPageSpread => 'Two-page spread';
@override
String get readersTwoPageSpreadSubtitle =>
'Show two pages side by side on wide screens';
@override
String get readersFirstPageIsCover => 'First page is cover';
@override
String get readersFirstPageIsCoverSubtitle =>
'Show the first page alone in two-page spread';
@override
String get readingDirectionTitle => 'Reading Direction';
@override
String get readingModeLtr => 'Left to right';
@override
String get readingModeLtrDescription => 'Standard Western reading order';
@override
String get readingModeRtl => 'Right to left';
@override
String get readingModeRtlDescription => 'Manga-style reading order';
@override
String get readingModeVertical => 'Vertical scroll';
@override
String get readingModeVerticalDescription =>
'Continuous webtoon-style scrolling';
@override
String get readingDirectionHelp =>
'Controls the reading direction for the image reader. Left to right is standard for Western comics, right to left for manga, and vertical scroll for webtoons.';
@override
String get readingModeShortLtr => 'LTR';
@override
String get readingModeShortRtl => 'RTL';
@override
String get readingModeShortVertical => 'Vertical';
@override
String get filterQualityTitle => 'Filter Quality';
@override
String get filterQualityNone => 'None';
@override
String get filterQualityNoneDescription => 'Fastest, may look pixelated';
@override
String get filterQualityLow => 'Low';
@override
String get filterQualityLowDescription => 'Bilinear interpolation';
@override
String get filterQualityMedium => 'Medium';
@override
String get filterQualityMediumDescription =>
'Bilinear with mipmaps, good balance';
@override
String get filterQualityHigh => 'High';
@override
String get filterQualityHighDescription =>
'Bicubic interpolation, best quality';
@override
String get filterQualityHelp =>
'Controls how images are scaled when a page is zoomed out to fit the screen. Higher quality makes text and fine details sharper but uses more GPU resources. Medium is recommended for most devices.';
@override
String get precachePagesTitle => 'Pre-cache Pages';
@override
String get precachePagesOff => 'Off';
@override
String get precachePagesOffDescription => 'Pages load on demand';
@override
String get precachePages1 => '1 page';
@override
String get precachePages1Description => 'Minimal pre-loading';
@override
String get precachePages2 => '2 pages';
@override
String get precachePages2Description => 'Light pre-loading';
@override
String get precachePages3 => '3 pages';
@override
String get precachePages3Description => 'Balanced, recommended';
@override
String get precachePages4 => '4 pages';
@override
String get precachePages4Description => 'Aggressive pre-loading';
@override
String get precachePages5 => '5 pages';
@override
String get precachePages5Description =>
'Maximum pre-loading, uses more bandwidth';
@override
String get precachePagesHelp =>
'Controls how many upcoming pages are pre-loaded in the background while reading. Higher values make swiping feel more seamless but use more bandwidth and memory.';
@override
String get advancedTitle => 'Advanced';
@override
String get advancedDeveloperMode => 'Developer mode';
@override
String get advancedDeveloperModeSubtitle => 'Enable debugging tools';
@override
String get advancedTests => 'Tests';
@override
String get advancedTestsSubtitle => 'Preview UI components';
@override
String get advancedDebuggingInfo => 'Debugging info';
@override
String get advancedVersion => 'Version';
@override
String get advancedBuildNumber => 'Build number';
@override
String get advancedPackageName => 'Package name';
@override
String get advancedDatabaseVersion => 'Database version';
@override
String get advancedPlatform => 'Platform';
@override
String get advancedCopyToClipboard => 'Copy to clipboard';
@override
String get advancedCopyToClipboardSubtitle =>
'Copy all debug info for bug reports';
@override
String get advancedDebugInfoCopied => 'Debug info copied to clipboard';
@override
String get advancedFailedToLoadInfo => 'Failed to load info';
@override
String get aboutTitle => 'About';
@override
String get aboutVersion => 'Version';
@override
String get aboutVersionUnknown => 'unknown';
@override
String get aboutSourceCode => 'Source code';
@override
String get aboutReportIssue => 'Report an issue';
@override
String get aboutReportIssueSubtitle => 'Open an issue on the repository';
@override
String get devTestsTitle => 'Dev Tests';
@override
String get devTestsSnackBars => 'Snack Bars';
@override
String get devTestsSuccess => 'Success';
@override
String get devTestsError => 'Error';
@override
String get devTestsWarning => 'Warning';
@override
String get devTestsInfo => 'Info';
@override
String get devTestsSuccessMessage => 'This is a success message';
@override
String get devTestsErrorMessage => 'This is an error message';
@override
String get devTestsWarningMessage => 'This is a warning message';
@override
String get devTestsInfoMessage => 'This is an info message';
@override
String get serverListTitle => 'My Servers';
@override
String get serverListEmpty => 'No Servers Yet';
@override
String get serverListEmptySubtitle =>
'Add your first OPDS server to start browsing and reading';
@override
String get serverListOffline =>
'You are offline. Connect to the internet to browse servers.';
@override
String serverListErrorLoading(String error) {
return 'Error loading servers: $error';
}
@override
String get serverListRetry => 'Retry';
@override
String get serverListAddServer => 'Add Server';
@override
String get serverDeleteTitle => 'Delete Server';
@override
String serverDeleteConfirmation(String name) {
return 'Are you sure you want to delete \"$name\"?';
}
@override
String serverDeleted(String name) {
return '$name deleted';
}
@override
String get addServerTitle => 'Add Server';
@override
String get addServerNameLabel => 'Server Name';
@override
String get addServerNameHint => 'My Library';
@override
String get addServerUrlLabel => 'Server URL';
@override
String get addServerUrlHint => 'https://example.com/opds';
@override
String get addServerRequiresAuth => 'Requires Authentication';
@override
String get addServerRequiresAuthSubtitle => 'Enable if server requires login';
@override
String get addServerUsername => 'Username';
@override
String get addServerPassword => 'Password';
@override
String get addServerValidationNameRequired => 'Please enter a server name';
@override
String get addServerValidationUrlRequired => 'Please enter a server URL';
@override
String get addServerValidationUrlInvalid => 'Please enter a valid URL';
@override
String get addServerValidationUrlScheme =>
'URL must start with http:// or https://';
@override
String get addServerValidationUsernameRequired => 'Please enter a username';
@override
String get addServerValidationPasswordRequired => 'Please enter a password';
@override
String get addServerHelp =>
'Enter the root URL of your OPDS server. Credentials will be securely stored on your device.';
@override
String get addServerButton => 'Add Server';
@override
String get addServerDuplicate => 'A server with this URL already exists';
@override
String addServerSuccess(String name) {
return '$name added successfully';
}
@override
String addServerError(String error) {
return 'Error adding server: $error';
}
@override
String get koreaderSyncToggle => 'KOReader API Sync';
@override
String get koreaderSyncToggleSubtitle =>
'Sync EPUB reading progress with a KOReader-compatible server';
@override
String get koreaderSyncUrl => 'Sync Server URL';
@override
String get koreaderSyncUrlHint => 'https://sync.example.com';
@override
String get koreaderSyncUsername => 'Sync Username';
@override
String get koreaderSyncPassword => 'Sync Password';
@override
String get koreaderSyncTestConnection => 'Test Connection';
@override
String koreaderSyncTestSuccess(String username) {
return 'Connection successful! Authenticated as $username.';
}
@override
String koreaderSyncTestFailed(String error) {
return 'Connection failed: $error';
}
@override
String get koreaderSyncValidationUrlRequired =>
'Sync server URL is required when KOReader sync is enabled';
@override
String get koreaderSyncValidationUrlInvalid => 'Please enter a valid URL';
@override
String get koreaderSyncValidationUsernameRequired =>
'Sync username is required';
@override
String get koreaderSyncValidationPasswordRequired =>
'Sync password is required';
@override
String get koreaderSyncAuthFailed =>
'KOReader sync: authentication failed. Check your server credentials.';
@override
String get koreaderSyncHelp =>
'Connect to a KOReader-compatible sync server to synchronize EPUB reading positions across devices.';
@override
String get koreaderSyncResumeInfo =>
'KOReader sync is enabled. Your reading position will be automatically restored from the sync server when you open this book.';
@override
String get editServerTitle => 'Edit Server';
@override
String get editServerNotFound => 'Server not found';
@override
String get editServerInfo => 'Server Information';
@override
String get editServerAdded => 'Added';
@override
String get editServerLastSynced => 'Last Synced';
@override
String get editServerSaveButton => 'Save Changes';
@override
String editServerSuccess(String name) {
return '$name updated successfully';
}
@override
String editServerError(String error) {
return 'Error updating server: $error';
}
@override
String editServerErrorLoading(String error) {
return 'Error loading server: $error';
}
@override
String get readerError => 'Error';
@override
String get readerNoStreamLink =>
'This publication cannot be read (no stream link)';
@override
String get readerServerNotFound => 'Server not found';
@override
String readerErrorLoadingServer(String error) {
return 'Error loading server: $error';
}
@override
String readerReadingDirectionWithMode(String mode) {
return 'Reading direction ($mode)';
}
@override
String readerPageOf(int current, int total) {
return 'Page $current of $total';
}
@override
String readerPagesOf(int start, int end, int total) {
return 'Pages $start-$end of $total';
}
@override
String get epubPreparing => 'Preparing...';
@override
String get epubLoadingFromCache => 'Loading from cache...';
@override
String epubDownloading(int percent) {
return 'Downloading... $percent%';
}
@override
String get epubProcessing => 'Processing EPUB...';
@override
String get epubOpeningReader => 'Opening reader...';
@override
String epubErrorLoading(String error) {
return 'Error loading EPUB: $error';
}
@override
String get epubGoBack => 'Go Back';
@override
String get epubSearch => 'Search';
@override
String get epubSearchHint => 'Enter search term...';
@override
String get epubNoResults => 'No results found';
@override
String epubSearchResults(int count, String query) {
return '$count results for \"$query\"';
}
@override
String epubSearchFailed(String error) {
return 'Search failed: $error';
}
@override
String get epubChapters => 'Chapters';
@override
String get epubBack => 'Back';
@override
String get libraryTitle => 'Library';
@override
String get libraryRecentlyRead => 'Recently Read';
@override
String get libraryNoServers => 'No Servers Configured';
@override
String get libraryNoServersSubtitle =>
'Add an OPDS server to start reading books';
@override
String get libraryAddServer => 'Add Server';
@override
String get libraryNoHistory => 'No Reading History';
@override
String get libraryNoHistorySubtitle => 'Start reading a book to see it here';
@override
String get libraryBrowseServers => 'Browse Servers';
@override
String get libraryErrorLoading => 'Error Loading Library';
@override
String get browserLoading => 'Loading...';
@override
String get browserLibrary => 'Library';
@override
String get browserNoContent => 'No Content Available';
@override
String get browserLibraryEmpty => 'This library appears to be empty';
@override
String get browserCollectionEmpty => 'This collection appears to be empty';
@override
String get browserFailedToLoadLibrary => 'Failed to Load Library';
@override
String get browserFailedToLoadFeed => 'Failed to Load Feed';
@override
String get browserRetry => 'Retry';
@override
String browserFailedToLoadMore(String error) {
return 'Failed to load more: $error';
}
@override
String get browserOfflineEpubNotCached =>
'This EPUB is not cached. You may not be able to read it offline.';
@override
String get browserOfflinePagesWarning =>
'You are offline. Pages may not load properly.';
@override
String publicationPages(int count) {
return '$count pages';
}
@override
String get publicationReadingProgress => 'Reading Progress';
@override
String publicationPageOfTotal(int current, int total) {
return 'Page $current of $total';
}
@override
String publicationLastRead(String time) {
return 'Last read: $time';
}
@override
String get publicationCannotRead =>
'This publication cannot be read in the app';
@override
String publicationContinueFromPage(int page) {
return 'Continue reading from page $page';
}
@override
String get publicationStartReading => 'Start Reading';
@override
String get publicationContinueReading => 'Continue Reading';
@override
String get publicationReadAgain => 'Read Again';
@override
String get publicationStartFromBeginning => 'Start from Beginning';
@override
String get publicationCollection => 'Collection';
@override
String get recentlyReadPublicationNotFound => 'Publication not found';
@override
String get recentlyReadErrorLoading => 'Error loading publication';
@override
String get recentlyReadViewRawData => 'View raw data';
@override
String get recentlyReadRemove => 'Remove from Recently Read';
@override
String get recentlyReadRemoveTitle => 'Remove from Recently Read';
@override
String recentlyReadRemoveConfirmation(String title) {
return 'Remove \"$title\" from your reading history?\n\nThis will not delete the book from your library.';
}
@override
String get recentlyReadRemoved => 'Removed from Recently Read';
@override
String recentlyReadRemoveFailed(String error) {
return 'Failed to remove: $error';
}
@override
String get recentlyReadRawData => 'Raw Data';
@override
String get recentlyReadOfflineEpubNotCached =>
'This EPUB is not cached. Connect to internet to download.';
@override
String get recentlyReadOfflinePagesWarning =>
'You are offline. Pages may not load.';
@override
String get recentlyReadUnsupportedFormat => 'Unsupported format';
@override
String get serverCardEdit => 'Edit';
@override
String get serverCardDelete => 'Delete';
@override
String get serverCardAuthenticated => 'Authenticated';
@override
String serverCardLastSynced(String time) {
return 'Last synced: $time';
}
@override
String get offlineSemanticLabel => 'Offline';
@override
String get nextInSeriesNext => 'Next';
@override
String get nextInSeriesFinished => 'Finished';
@override
String get nextInSeriesBackToDetails => 'Back to details';
@override
String get nextInSeriesBackToLibrary => 'Back to library';
@override
String routeNotFound(String uri) {
return 'Page not found: $uri';
}
@override
String get commonCancel => 'Cancel';
@override
String get commonDelete => 'Delete';
@override
String get commonRemove => 'Remove';
@override
String get timeJustNow => 'just now';
@override
String timeMinutesAgo(int minutes) {
return '${minutes}m ago';
}
@override
String timeHoursAgo(int hours) {
return '${hours}h ago';
}
@override
String timeDaysAgo(int days) {
return '${days}d ago';
}
@override
String timeWeeksAgo(int weeks) {
return '${weeks}w ago';
}
@override
String timeMonthsAgo(int months) {
return '${months}mo ago';
}
@override
String timeYearsAgo(int years) {
return '${years}y ago';
}
@override
String get timeToday => 'Today';
@override
String get timeYesterday => 'Yesterday';
@override
String timeMinAgo(int minutes) {
return '$minutes min ago';
}
@override
String timeHoursAgoLong(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'hours',
one: 'hour',
);
return '$count $_temp0 ago';
}
@override
String timeDaysAgoLong(int days) {
return '$days days ago';
}
}