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,