From 2f3ffe72dd486f835f1973830906de57d54b7a23 Mon Sep 17 00:00:00 2001 From: markm39 Date: Sun, 30 Aug 2026 09:32:45 -0500 Subject: [PATCH] feat(i18n): localize the editor; bump to 1.3 (build 10) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extends the string catalogs with editor and tools sections in all 13 languages: header status line (Page X of Y / saving / saved / failed), the unreadable-note recovery screen, start-blank and save-failed dialogs, export errors, insert-image menu, background sheet, page sidebar and toolbar accessibility labels, text box placeholders, and tool names. New notes are created with a localized default title, and BACKGROUND_LABELS is removed in favor of the catalog. Bumps the app to 1.3 (build 10) across app.json, build.gradle, project.pbxproj, and Info.plist for the release carrying iCloud backup, the onboarding backup choice, and localization. Verified on iPad simulator in German end to end: create-note sheet (Blanko/Liniert/Kariert/Gepunktet/Millimeterpapier), editor header 'Seite 1 von 1 · bereit', back button 'Bibliothek', default title 'Ohne Titel'. Typecheck enforces catalog completeness; 43/43 tests; Metro export bundles. Claude-Session: https://claude.ai/code/session_01YM3PBapEXHwuXY97Bibsqk --- android/app/build.gradle | 4 +- app.json | 6 +- app/note/[id].tsx | 48 ++++++++-------- ios/OpenNotes.xcodeproj/project.pbxproj | 8 +-- ios/OpenNotes/Info.plist | 4 +- src/components/editor/BackgroundSheet.tsx | 7 ++- src/components/editor/EditorHeader.tsx | 19 ++++--- src/components/editor/FloatingToolbar.tsx | 7 ++- src/components/editor/PageSidebar.tsx | 9 +-- src/components/editor/TextBoxOverlay.tsx | 5 +- src/components/editor/ToolSettingsPopover.tsx | 3 +- src/i18n/locales/de.ts | 55 +++++++++++++++++++ src/i18n/locales/en.ts | 55 +++++++++++++++++++ src/i18n/locales/es.ts | 55 +++++++++++++++++++ src/i18n/locales/fr.ts | 55 +++++++++++++++++++ src/i18n/locales/it.ts | 55 +++++++++++++++++++ src/i18n/locales/ja.ts | 55 +++++++++++++++++++ src/i18n/locales/ko.ts | 55 +++++++++++++++++++ src/i18n/locales/nl.ts | 55 +++++++++++++++++++ src/i18n/locales/pt.ts | 55 +++++++++++++++++++ src/i18n/locales/ru.ts | 55 +++++++++++++++++++ src/i18n/locales/zhHans.ts | 54 ++++++++++++++++++ src/i18n/locales/zhHant.ts | 54 ++++++++++++++++++ src/services/notesRepo.ts | 5 +- src/types/note.ts | 9 --- src/utils/toolPalette.ts | 17 +++--- 26 files changed, 733 insertions(+), 76 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 812ff60..38d5d1b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -92,8 +92,8 @@ android { applicationId 'com.builderpro.opennotes' minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 9 - versionName "1.2" + versionCode 10 + versionName "1.3" buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\"" } diff --git a/app.json b/app.json index b301c97..6aa3f65 100644 --- a/app.json +++ b/app.json @@ -2,7 +2,7 @@ "expo": { "name": "OpenNotes", "slug": "open-notes", - "version": "1.2", + "version": "1.3", "scheme": "opennotes", "orientation": "default", "icon": "./assets/icon.png", @@ -16,7 +16,7 @@ "ios": { "bundleIdentifier": "com.builderpro.opennotes", "icon": "./assets/icon.png", - "buildNumber": "9", + "buildNumber": "10", "supportsTablet": true, "usesIcloudStorage": true, "entitlements": { @@ -65,7 +65,7 @@ }, "android": { "package": "com.builderpro.opennotes", - "versionCode": 9, + "versionCode": 10, "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png", "backgroundColor": "#F7F7F4" diff --git a/app/note/[id].tsx b/app/note/[id].tsx index f92eb9c..de495e3 100644 --- a/app/note/[id].tsx +++ b/app/note/[id].tsx @@ -63,6 +63,7 @@ import { exportNotebookAsPdf } from '../../src/services/exportService'; import { recordSuccessfulNoteSave } from '../../src/services/lifecycleService'; import { textBoxId, insertedElementId } from '../../src/utils/id'; import { spacing } from '../../src/theme/spacing'; +import { t } from '../../src/i18n'; import { typography } from '../../src/theme/typography'; import type { NoteMetadata } from '../../src/types/note'; import type { ToolDescriptor } from '../../src/utils/toolPalette'; @@ -335,12 +336,12 @@ export default function NoteScreen() { const startBlankAfterLoadFailure = useCallback(() => { Alert.alert( - 'Start with a blank note?', - 'The existing contents of this note could not be read. Starting blank will replace them the next time the note saves.', + t.editor.startBlankTitle, + t.editor.startBlankBody, [ - { text: 'Cancel', style: 'cancel' }, + { text: t.common.cancel, style: 'cancel' }, { - text: 'Start blank', + text: t.editor.startBlankConfirm, style: 'destructive', onPress: () => { setBodyLoadFailed(false); @@ -715,13 +716,13 @@ export default function NoteScreen() { }); if (!result.ok) { Alert.alert( - 'Export failed', - result.error ?? 'Could not generate a PDF. Please try again.', + t.editor.exportFailedTitle, + result.error ?? t.editor.exportFailedBody, ); } } catch (error) { if (__DEV__) console.warn('[NoteScreen] export failed', error); - Alert.alert('Export failed', 'Could not generate a PDF. Please try again.'); + Alert.alert(t.editor.exportFailedTitle, t.editor.exportFailedBody); } finally { if (isMountedRef.current) setIsExporting(false); } @@ -757,17 +758,17 @@ export default function NoteScreen() { return; } Alert.alert( - "Couldn't save your note", - 'Your latest changes could not be written to storage. Leaving now will discard them.', + t.editor.saveFailedTitle, + t.editor.saveFailedBody, [ - { text: 'Try again', onPress: () => void attempt() }, + { text: t.editor.tryAgain, onPress: () => void attempt() }, { - text: 'Leave anyway', + text: t.editor.leaveAnyway, style: 'destructive', onPress: () => navigateHome(), }, { - text: 'Stay', + text: t.editor.stay, style: 'cancel', onPress: () => { exitRef.current = 'editing'; @@ -829,7 +830,7 @@ export default function NoteScreen() { ]} > - Couldn't open this note + {t.editor.couldNotOpenTitle} - The note's contents could not be read from storage. Nothing has been - changed; your data is still on this device. + {t.editor.couldNotOpenBody} - Try again + {t.editor.tryAgain} void handleBack()} style={[styles.errorButton, { backgroundColor: theme.colors.surfaceMuted }]} > - Back to library + {t.editor.backToLibrary} - Start with a blank note + {t.editor.startBlankLink} @@ -881,7 +881,7 @@ export default function NoteScreen() { return ( void handleInsertFromLibrary(), }, { key: 'camera', - label: 'Take Photo', + label: t.editor.takePhoto, onPress: () => void handleInsertFromCamera(), }, ]} @@ -1004,9 +1004,9 @@ export default function NoteScreen() { setAction(null)} onConfirm={(value) => void handleRename(value)} /> diff --git a/ios/OpenNotes.xcodeproj/project.pbxproj b/ios/OpenNotes.xcodeproj/project.pbxproj index a0fc9d0..da39e3b 100644 --- a/ios/OpenNotes.xcodeproj/project.pbxproj +++ b/ios/OpenNotes.xcodeproj/project.pbxproj @@ -364,7 +364,7 @@ CODE_SIGN_ENTITLEMENTS = OpenNotes/OpenNotes.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 9; + CURRENT_PROJECT_VERSION = 10; DEVELOPMENT_TEAM = U2CPXQV7AJ; ENABLE_BITCODE = NO; GCC_PREPROCESSOR_DEFINITIONS = ( @@ -377,7 +377,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2; + MARKETING_VERSION = 1.3; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -403,7 +403,7 @@ CODE_SIGN_ENTITLEMENTS = OpenNotes/OpenNotes.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 9; + CURRENT_PROJECT_VERSION = 10; DEVELOPMENT_TEAM = U2CPXQV7AJ; INFOPLIST_FILE = OpenNotes/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 15.1; @@ -411,7 +411,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.2; + MARKETING_VERSION = 1.3; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", diff --git a/ios/OpenNotes/Info.plist b/ios/OpenNotes/Info.plist index 807a1f7..a41742e 100644 --- a/ios/OpenNotes/Info.plist +++ b/ios/OpenNotes/Info.plist @@ -34,7 +34,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.2 + 1.3 CFBundleSignature ???? CFBundleURLTypes @@ -54,7 +54,7 @@ CFBundleVersion - 9 + 10 ITSAppUsesNonExemptEncryption LSMinimumSystemVersion diff --git a/src/components/editor/BackgroundSheet.tsx b/src/components/editor/BackgroundSheet.tsx index 214cbbc..5790ad2 100644 --- a/src/components/editor/BackgroundSheet.tsx +++ b/src/components/editor/BackgroundSheet.tsx @@ -5,8 +5,9 @@ import { Sheet } from '../ui/Sheet'; import { useTheme } from '../../hooks/useTheme'; import { radius, spacing } from '../../theme/spacing'; import { typography } from '../../theme/typography'; -import { BACKGROUND_LABELS, BACKGROUND_TYPES } from '../../types/note'; +import { BACKGROUND_TYPES } from '../../types/note'; import type { BackgroundType } from '../../types/note'; +import { t } from '../../i18n'; export interface BackgroundSheetProps { visible: boolean; @@ -34,7 +35,7 @@ export function BackgroundSheet({ return ( - Background + {t.editor.backgroundTitle} {BACKGROUND_TYPES.map((type) => { @@ -70,7 +71,7 @@ export function BackgroundSheet({ }, ]} > - {BACKGROUND_LABELS[type]} + {t.library.backgrounds[type]} ); diff --git a/src/components/editor/EditorHeader.tsx b/src/components/editor/EditorHeader.tsx index 521b85d..aa14a69 100644 --- a/src/components/editor/EditorHeader.tsx +++ b/src/components/editor/EditorHeader.tsx @@ -6,6 +6,7 @@ import { useTheme } from '../../hooks/useTheme'; import { spacing } from '../../theme/spacing'; import { typography } from '../../theme/typography'; import type { AutosaveStatus } from '../../hooks/useAutosave'; +import { t } from '../../i18n'; export const EDITOR_HEADER_BAR_HEIGHT = 48; @@ -54,7 +55,7 @@ export function EditorHeader({ style={({ pressed }) => [styles.sideButton, pressed && { opacity: 0.5 }]} > - Library + {t.library.backLabel} - Page {currentPage + 1} of {pageCount} · {statusLabel(status)} + {t.editor.pageStatus(currentPage + 1, pageCount, statusLabel(status))} diff --git a/src/components/editor/PageSidebar.tsx b/src/components/editor/PageSidebar.tsx index 46970b9..70b01a2 100644 --- a/src/components/editor/PageSidebar.tsx +++ b/src/components/editor/PageSidebar.tsx @@ -14,6 +14,7 @@ import type { NotebookPage } from '@mathnotes/mobile-ink'; import { useTheme } from '../../hooks/useTheme'; import { radius, spacing } from '../../theme/spacing'; import { typography } from '../../theme/typography'; +import { t } from '../../i18n'; const SIDEBAR_WIDTH = 136; const THUMBNAIL_WIDTH = 78; @@ -81,7 +82,7 @@ export function PageSidebar({ @@ -103,7 +104,7 @@ export function PageSidebar({ [styles.closeButton, pressed && { opacity: 0.5 }]} @@ -114,7 +115,7 @@ export function PageSidebar({ jumpToPageNumber(index + 1)} style={({ pressed }) => [ styles.thumbButton, diff --git a/src/components/editor/TextBoxOverlay.tsx b/src/components/editor/TextBoxOverlay.tsx index 56ab2cf..887a696 100644 --- a/src/components/editor/TextBoxOverlay.tsx +++ b/src/components/editor/TextBoxOverlay.tsx @@ -21,6 +21,7 @@ import Animated, { } from 'react-native-reanimated'; import type { InkTextBox } from '@mathnotes/mobile-ink'; import { useTheme } from '../../hooks/useTheme'; +import { t } from '../../i18n'; const MIN_WIDTH = 200; const MIN_HEIGHT = 100; @@ -374,7 +375,7 @@ export function TextBoxOverlay({ backgroundColor: 'transparent', }, ]} - placeholder="Type..." + placeholder={t.editor.typePlaceholder} placeholderTextColor={theme.colors.textTertiary} autoCapitalize="sentences" textAlignVertical="top" @@ -397,7 +398,7 @@ export function TextBoxOverlay({ fontFamily: Platform.OS === 'ios' ? 'System' : 'sans-serif', }} > - {textBox.content || 'Tap to add text'} + {textBox.content || t.editor.tapToAddText} )} diff --git a/src/components/editor/ToolSettingsPopover.tsx b/src/components/editor/ToolSettingsPopover.tsx index 4ce42ec..49bfcba 100644 --- a/src/components/editor/ToolSettingsPopover.tsx +++ b/src/components/editor/ToolSettingsPopover.tsx @@ -21,6 +21,7 @@ import { HIGHLIGHTER_COLORS, STROKE_COLORS } from '../../theme/colors'; import { TOOL_BY_TYPE, WIDTH_RANGE } from '../../utils/toolPalette'; import type { SupportedTool } from '../../utils/toolPalette'; import type { DockedEdge } from './FloatingToolbar'; +import { t } from '../../i18n'; const CARD_WIDTH = 288; const CARD_PADDING = 12; @@ -148,7 +149,7 @@ export function ToolSettingsPopover({ }, ]} > - {mode === 'pixel' ? 'Pixel' : 'Object'} + {mode === 'pixel' ? t.editor.eraserPixel : t.editor.eraserObject} ); diff --git a/src/i18n/locales/de.ts b/src/i18n/locales/de.ts index b78fdf8..9db41a5 100644 --- a/src/i18n/locales/de.ts +++ b/src/i18n/locales/de.ts @@ -141,6 +141,61 @@ export const de: Strings = { 'Die Bewertungsfunktion wird verfügbar, wenn OpenNotes aus einem App Store installiert ist.', couldNotOpenRatingsTitle: 'Bewertungen konnten nicht geöffnet werden', }, + editor: { + statusReady: 'bereit', + statusPending: 'ungesicherte Änderungen', + statusSaving: 'sichert…', + statusSaved: 'gesichert', + statusError: 'Sichern fehlgeschlagen', + pageStatus: (page: number, count: number, status: string) => + `Seite ${page} von ${count} · ${status}`, + pagesA11y: 'Seiten', + exportA11y: 'Exportieren', + couldNotOpenTitle: 'Notiz konnte nicht geöffnet werden', + couldNotOpenBody: + 'Der Inhalt der Notiz konnte nicht gelesen werden. Es wurde nichts verändert; deine Daten sind weiterhin auf diesem Gerät.', + tryAgain: 'Erneut versuchen', + backToLibrary: 'Zurück zur Bibliothek', + startBlankLink: 'Mit leerer Notiz beginnen', + startBlankTitle: 'Mit leerer Notiz beginnen?', + startBlankBody: + 'Der bisherige Inhalt dieser Notiz konnte nicht gelesen werden. Ein leerer Start ersetzt ihn beim nächsten Sichern.', + startBlankConfirm: 'Leer beginnen', + saveFailedTitle: 'Notiz konnte nicht gesichert werden', + saveFailedBody: + 'Deine letzten Änderungen konnten nicht gespeichert werden. Wenn du jetzt gehst, gehen sie verloren.', + leaveAnyway: 'Trotzdem verlassen', + stay: 'Bleiben', + exportFailedTitle: 'Export fehlgeschlagen', + exportFailedBody: 'PDF konnte nicht erstellt werden. Bitte versuche es erneut.', + insertImageTitle: 'Bild einfügen', + chooseFromPhotos: 'Aus Fotos wählen', + takePhoto: 'Foto aufnehmen', + backgroundTitle: 'Hintergrund', + pagesTitle: 'Seiten', + closePagesA11y: 'Seiten schließen', + closePageSidebarA11y: 'Seitenleiste schließen', + jumpToPageA11y: 'Zu Seite springen', + goToPageA11y: (page: number) => `Zu Seite ${page} wechseln`, + undo: 'Widerrufen', + redo: 'Wiederholen', + enableFingerDrawing: 'Fingerzeichnen aktivieren', + disableFingerDrawing: 'Fingerzeichnen deaktivieren', + tapToAddText: 'Tippen, um Text hinzuzufügen', + typePlaceholder: 'Text…', + eraserPixel: 'Pixel', + eraserObject: 'Objekt', + }, + tools: { + pen: 'Stift', + highlighter: 'Textmarker', + crayon: 'Wachsstift', + calligraphy: 'Kalligrafie', + eraser: 'Radierer', + lasso: 'Lasso', + text: 'Text', + image: 'Bild', + }, time: { justNow: 'gerade eben', minutesAgo: (m: number) => `vor ${m} Min.`, diff --git a/src/i18n/locales/en.ts b/src/i18n/locales/en.ts index 2dfa23c..e3ad3ab 100644 --- a/src/i18n/locales/en.ts +++ b/src/i18n/locales/en.ts @@ -141,6 +141,61 @@ export const en = { 'The rating option becomes available when OpenNotes is installed from an app store.', couldNotOpenRatingsTitle: 'Could not open ratings', }, + editor: { + statusReady: 'ready', + statusPending: 'unsaved changes', + statusSaving: 'saving…', + statusSaved: 'saved', + statusError: 'save failed', + pageStatus: (page: number, count: number, status: string) => + `Page ${page} of ${count} · ${status}`, + pagesA11y: 'Pages', + exportA11y: 'Export', + couldNotOpenTitle: "Couldn't open this note", + couldNotOpenBody: + "The note's contents could not be read from storage. Nothing has been changed; your data is still on this device.", + tryAgain: 'Try again', + backToLibrary: 'Back to library', + startBlankLink: 'Start with a blank note', + startBlankTitle: 'Start with a blank note?', + startBlankBody: + 'The existing contents of this note could not be read. Starting blank will replace them the next time the note saves.', + startBlankConfirm: 'Start blank', + saveFailedTitle: "Couldn't save your note", + saveFailedBody: + 'Your latest changes could not be written to storage. Leaving now will discard them.', + leaveAnyway: 'Leave anyway', + stay: 'Stay', + exportFailedTitle: 'Export failed', + exportFailedBody: 'Could not generate a PDF. Please try again.', + insertImageTitle: 'Insert image', + chooseFromPhotos: 'Choose from Photos', + takePhoto: 'Take Photo', + backgroundTitle: 'Background', + pagesTitle: 'Pages', + closePagesA11y: 'Close pages', + closePageSidebarA11y: 'Close page sidebar', + jumpToPageA11y: 'Jump to page', + goToPageA11y: (page: number) => `Go to page ${page}`, + undo: 'Undo', + redo: 'Redo', + enableFingerDrawing: 'Enable finger drawing', + disableFingerDrawing: 'Disable finger drawing', + tapToAddText: 'Tap to add text', + typePlaceholder: 'Type...', + eraserPixel: 'Pixel', + eraserObject: 'Object', + }, + tools: { + pen: 'Pen', + highlighter: 'Highlighter', + crayon: 'Crayon', + calligraphy: 'Calligraphy', + eraser: 'Eraser', + lasso: 'Lasso', + text: 'Text', + image: 'Image', + }, time: { justNow: 'just now', minutesAgo: (m: number) => `${m}m ago`, diff --git a/src/i18n/locales/es.ts b/src/i18n/locales/es.ts index f2c5f41..832c989 100644 --- a/src/i18n/locales/es.ts +++ b/src/i18n/locales/es.ts @@ -141,6 +141,61 @@ export const es: Strings = { 'La opción de valorar estará disponible cuando OpenNotes se instale desde una tienda de apps.', couldNotOpenRatingsTitle: 'No se pudieron abrir las valoraciones', }, + editor: { + statusReady: 'listo', + statusPending: 'cambios sin guardar', + statusSaving: 'guardando…', + statusSaved: 'guardado', + statusError: 'error al guardar', + pageStatus: (page: number, count: number, status: string) => + `Página ${page} de ${count} · ${status}`, + pagesA11y: 'Páginas', + exportA11y: 'Exportar', + couldNotOpenTitle: 'No se pudo abrir esta nota', + couldNotOpenBody: + 'No se pudo leer el contenido de la nota. No se ha cambiado nada; tus datos siguen en este dispositivo.', + tryAgain: 'Reintentar', + backToLibrary: 'Volver a la biblioteca', + startBlankLink: 'Empezar con una nota en blanco', + startBlankTitle: '¿Empezar con una nota en blanco?', + startBlankBody: + 'No se pudo leer el contenido existente de esta nota. Empezar en blanco lo reemplazará la próxima vez que se guarde.', + startBlankConfirm: 'Empezar en blanco', + saveFailedTitle: 'No se pudo guardar tu nota', + saveFailedBody: + 'No se pudieron escribir tus últimos cambios. Si sales ahora, se perderán.', + leaveAnyway: 'Salir igualmente', + stay: 'Quedarse', + exportFailedTitle: 'Error al exportar', + exportFailedBody: 'No se pudo generar el PDF. Inténtalo de nuevo.', + insertImageTitle: 'Insertar imagen', + chooseFromPhotos: 'Elegir de Fotos', + takePhoto: 'Hacer foto', + backgroundTitle: 'Fondo', + pagesTitle: 'Páginas', + closePagesA11y: 'Cerrar páginas', + closePageSidebarA11y: 'Cerrar barra de páginas', + jumpToPageA11y: 'Ir a la página', + goToPageA11y: (page: number) => `Ir a la página ${page}`, + undo: 'Deshacer', + redo: 'Rehacer', + enableFingerDrawing: 'Activar dibujo con el dedo', + disableFingerDrawing: 'Desactivar dibujo con el dedo', + tapToAddText: 'Toca para añadir texto', + typePlaceholder: 'Escribe…', + eraserPixel: 'Píxel', + eraserObject: 'Objeto', + }, + tools: { + pen: 'Bolígrafo', + highlighter: 'Marcador', + crayon: 'Cera', + calligraphy: 'Caligrafía', + eraser: 'Borrador', + lasso: 'Lazo', + text: 'Texto', + image: 'Imagen', + }, time: { justNow: 'ahora mismo', minutesAgo: (m: number) => `hace ${m} min`, diff --git a/src/i18n/locales/fr.ts b/src/i18n/locales/fr.ts index 187d0c6..18e41b6 100644 --- a/src/i18n/locales/fr.ts +++ b/src/i18n/locales/fr.ts @@ -141,6 +141,61 @@ export const fr: Strings = { 'L’évaluation devient disponible lorsque OpenNotes est installé depuis un app store.', couldNotOpenRatingsTitle: 'Impossible d’ouvrir les évaluations', }, + editor: { + statusReady: 'prêt', + statusPending: 'modifications non enregistrées', + statusSaving: 'enregistrement…', + statusSaved: 'enregistré', + statusError: 'échec de l’enregistrement', + pageStatus: (page: number, count: number, status: string) => + `Page ${page} sur ${count} · ${status}`, + pagesA11y: 'Pages', + exportA11y: 'Exporter', + couldNotOpenTitle: 'Impossible d’ouvrir cette note', + couldNotOpenBody: + 'Le contenu de la note n’a pas pu être lu. Rien n’a été modifié ; vos données sont toujours sur cet appareil.', + tryAgain: 'Réessayer', + backToLibrary: 'Retour à la bibliothèque', + startBlankLink: 'Commencer avec une note vierge', + startBlankTitle: 'Commencer avec une note vierge ?', + startBlankBody: + 'Le contenu existant de cette note n’a pas pu être lu. Repartir de zéro le remplacera au prochain enregistrement.', + startBlankConfirm: 'Commencer vierge', + saveFailedTitle: 'Impossible d’enregistrer votre note', + saveFailedBody: + 'Vos dernières modifications n’ont pas pu être écrites. Partir maintenant les fera disparaître.', + leaveAnyway: 'Partir quand même', + stay: 'Rester', + exportFailedTitle: 'Échec de l’export', + exportFailedBody: 'Impossible de générer un PDF. Veuillez réessayer.', + insertImageTitle: 'Insérer une image', + chooseFromPhotos: 'Choisir dans Photos', + takePhoto: 'Prendre une photo', + backgroundTitle: 'Arrière-plan', + pagesTitle: 'Pages', + closePagesA11y: 'Fermer les pages', + closePageSidebarA11y: 'Fermer la barre des pages', + jumpToPageA11y: 'Aller à la page', + goToPageA11y: (page: number) => `Aller à la page ${page}`, + undo: 'Annuler', + redo: 'Rétablir', + enableFingerDrawing: 'Activer le dessin au doigt', + disableFingerDrawing: 'Désactiver le dessin au doigt', + tapToAddText: 'Touchez pour ajouter du texte', + typePlaceholder: 'Saisir…', + eraserPixel: 'Pixel', + eraserObject: 'Objet', + }, + tools: { + pen: 'Stylo', + highlighter: 'Surligneur', + crayon: 'Craie grasse', + calligraphy: 'Calligraphie', + eraser: 'Gomme', + lasso: 'Lasso', + text: 'Texte', + image: 'Image', + }, time: { justNow: 'à l’instant', minutesAgo: (m: number) => `il y a ${m} min`, diff --git a/src/i18n/locales/it.ts b/src/i18n/locales/it.ts index e3edc6e..ac91e8b 100644 --- a/src/i18n/locales/it.ts +++ b/src/i18n/locales/it.ts @@ -141,6 +141,61 @@ export const it: Strings = { 'L’opzione di valutazione sarà disponibile quando OpenNotes è installato da un app store.', couldNotOpenRatingsTitle: 'Impossibile aprire le valutazioni', }, + editor: { + statusReady: 'pronto', + statusPending: 'modifiche non salvate', + statusSaving: 'salvataggio…', + statusSaved: 'salvato', + statusError: 'salvataggio non riuscito', + pageStatus: (page: number, count: number, status: string) => + `Pagina ${page} di ${count} · ${status}`, + pagesA11y: 'Pagine', + exportA11y: 'Esporta', + couldNotOpenTitle: 'Impossibile aprire questa nota', + couldNotOpenBody: + 'Non è stato possibile leggere il contenuto della nota. Nulla è stato modificato; i tuoi dati sono ancora su questo dispositivo.', + tryAgain: 'Riprova', + backToLibrary: 'Torna alla libreria', + startBlankLink: 'Inizia con una nota vuota', + startBlankTitle: 'Iniziare con una nota vuota?', + startBlankBody: + 'Il contenuto esistente di questa nota non è leggibile. Iniziando da zero verrà sostituito al prossimo salvataggio.', + startBlankConfirm: 'Inizia vuota', + saveFailedTitle: 'Impossibile salvare la nota', + saveFailedBody: + 'Le ultime modifiche non sono state scritte. Uscendo ora andranno perse.', + leaveAnyway: 'Esci comunque', + stay: 'Rimani', + exportFailedTitle: 'Esportazione non riuscita', + exportFailedBody: 'Impossibile generare il PDF. Riprova.', + insertImageTitle: 'Inserisci immagine', + chooseFromPhotos: 'Scegli da Foto', + takePhoto: 'Scatta foto', + backgroundTitle: 'Sfondo', + pagesTitle: 'Pagine', + closePagesA11y: 'Chiudi pagine', + closePageSidebarA11y: 'Chiudi barra delle pagine', + jumpToPageA11y: 'Vai alla pagina', + goToPageA11y: (page: number) => `Vai alla pagina ${page}`, + undo: 'Annulla', + redo: 'Ripeti', + enableFingerDrawing: 'Attiva disegno col dito', + disableFingerDrawing: 'Disattiva disegno col dito', + tapToAddText: 'Tocca per aggiungere testo', + typePlaceholder: 'Scrivi…', + eraserPixel: 'Pixel', + eraserObject: 'Oggetto', + }, + tools: { + pen: 'Penna', + highlighter: 'Evidenziatore', + crayon: 'Pastello', + calligraphy: 'Calligrafia', + eraser: 'Gomma', + lasso: 'Lazo', + text: 'Testo', + image: 'Immagine', + }, time: { justNow: 'adesso', minutesAgo: (m: number) => `${m} min fa`, diff --git a/src/i18n/locales/ja.ts b/src/i18n/locales/ja.ts index 3fab4a9..6feddc5 100644 --- a/src/i18n/locales/ja.ts +++ b/src/i18n/locales/ja.ts @@ -141,6 +141,61 @@ export const ja: Strings = { '評価機能は、OpenNotesをApp Storeからインストールすると利用できるようになります。', couldNotOpenRatingsTitle: '評価を開けませんでした', }, + editor: { + statusReady: '準備完了', + statusPending: '未保存の変更', + statusSaving: '保存中…', + statusSaved: '保存済み', + statusError: '保存に失敗', + pageStatus: (page: number, count: number, status: string) => + `${count}ページ中${page}ページ · ${status}`, + pagesA11y: 'ページ', + exportA11y: '書き出す', + couldNotOpenTitle: 'このノートを開けませんでした', + couldNotOpenBody: + 'ノートの内容を読み込めませんでした。何も変更されていません。データはこの端末に残っています。', + tryAgain: 'もう一度試す', + backToLibrary: 'ライブラリに戻る', + startBlankLink: '白紙のノートで始める', + startBlankTitle: '白紙のノートで始めますか?', + startBlankBody: + 'このノートの既存の内容を読み込めませんでした。白紙で始めると、次の保存時に置き換えられます。', + startBlankConfirm: '白紙で始める', + saveFailedTitle: 'ノートを保存できませんでした', + saveFailedBody: + '最新の変更を書き込めませんでした。今離れると変更は失われます。', + leaveAnyway: 'それでも離れる', + stay: 'とどまる', + exportFailedTitle: '書き出しに失敗しました', + exportFailedBody: 'PDFを生成できませんでした。もう一度お試しください。', + insertImageTitle: '画像を挿入', + chooseFromPhotos: '写真から選択', + takePhoto: '写真を撮る', + backgroundTitle: '背景', + pagesTitle: 'ページ', + closePagesA11y: 'ページを閉じる', + closePageSidebarA11y: 'ページサイドバーを閉じる', + jumpToPageA11y: 'ページへ移動', + goToPageA11y: (page: number) => `${page}ページへ移動`, + undo: '取り消す', + redo: 'やり直す', + enableFingerDrawing: '指での描画を有効にする', + disableFingerDrawing: '指での描画を無効にする', + tapToAddText: 'タップしてテキストを追加', + typePlaceholder: '入力…', + eraserPixel: 'ピクセル', + eraserObject: 'オブジェクト', + }, + tools: { + pen: 'ペン', + highlighter: '蛍光ペン', + crayon: 'クレヨン', + calligraphy: 'カリグラフィー', + eraser: '消しゴム', + lasso: '投げなわ', + text: 'テキスト', + image: '画像', + }, time: { justNow: 'たった今', minutesAgo: (m: number) => `${m}分前`, diff --git a/src/i18n/locales/ko.ts b/src/i18n/locales/ko.ts index 3501fb9..41d8959 100644 --- a/src/i18n/locales/ko.ts +++ b/src/i18n/locales/ko.ts @@ -141,6 +141,61 @@ export const ko: Strings = { '평가 기능은 OpenNotes를 앱 스토어에서 설치했을 때 사용할 수 있습니다.', couldNotOpenRatingsTitle: '평가를 열지 못했습니다', }, + editor: { + statusReady: '준비됨', + statusPending: '저장되지 않은 변경 사항', + statusSaving: '저장 중…', + statusSaved: '저장됨', + statusError: '저장 실패', + pageStatus: (page: number, count: number, status: string) => + `${count}페이지 중 ${page}페이지 · ${status}`, + pagesA11y: '페이지', + exportA11y: '내보내기', + couldNotOpenTitle: '이 노트를 열 수 없습니다', + couldNotOpenBody: + '노트 내용을 읽을 수 없었습니다. 아무것도 변경되지 않았으며, 데이터는 이 기기에 그대로 있습니다.', + tryAgain: '다시 시도', + backToLibrary: '보관함으로 돌아가기', + startBlankLink: '빈 노트로 시작', + startBlankTitle: '빈 노트로 시작할까요?', + startBlankBody: + '이 노트의 기존 내용을 읽을 수 없었습니다. 빈 노트로 시작하면 다음 저장 시 기존 내용이 대체됩니다.', + startBlankConfirm: '빈 노트로 시작', + saveFailedTitle: '노트를 저장하지 못했습니다', + saveFailedBody: + '최근 변경 사항을 기록하지 못했습니다. 지금 나가면 변경 사항이 사라집니다.', + leaveAnyway: '그래도 나가기', + stay: '머무르기', + exportFailedTitle: '내보내기 실패', + exportFailedBody: 'PDF를 만들지 못했습니다. 다시 시도해 주세요.', + insertImageTitle: '이미지 삽입', + chooseFromPhotos: '사진에서 선택', + takePhoto: '사진 찍기', + backgroundTitle: '배경', + pagesTitle: '페이지', + closePagesA11y: '페이지 닫기', + closePageSidebarA11y: '페이지 사이드바 닫기', + jumpToPageA11y: '페이지로 이동', + goToPageA11y: (page: number) => `${page}페이지로 이동`, + undo: '실행 취소', + redo: '다시 실행', + enableFingerDrawing: '손가락 그리기 켜기', + disableFingerDrawing: '손가락 그리기 끄기', + tapToAddText: '탭하여 텍스트 추가', + typePlaceholder: '입력…', + eraserPixel: '픽셀', + eraserObject: '개체', + }, + tools: { + pen: '펜', + highlighter: '형광펜', + crayon: '크레용', + calligraphy: '캘리그래피', + eraser: '지우개', + lasso: '올가미', + text: '텍스트', + image: '이미지', + }, time: { justNow: '방금', minutesAgo: (m: number) => `${m}분 전`, diff --git a/src/i18n/locales/nl.ts b/src/i18n/locales/nl.ts index b345208..caf7601 100644 --- a/src/i18n/locales/nl.ts +++ b/src/i18n/locales/nl.ts @@ -141,6 +141,61 @@ export const nl: Strings = { 'Beoordelen wordt beschikbaar wanneer OpenNotes via een appwinkel is geïnstalleerd.', couldNotOpenRatingsTitle: 'Kon beoordelingen niet openen', }, + editor: { + statusReady: 'gereed', + statusPending: 'niet-bewaarde wijzigingen', + statusSaving: 'bewaren…', + statusSaved: 'bewaard', + statusError: 'bewaren mislukt', + pageStatus: (page: number, count: number, status: string) => + `Pagina ${page} van ${count} · ${status}`, + pagesA11y: 'Pagina’s', + exportA11y: 'Exporteer', + couldNotOpenTitle: 'Kon deze notitie niet openen', + couldNotOpenBody: + 'De inhoud van de notitie kon niet worden gelezen. Er is niets veranderd; je gegevens staan nog op dit apparaat.', + tryAgain: 'Probeer opnieuw', + backToLibrary: 'Terug naar bibliotheek', + startBlankLink: 'Begin met een lege notitie', + startBlankTitle: 'Beginnen met een lege notitie?', + startBlankBody: + 'De bestaande inhoud van deze notitie kon niet worden gelezen. Leeg beginnen vervangt die bij de volgende keer bewaren.', + startBlankConfirm: 'Begin leeg', + saveFailedTitle: 'Kon je notitie niet bewaren', + saveFailedBody: + 'Je laatste wijzigingen konden niet worden weggeschreven. Nu weggaan gooit ze weg.', + leaveAnyway: 'Toch weggaan', + stay: 'Blijf', + exportFailedTitle: 'Exporteren mislukt', + exportFailedBody: 'Kon geen PDF genereren. Probeer het opnieuw.', + insertImageTitle: 'Afbeelding invoegen', + chooseFromPhotos: 'Kies uit Foto’s', + takePhoto: 'Maak foto', + backgroundTitle: 'Achtergrond', + pagesTitle: 'Pagina’s', + closePagesA11y: 'Sluit pagina’s', + closePageSidebarA11y: 'Sluit paginabalk', + jumpToPageA11y: 'Spring naar pagina', + goToPageA11y: (page: number) => `Ga naar pagina ${page}`, + undo: 'Herstel', + redo: 'Opnieuw', + enableFingerDrawing: 'Tekenen met vinger aanzetten', + disableFingerDrawing: 'Tekenen met vinger uitzetten', + tapToAddText: 'Tik om tekst toe te voegen', + typePlaceholder: 'Typ…', + eraserPixel: 'Pixel', + eraserObject: 'Object', + }, + tools: { + pen: 'Pen', + highlighter: 'Markeerstift', + crayon: 'Waskrijt', + calligraphy: 'Kalligrafie', + eraser: 'Gum', + lasso: 'Lasso', + text: 'Tekst', + image: 'Afbeelding', + }, time: { justNow: 'zojuist', minutesAgo: (m: number) => `${m} min geleden`, diff --git a/src/i18n/locales/pt.ts b/src/i18n/locales/pt.ts index e1ca58b..7056d85 100644 --- a/src/i18n/locales/pt.ts +++ b/src/i18n/locales/pt.ts @@ -141,6 +141,61 @@ export const pt: Strings = { 'A opção de avaliar fica disponível quando o OpenNotes é instalado por uma loja de apps.', couldNotOpenRatingsTitle: 'Não foi possível abrir as avaliações', }, + editor: { + statusReady: 'pronto', + statusPending: 'alterações não salvas', + statusSaving: 'salvando…', + statusSaved: 'salvo', + statusError: 'falha ao salvar', + pageStatus: (page: number, count: number, status: string) => + `Página ${page} de ${count} · ${status}`, + pagesA11y: 'Páginas', + exportA11y: 'Exportar', + couldNotOpenTitle: 'Não foi possível abrir esta nota', + couldNotOpenBody: + 'O conteúdo da nota não pôde ser lido. Nada foi alterado; seus dados continuam neste aparelho.', + tryAgain: 'Tentar novamente', + backToLibrary: 'Voltar à biblioteca', + startBlankLink: 'Começar com uma nota em branco', + startBlankTitle: 'Começar com uma nota em branco?', + startBlankBody: + 'O conteúdo existente desta nota não pôde ser lido. Começar em branco vai substituí-lo no próximo salvamento.', + startBlankConfirm: 'Começar em branco', + saveFailedTitle: 'Não foi possível salvar sua nota', + saveFailedBody: + 'Suas últimas alterações não puderam ser gravadas. Sair agora vai descartá-las.', + leaveAnyway: 'Sair mesmo assim', + stay: 'Ficar', + exportFailedTitle: 'Falha na exportação', + exportFailedBody: 'Não foi possível gerar o PDF. Tente novamente.', + insertImageTitle: 'Inserir imagem', + chooseFromPhotos: 'Escolher das Fotos', + takePhoto: 'Tirar foto', + backgroundTitle: 'Plano de fundo', + pagesTitle: 'Páginas', + closePagesA11y: 'Fechar páginas', + closePageSidebarA11y: 'Fechar barra de páginas', + jumpToPageA11y: 'Ir para a página', + goToPageA11y: (page: number) => `Ir para a página ${page}`, + undo: 'Desfazer', + redo: 'Refazer', + enableFingerDrawing: 'Ativar desenho com o dedo', + disableFingerDrawing: 'Desativar desenho com o dedo', + tapToAddText: 'Toque para adicionar texto', + typePlaceholder: 'Digite…', + eraserPixel: 'Pixel', + eraserObject: 'Objeto', + }, + tools: { + pen: 'Caneta', + highlighter: 'Marca-texto', + crayon: 'Giz de cera', + calligraphy: 'Caligrafia', + eraser: 'Borracha', + lasso: 'Laço', + text: 'Texto', + image: 'Imagem', + }, time: { justNow: 'agora mesmo', minutesAgo: (m: number) => `${m} min atrás`, diff --git a/src/i18n/locales/ru.ts b/src/i18n/locales/ru.ts index 7aca720..d578195 100644 --- a/src/i18n/locales/ru.ts +++ b/src/i18n/locales/ru.ts @@ -151,6 +151,61 @@ export const ru: Strings = { 'Оценка станет доступна, когда OpenNotes установлен из магазина приложений.', couldNotOpenRatingsTitle: 'Не удалось открыть оценки', }, + editor: { + statusReady: 'готово', + statusPending: 'несохранённые изменения', + statusSaving: 'сохранение…', + statusSaved: 'сохранено', + statusError: 'не удалось сохранить', + pageStatus: (page: number, count: number, status: string) => + `Страница ${page} из ${count} · ${status}`, + pagesA11y: 'Страницы', + exportA11y: 'Экспорт', + couldNotOpenTitle: 'Не удалось открыть заметку', + couldNotOpenBody: + 'Содержимое заметки не удалось прочитать. Ничего не изменено; ваши данные по-прежнему на этом устройстве.', + tryAgain: 'Повторить', + backToLibrary: 'Назад в библиотеку', + startBlankLink: 'Начать с пустой заметки', + startBlankTitle: 'Начать с пустой заметки?', + startBlankBody: + 'Существующее содержимое этой заметки не удалось прочитать. Пустое начало заменит его при следующем сохранении.', + startBlankConfirm: 'Начать с пустой', + saveFailedTitle: 'Не удалось сохранить заметку', + saveFailedBody: + 'Последние изменения не удалось записать. Если уйти сейчас, они будут потеряны.', + leaveAnyway: 'Всё равно уйти', + stay: 'Остаться', + exportFailedTitle: 'Не удалось экспортировать', + exportFailedBody: 'Не удалось создать PDF. Попробуйте ещё раз.', + insertImageTitle: 'Вставить изображение', + chooseFromPhotos: 'Выбрать из Фото', + takePhoto: 'Снять фото', + backgroundTitle: 'Фон', + pagesTitle: 'Страницы', + closePagesA11y: 'Закрыть страницы', + closePageSidebarA11y: 'Закрыть панель страниц', + jumpToPageA11y: 'Перейти к странице', + goToPageA11y: (page: number) => `Перейти к странице ${page}`, + undo: 'Отменить', + redo: 'Повторить', + enableFingerDrawing: 'Включить рисование пальцем', + disableFingerDrawing: 'Выключить рисование пальцем', + tapToAddText: 'Коснитесь, чтобы добавить текст', + typePlaceholder: 'Введите…', + eraserPixel: 'Пиксель', + eraserObject: 'Объект', + }, + tools: { + pen: 'Ручка', + highlighter: 'Маркер', + crayon: 'Мелок', + calligraphy: 'Каллиграфия', + eraser: 'Ластик', + lasso: 'Лассо', + text: 'Текст', + image: 'Изображение', + }, time: { justNow: 'только что', minutesAgo: (m: number) => `${m} мин назад`, diff --git a/src/i18n/locales/zhHans.ts b/src/i18n/locales/zhHans.ts index 28541e9..46a2bdf 100644 --- a/src/i18n/locales/zhHans.ts +++ b/src/i18n/locales/zhHans.ts @@ -139,6 +139,60 @@ export const zhHans: Strings = { ratingsUnavailableMessage: '当 OpenNotes 从应用商店安装后,评价功能即可使用。', couldNotOpenRatingsTitle: '无法打开评价', }, + editor: { + statusReady: '就绪', + statusPending: '有未保存的更改', + statusSaving: '保存中…', + statusSaved: '已保存', + statusError: '保存失败', + pageStatus: (page: number, count: number, status: string) => + `第 ${page} 页,共 ${count} 页 · ${status}`, + pagesA11y: '页面', + exportA11y: '导出', + couldNotOpenTitle: '无法打开这条笔记', + couldNotOpenBody: + '无法读取笔记内容。没有任何更改;你的数据仍在此设备上。', + tryAgain: '重试', + backToLibrary: '返回资料库', + startBlankLink: '以空白笔记开始', + startBlankTitle: '以空白笔记开始?', + startBlankBody: + '无法读取这条笔记的现有内容。以空白开始后,下次保存时将替换原内容。', + startBlankConfirm: '空白开始', + saveFailedTitle: '无法保存你的笔记', + saveFailedBody: '最近的更改无法写入。现在离开将丢弃这些更改。', + leaveAnyway: '仍要离开', + stay: '留下', + exportFailedTitle: '导出失败', + exportFailedBody: '无法生成 PDF。请重试。', + insertImageTitle: '插入图片', + chooseFromPhotos: '从照片中选择', + takePhoto: '拍照', + backgroundTitle: '背景', + pagesTitle: '页面', + closePagesA11y: '关闭页面', + closePageSidebarA11y: '关闭页面边栏', + jumpToPageA11y: '跳转到页面', + goToPageA11y: (page: number) => `前往第 ${page} 页`, + undo: '撤销', + redo: '重做', + enableFingerDrawing: '开启手指绘画', + disableFingerDrawing: '关闭手指绘画', + tapToAddText: '点按以添加文本', + typePlaceholder: '输入…', + eraserPixel: '像素', + eraserObject: '对象', + }, + tools: { + pen: '钢笔', + highlighter: '荧光笔', + crayon: '蜡笔', + calligraphy: '书法笔', + eraser: '橡皮擦', + lasso: '套索', + text: '文本', + image: '图片', + }, time: { justNow: '刚刚', minutesAgo: (m: number) => `${m} 分钟前`, diff --git a/src/i18n/locales/zhHant.ts b/src/i18n/locales/zhHant.ts index af0b367..0783e46 100644 --- a/src/i18n/locales/zhHant.ts +++ b/src/i18n/locales/zhHant.ts @@ -139,6 +139,60 @@ export const zhHant: Strings = { ratingsUnavailableMessage: '當 OpenNotes 從 App 商店安裝後,即可使用評分功能。', couldNotOpenRatingsTitle: '無法開啟評分', }, + editor: { + statusReady: '就緒', + statusPending: '有未儲存的變更', + statusSaving: '儲存中…', + statusSaved: '已儲存', + statusError: '儲存失敗', + pageStatus: (page: number, count: number, status: string) => + `第 ${page} 頁,共 ${count} 頁 · ${status}`, + pagesA11y: '頁面', + exportA11y: '匯出', + couldNotOpenTitle: '無法開啟這則筆記', + couldNotOpenBody: + '無法讀取筆記內容。沒有任何變更;你的資料仍在此裝置上。', + tryAgain: '再試一次', + backToLibrary: '返回資料庫', + startBlankLink: '以空白筆記開始', + startBlankTitle: '以空白筆記開始?', + startBlankBody: + '無法讀取這則筆記的現有內容。以空白開始後,下次儲存時將取代原內容。', + startBlankConfirm: '空白開始', + saveFailedTitle: '無法儲存你的筆記', + saveFailedBody: '最近的變更無法寫入。現在離開將捨棄這些變更。', + leaveAnyway: '仍要離開', + stay: '留下', + exportFailedTitle: '匯出失敗', + exportFailedBody: '無法產生 PDF。請再試一次。', + insertImageTitle: '插入影像', + chooseFromPhotos: '從照片中選擇', + takePhoto: '拍照', + backgroundTitle: '背景', + pagesTitle: '頁面', + closePagesA11y: '關閉頁面', + closePageSidebarA11y: '關閉頁面側邊欄', + jumpToPageA11y: '跳至頁面', + goToPageA11y: (page: number) => `前往第 ${page} 頁`, + undo: '還原', + redo: '重做', + enableFingerDrawing: '開啟手指繪圖', + disableFingerDrawing: '關閉手指繪圖', + tapToAddText: '點一下以加入文字', + typePlaceholder: '輸入…', + eraserPixel: '像素', + eraserObject: '物件', + }, + tools: { + pen: '鋼筆', + highlighter: '螢光筆', + crayon: '蠟筆', + calligraphy: '書法筆', + eraser: '橡皮擦', + lasso: '套索', + text: '文字', + image: '影像', + }, time: { justNow: '剛剛', minutesAgo: (m: number) => `${m} 分鐘前`, diff --git a/src/services/notesRepo.ts b/src/services/notesRepo.ts index ed9ac8d..bf9c467 100644 --- a/src/services/notesRepo.ts +++ b/src/services/notesRepo.ts @@ -1,6 +1,7 @@ import type { SerializedNotebookData } from '@mathnotes/mobile-ink'; import type { BackgroundType, NoteMetadata } from '../types/note'; import { noteId as makeNoteId } from '../utils/id'; +import { t } from '../i18n'; import { catalogStore } from './catalogEnv'; import { pruneTombstones } from './catalogStore'; import { deleteBody, readBody, writeBody, type BodyReadResult } from './noteBodyStorage'; @@ -30,7 +31,7 @@ export async function createNote(opts: { const now = new Date().toISOString(); const meta: NoteMetadata = { id: makeNoteId(), - title: opts.title ?? 'Untitled', + title: opts.title ?? t.common.untitled, folderId: opts.folderId ?? null, createdAt: now, updatedAt: now, @@ -96,7 +97,7 @@ export async function moveNote(id: string, folderId: string | null): Promise { - return updateMetadata(id, { title: title.trim() || 'Untitled' }); + return updateMetadata(id, { title: title.trim() || t.common.untitled }); } export async function setNoteBackground( diff --git a/src/types/note.ts b/src/types/note.ts index 14f06cf..e29755c 100644 --- a/src/types/note.ts +++ b/src/types/note.ts @@ -15,15 +15,6 @@ export const BACKGROUND_TYPES: BackgroundType[] = [ 'pdf', ]; -export const BACKGROUND_LABELS: Record = { - plain: 'Plain', - lined: 'Lined', - grid: 'Grid', - dotted: 'Dotted', - graph: 'Graph', - pdf: 'PDF', -}; - export interface FolderMetadata { id: string; name: string; diff --git a/src/utils/toolPalette.ts b/src/utils/toolPalette.ts index ee04944..7f17888 100644 --- a/src/utils/toolPalette.ts +++ b/src/utils/toolPalette.ts @@ -1,4 +1,5 @@ import type { InkToolType } from '@mathnotes/mobile-ink'; +import { t } from '../i18n'; export type SupportedTool = Exclude; @@ -16,7 +17,7 @@ export interface ToolDescriptor { export const TOOL_DESCRIPTORS: ToolDescriptor[] = [ { type: 'pen', - label: 'Pen', + label: t.tools.pen, iconFamily: 'mci', iconName: 'pen', defaultWidth: 3, @@ -26,7 +27,7 @@ export const TOOL_DESCRIPTORS: ToolDescriptor[] = [ }, { type: 'highlighter', - label: 'Highlighter', + label: t.tools.highlighter, iconFamily: 'mci', iconName: 'marker', defaultWidth: 14, @@ -36,7 +37,7 @@ export const TOOL_DESCRIPTORS: ToolDescriptor[] = [ }, { type: 'crayon', - label: 'Crayon', + label: t.tools.crayon, iconFamily: 'mci', iconName: 'grease-pencil', defaultWidth: 6, @@ -46,7 +47,7 @@ export const TOOL_DESCRIPTORS: ToolDescriptor[] = [ }, { type: 'calligraphy', - label: 'Calligraphy', + label: t.tools.calligraphy, iconFamily: 'mci', iconName: 'fountain-pen-tip', defaultWidth: 4, @@ -56,7 +57,7 @@ export const TOOL_DESCRIPTORS: ToolDescriptor[] = [ }, { type: 'eraser', - label: 'Eraser', + label: t.tools.eraser, iconFamily: 'mci', iconName: 'eraser', defaultWidth: 18, @@ -66,7 +67,7 @@ export const TOOL_DESCRIPTORS: ToolDescriptor[] = [ }, { type: 'select', - label: 'Lasso', + label: t.tools.lasso, iconFamily: 'mci', iconName: 'lasso', defaultWidth: 0, @@ -76,7 +77,7 @@ export const TOOL_DESCRIPTORS: ToolDescriptor[] = [ }, { type: 'text', - label: 'Text', + label: t.tools.text, iconFamily: 'mci', iconName: 'format-text', defaultWidth: 0, @@ -86,7 +87,7 @@ export const TOOL_DESCRIPTORS: ToolDescriptor[] = [ }, { type: 'insert', - label: 'Image', + label: t.tools.image, iconFamily: 'ion', iconName: 'image-outline', defaultWidth: 0,