Files
BadNote/lib/l10n/app_localizations.dart
Akiba So 2f0fda5f95
All checks were successful
CI / Windows build (push) Successful in 14m14s
feat(import): one Import-file entry + vault notebooks
Phase 3. Import becomes a single top-level action beside "Create
notebook" and the library is vault-backed.

- VaultService.createNotebook copies a picked file into a fresh
  (de-duplicated) notebook folder under the vault; its sidecar lives
  beside it, so annotations travel with the file.
- Home screen: one "Import file" action with a multi-extension picker
  (pdf / docx / pptx); routes to the editor by extension.
- The document list is now a vault scan (folders with a source file),
  not the SQLite documents table — no cache, always correct.
- PPTX soffice detection fix; DOCX convert-on-import is best-effort
  and fails gracefully when LibreOffice is unavailable.

analyze clean, tests green.
2026-06-24 21:12:38 +08:00

735 lines
20 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;
import 'app_localizations_en.dart';
import 'app_localizations_zh.dart';
// ignore_for_file: type=lint
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'l10n/app_localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
/// # Internationalization support.
/// flutter_localizations:
/// sdk: flutter
/// intl: any # Use the pinned version from flutter_localizations
///
/// # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, youll need to edit this
/// file.
///
/// First, open your projects ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// projects Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale)
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations)!;
}
static const LocalizationsDelegate<AppLocalizations> delegate =
_AppLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
///
/// Returns a list of localizations delegates containing this delegate along with
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
/// and GlobalWidgetsLocalizations.delegate.
///
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
<LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
];
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('en'),
Locale('zh'),
];
/// No description provided for @appTitle.
///
/// In en, this message translates to:
/// **'BadNote'**
String get appTitle;
/// No description provided for @settings.
///
/// In en, this message translates to:
/// **'Settings'**
String get settings;
/// No description provided for @search.
///
/// In en, this message translates to:
/// **'Search'**
String get search;
/// No description provided for @importPdf.
///
/// In en, this message translates to:
/// **'Import PDF'**
String get importPdf;
/// No description provided for @importPpt.
///
/// In en, this message translates to:
/// **'Import PPT'**
String get importPpt;
/// No description provided for @importFile.
///
/// In en, this message translates to:
/// **'Import file'**
String get importFile;
/// No description provided for @createNotebook.
///
/// In en, this message translates to:
/// **'Create notebook'**
String get createNotebook;
/// No description provided for @noDocumentsYet.
///
/// In en, this message translates to:
/// **'No documents yet — tap Import file'**
String get noDocumentsYet;
/// No description provided for @processingImport.
///
/// In en, this message translates to:
/// **'Importing…'**
String get processingImport;
/// No description provided for @importFailed.
///
/// In en, this message translates to:
/// **'Couldn\'t import that file: {error}'**
String importFailed(String error);
/// No description provided for @convertNeedsLibreOffice.
///
/// In en, this message translates to:
/// **'Importing Word documents needs LibreOffice installed. Convert to PDF first, or install LibreOffice.'**
String get convertNeedsLibreOffice;
/// No description provided for @unsupportedFileType.
///
/// In en, this message translates to:
/// **'Unsupported file type: {ext}'**
String unsupportedFileType(String ext);
/// No description provided for @penCanvasBeta.
///
/// In en, this message translates to:
/// **'Pen Canvas (beta)'**
String get penCanvasBeta;
/// No description provided for @newNote.
///
/// In en, this message translates to:
/// **'New Note'**
String get newNote;
/// No description provided for @open.
///
/// In en, this message translates to:
/// **'Open'**
String get open;
/// No description provided for @cancel.
///
/// In en, this message translates to:
/// **'Cancel'**
String get cancel;
/// No description provided for @delete.
///
/// In en, this message translates to:
/// **'Delete'**
String get delete;
/// No description provided for @deleteNoteTitle.
///
/// In en, this message translates to:
/// **'Delete note?'**
String get deleteNoteTitle;
/// No description provided for @deleteNote.
///
/// In en, this message translates to:
/// **'Delete note'**
String get deleteNote;
/// No description provided for @openInSplitView.
///
/// In en, this message translates to:
/// **'Open in Split View'**
String get openInSplitView;
/// No description provided for @splitViewSubtitle.
///
/// In en, this message translates to:
/// **'PDF reference + scratchpad'**
String get splitViewSubtitle;
/// No description provided for @removeDocument.
///
/// In en, this message translates to:
/// **'Remove document'**
String get removeDocument;
/// No description provided for @ok.
///
/// In en, this message translates to:
/// **'OK'**
String get ok;
/// No description provided for @pickColor.
///
/// In en, this message translates to:
/// **'Pick a color'**
String get pickColor;
/// No description provided for @clearSettingsTitle.
///
/// In en, this message translates to:
/// **'Clear all local settings?'**
String get clearSettingsTitle;
/// No description provided for @clear.
///
/// In en, this message translates to:
/// **'Clear'**
String get clear;
/// No description provided for @settingsReset.
///
/// In en, this message translates to:
/// **'Settings reset to defaults'**
String get settingsReset;
/// No description provided for @themeSystem.
///
/// In en, this message translates to:
/// **'System'**
String get themeSystem;
/// No description provided for @themeLight.
///
/// In en, this message translates to:
/// **'Light'**
String get themeLight;
/// No description provided for @themeDark.
///
/// In en, this message translates to:
/// **'Dark'**
String get themeDark;
/// No description provided for @seedColorDesc.
///
/// In en, this message translates to:
/// **'Seed color for Material 3 theme'**
String get seedColorDesc;
/// No description provided for @searchHint.
///
/// In en, this message translates to:
/// **'Search notes and documents...'**
String get searchHint;
/// No description provided for @searchError.
///
/// In en, this message translates to:
/// **'Search error: {error}'**
String searchError(String error);
/// No description provided for @noResultsFor.
///
/// In en, this message translates to:
/// **'No results for \"{query}\"'**
String noResultsFor(String query);
/// No description provided for @typeToSearch.
///
/// In en, this message translates to:
/// **'Type to search your notes and documents'**
String get typeToSearch;
/// No description provided for @sectionNotes.
///
/// In en, this message translates to:
/// **'Notes'**
String get sectionNotes;
/// No description provided for @sectionDocuments.
///
/// In en, this message translates to:
/// **'Documents'**
String get sectionDocuments;
/// No description provided for @pageLabel.
///
/// In en, this message translates to:
/// **'Page {page}'**
String pageLabel(int page);
/// No description provided for @processingPptx.
///
/// In en, this message translates to:
/// **'Processing PPTX...'**
String get processingPptx;
/// No description provided for @processingPresentation.
///
/// In en, this message translates to:
/// **'Processing presentation...'**
String get processingPresentation;
/// No description provided for @couldNotOpenPresentation.
///
/// In en, this message translates to:
/// **'Could not open presentation.'**
String get couldNotOpenPresentation;
/// No description provided for @toolPen.
///
/// In en, this message translates to:
/// **'Pen'**
String get toolPen;
/// No description provided for @toolHighlighter.
///
/// In en, this message translates to:
/// **'Highlighter'**
String get toolHighlighter;
/// No description provided for @toolEraser.
///
/// In en, this message translates to:
/// **'Eraser'**
String get toolEraser;
/// No description provided for @brushPicker.
///
/// In en, this message translates to:
/// **'Brush'**
String get brushPicker;
/// No description provided for @brushFountainPen.
///
/// In en, this message translates to:
/// **'Fountain pen'**
String get brushFountainPen;
/// No description provided for @brushBallpoint.
///
/// In en, this message translates to:
/// **'Ballpoint'**
String get brushBallpoint;
/// No description provided for @brushPencil.
///
/// In en, this message translates to:
/// **'Pencil'**
String get brushPencil;
/// No description provided for @brushHighlighter.
///
/// In en, this message translates to:
/// **'Highlighter'**
String get brushHighlighter;
/// No description provided for @toolSelect.
///
/// In en, this message translates to:
/// **'Select'**
String get toolSelect;
/// No description provided for @toolShape.
///
/// In en, this message translates to:
/// **'Shape'**
String get toolShape;
/// No description provided for @shapePicker.
///
/// In en, this message translates to:
/// **'Shape'**
String get shapePicker;
/// No description provided for @shapeLine.
///
/// In en, this message translates to:
/// **'Line'**
String get shapeLine;
/// No description provided for @shapeRectangle.
///
/// In en, this message translates to:
/// **'Rectangle'**
String get shapeRectangle;
/// No description provided for @shapeEllipse.
///
/// In en, this message translates to:
/// **'Ellipse'**
String get shapeEllipse;
/// No description provided for @shapeArrow.
///
/// In en, this message translates to:
/// **'Arrow'**
String get shapeArrow;
/// No description provided for @actionDeleteSelection.
///
/// In en, this message translates to:
/// **'Delete selection'**
String get actionDeleteSelection;
/// No description provided for @actionUndo.
///
/// In en, this message translates to:
/// **'Undo'**
String get actionUndo;
/// No description provided for @actionRedo.
///
/// In en, this message translates to:
/// **'Redo'**
String get actionRedo;
/// No description provided for @fingerDrawingOn.
///
/// In en, this message translates to:
/// **'Finger drawing ON'**
String get fingerDrawingOn;
/// No description provided for @fingerDrawingOff.
///
/// In en, this message translates to:
/// **'Finger drawing OFF (pen only)'**
String get fingerDrawingOff;
/// No description provided for @pages.
///
/// In en, this message translates to:
/// **'Pages'**
String get pages;
/// No description provided for @penSettings.
///
/// In en, this message translates to:
/// **'Pen settings'**
String get penSettings;
/// No description provided for @inputDiagnostic.
///
/// In en, this message translates to:
/// **'Input diagnostic (writes a log file)'**
String get inputDiagnostic;
/// No description provided for @back.
///
/// In en, this message translates to:
/// **'Back'**
String get back;
/// No description provided for @previousPage.
///
/// In en, this message translates to:
/// **'Previous page'**
String get previousPage;
/// No description provided for @nextPage.
///
/// In en, this message translates to:
/// **'Next page'**
String get nextPage;
/// No description provided for @toolSelectText.
///
/// In en, this message translates to:
/// **'Select text'**
String get toolSelectText;
/// No description provided for @actionHighlightSelection.
///
/// In en, this message translates to:
/// **'Highlight selection'**
String get actionHighlightSelection;
/// No description provided for @toolRemoveHighlight.
///
/// In en, this message translates to:
/// **'Remove highlight (tap a highlight)'**
String get toolRemoveHighlight;
/// No description provided for @toolPlaceScratchLink.
///
/// In en, this message translates to:
/// **'Place scratch link'**
String get toolPlaceScratchLink;
/// No description provided for @scratchLinkDeleteTitle.
///
/// In en, this message translates to:
/// **'Delete scratch link?'**
String get scratchLinkDeleteTitle;
/// No description provided for @scratchLinkDeleteBody.
///
/// In en, this message translates to:
/// **'This removes the anchor and its private scratchpad.'**
String get scratchLinkDeleteBody;
/// No description provided for @failedToOpenPdf.
///
/// In en, this message translates to:
/// **'Failed to open PDF:\n{error}'**
String failedToOpenPdf(String error);
/// No description provided for @pdfNoPages.
///
/// In en, this message translates to:
/// **'PDF has no pages.'**
String get pdfNoPages;
/// No description provided for @pageOfPages.
///
/// In en, this message translates to:
/// **'{current} / {total}'**
String pageOfPages(int current, int total);
/// No description provided for @board.
///
/// In en, this message translates to:
/// **'Board'**
String get board;
/// No description provided for @boardTitle.
///
/// In en, this message translates to:
/// **'Sticky Board'**
String get boardTitle;
/// No description provided for @boardOpen.
///
/// In en, this message translates to:
/// **'Sticky note board'**
String get boardOpen;
/// No description provided for @boardAddCard.
///
/// In en, this message translates to:
/// **'Add card'**
String get boardAddCard;
/// No description provided for @boardNewCardText.
///
/// In en, this message translates to:
/// **'New note'**
String get boardNewCardText;
/// No description provided for @boardDeleteCard.
///
/// In en, this message translates to:
/// **'Delete card'**
String get boardDeleteCard;
/// No description provided for @boardDeleteCardTitle.
///
/// In en, this message translates to:
/// **'Delete this card?'**
String get boardDeleteCardTitle;
/// No description provided for @boardBacklinks.
///
/// In en, this message translates to:
/// **'Linked from'**
String get boardBacklinks;
/// No description provided for @boardNoBacklinks.
///
/// In en, this message translates to:
/// **'Nothing links here yet'**
String get boardNoBacklinks;
/// No description provided for @boardDanglingLink.
///
/// In en, this message translates to:
/// **'No card named \"{target}\"'**
String boardDanglingLink(String target);
/// No description provided for @close.
///
/// In en, this message translates to:
/// **'Close'**
String get close;
/// No description provided for @vaultSetupTitle.
///
/// In en, this message translates to:
/// **'Choose your vault'**
String get vaultSetupTitle;
/// No description provided for @vaultSetupHeadline.
///
/// In en, this message translates to:
/// **'Pick a folder for your notebooks'**
String get vaultSetupHeadline;
/// No description provided for @vaultSetupBody.
///
/// In en, this message translates to:
/// **'BadNote stores your notebooks inside one folder you choose — like an Obsidian vault. Pick a folder you control (e.g. a synced folder) so your notes travel with their files.'**
String get vaultSetupBody;
/// No description provided for @vaultChooseFolder.
///
/// In en, this message translates to:
/// **'Choose folder'**
String get vaultChooseFolder;
/// No description provided for @vaultMissingTitle.
///
/// In en, this message translates to:
/// **'Your vault folder is missing'**
String get vaultMissingTitle;
/// No description provided for @vaultMissingBody.
///
/// In en, this message translates to:
/// **'The folder you picked can\'t be found (it may have been moved, deleted, or on a drive that\'s unplugged). Relocate it or pick a new one.'**
String get vaultMissingBody;
/// No description provided for @vaultPickFailed.
///
/// In en, this message translates to:
/// **'Couldn\'t open the folder picker: {error}'**
String vaultPickFailed(String error);
/// No description provided for @vaultNotWritable.
///
/// In en, this message translates to:
/// **'That folder isn\'t writable. Please choose another.'**
String get vaultNotWritable;
/// No description provided for @vaultSection.
///
/// In en, this message translates to:
/// **'Vault'**
String get vaultSection;
/// No description provided for @vaultFolderLabel.
///
/// In en, this message translates to:
/// **'Vault folder'**
String get vaultFolderLabel;
/// No description provided for @vaultNoneSelected.
///
/// In en, this message translates to:
/// **'No folder selected'**
String get vaultNoneSelected;
/// No description provided for @vaultChangeFolder.
///
/// In en, this message translates to:
/// **'Change vault folder'**
String get vaultChangeFolder;
/// No description provided for @vaultUpdated.
///
/// In en, this message translates to:
/// **'Vault folder updated'**
String get vaultUpdated;
}
class _AppLocalizationsDelegate
extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
}
@override
bool isSupported(Locale locale) =>
<String>['en', 'zh'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'en':
return AppLocalizationsEn();
case 'zh':
return AppLocalizationsZh();
}
throw FlutterError(
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.',
);
}