worldhopper/lib/l10n/app_localizations_es.dart
Felipe M. 58a562abe8
feat: refactor server software abstraction with Kavita REST API integration
Rename all OPDS-prefixed models to generic names (Server, Feed, Entry,
Link, StreamLink), expand the ServerSoftware interface to cover all
server interactions, and implement a full Kavita REST API client that
replaces the OPDS delegation.

- Rename OPDS* models to generic names across ~60 files
- Add database migrations 13 (opds_id → entry_id) and 14 (unify credentials)
- Create OPDSServerSoftware wrapping existing OPDS services
- Create KavitaApiClient for direct Kavita REST API calls
- Create KavitaFeedMapper to convert Kavita JSON to Feed/Entry models
- Rewrite KavitaServerSoftware to use native API (no OPDS delegation)
- Unify server credentials (remove softwareUsername/softwarePassword)
- Simplify add/edit server UI to single auth section
- Add test connection button to server add/edit screens
- Add progress indicator to PublicationCard using local and server data
- Eliminate softwareType branching in reader screens
- Add EntryProgress and fetchEntryProgress to ServerSoftware interface
- Fix Entry.acquisitionLink crash on empty links
- Add 59 new tests covering models, services, and providers
2026-04-06 17:46:48 +02:00

980 lines
23 KiB
Dart

// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Spanish Castilian (`es`).
class AppLocalizationsEs extends AppLocalizations {
AppLocalizationsEs([String locale = 'es']) : super(locale);
@override
String get appName => 'Worldhopper';
@override
String get navLibrary => 'Biblioteca';
@override
String get navServers => 'Servidores';
@override
String get navSettings => 'Ajustes';
@override
String get settingsTitle => 'Ajustes';
@override
String get settingsAppearance => 'Apariencia';
@override
String get settingsAppearanceSubtitle => 'Opciones de visualización';
@override
String get settingsLanguage => 'Idioma';
@override
String get settingsLanguageSubtitle => 'Idioma de la aplicación';
@override
String get settingsReaders => 'Lectores';
@override
String get settingsReadersSubtitle => 'Opciones de lectura';
@override
String get settingsAdvanced => 'Avanzado';
@override
String get settingsAdvancedSubtitle => 'Desarrollo y depuración';
@override
String get settingsAbout => 'Acerca de';
@override
String get settingsAboutSubtitle => 'Worldhopper';
@override
String get appearanceTitle => 'Apariencia';
@override
String get appearanceTheme => 'Tema';
@override
String get themeLight => 'Claro';
@override
String get themeDark => 'Oscuro';
@override
String get themeSystem => 'Sistema';
@override
String get themeSystemSubtitle => 'Seguir el tema del dispositivo';
@override
String get languageTitle => 'Idioma';
@override
String get languageSystem => 'Predeterminado del sistema';
@override
String get languageSystemSubtitle => 'Usar el idioma del dispositivo';
@override
String get readersTitle => 'Lectores';
@override
String get readersGeneralSection => 'General';
@override
String get readersEinkMode => 'Modo e-ink';
@override
String get readersEinkModeSubtitle =>
'Desactivar animaciones para pantallas e-ink';
@override
String get readersImageReaderSection => 'Lector de imágenes';
@override
String get readersCachingSection => 'Caché';
@override
String get readersReadingDirection => 'Dirección de lectura';
@override
String get readersFilterQuality => 'Calidad de filtro';
@override
String get readersPrecachePages => 'Precarga de páginas';
@override
String get readersTwoPageSpread => 'Doble página';
@override
String get readersTwoPageSpreadSubtitle =>
'Mostrar dos páginas lado a lado en pantallas anchas';
@override
String get readersFirstPageIsCover => 'La primera página es portada';
@override
String get readersFirstPageIsCoverSubtitle =>
'Mostrar la primera página sola en doble página';
@override
String get readersSyncProgress => 'Sincronizar progreso de páginas en caché';
@override
String get readersSyncProgressSubtitle =>
'Vuelve a descargar cada página al pasar para que el servidor registre tu progreso de lectura. Consume datos adicionales.';
@override
String get readingDirectionTitle => 'Dirección de lectura';
@override
String get readingModeLtr => 'Izquierda a derecha';
@override
String get readingModeLtrDescription =>
'Orden de lectura occidental estándar';
@override
String get readingModeRtl => 'Derecha a izquierda';
@override
String get readingModeRtlDescription => 'Orden de lectura estilo manga';
@override
String get readingModeVertical => 'Desplazamiento vertical';
@override
String get readingModeVerticalDescription =>
'Desplazamiento continuo estilo webtoon';
@override
String get readingDirectionHelp =>
'Controla la dirección de lectura del lector de imágenes. Izquierda a derecha es el estándar para cómics occidentales, derecha a izquierda para manga, y desplazamiento vertical para webtoons.';
@override
String get readingModeShortLtr => 'IaD';
@override
String get readingModeShortRtl => 'DaI';
@override
String get readingModeShortVertical => 'Vertical';
@override
String get filterQualityTitle => 'Calidad de filtro';
@override
String get filterQualityNone => 'Ninguna';
@override
String get filterQualityNoneDescription => 'Más rápido, puede verse pixelado';
@override
String get filterQualityLow => 'Baja';
@override
String get filterQualityLowDescription => 'Interpolación bilineal';
@override
String get filterQualityMedium => 'Media';
@override
String get filterQualityMediumDescription =>
'Bilineal con mipmaps, buen equilibrio';
@override
String get filterQualityHigh => 'Alta';
@override
String get filterQualityHighDescription =>
'Interpolación bicúbica, mejor calidad';
@override
String get filterQualityHelp =>
'Controla cómo se escalan las imágenes cuando una página se reduce para ajustarse a la pantalla. Mayor calidad hace que el texto y los detalles finos sean más nítidos, pero usa más recursos de GPU. Se recomienda Media para la mayoría de dispositivos.';
@override
String get precachePagesTitle => 'Precarga de páginas';
@override
String get precachePagesOff => 'Desactivada';
@override
String get precachePagesOffDescription =>
'Las páginas se cargan bajo demanda';
@override
String get precachePages1 => '1 página';
@override
String get precachePages1Description => 'Precarga mínima';
@override
String get precachePages2 => '2 páginas';
@override
String get precachePages2Description => 'Precarga ligera';
@override
String get precachePages3 => '3 páginas';
@override
String get precachePages3Description => 'Equilibrada, recomendada';
@override
String get precachePages4 => '4 páginas';
@override
String get precachePages4Description => 'Precarga agresiva';
@override
String get precachePages5 => '5 páginas';
@override
String get precachePages5Description =>
'Precarga máxima, usa más ancho de banda';
@override
String get precachePagesHelp =>
'Controla cuántas páginas siguientes se precargan en segundo plano mientras lees. Valores más altos hacen que pasar página sea más fluido, pero usan más ancho de banda y memoria.\n\nNota: La precarga de páginas puede marcarlas como leídas en el servidor. Tu progreso de lectura local no se verá afectado.';
@override
String get advancedTitle => 'Avanzado';
@override
String get advancedDeveloperMode => 'Modo desarrollador';
@override
String get advancedDeveloperModeSubtitle =>
'Activar herramientas de depuración';
@override
String get advancedTests => 'Pruebas';
@override
String get advancedTestsSubtitle => 'Previsualizar componentes de interfaz';
@override
String get advancedDebuggingInfo => 'Información de depuración';
@override
String get advancedVersion => 'Versión';
@override
String get advancedBuildNumber => 'Número de compilación';
@override
String get advancedPackageName => 'Nombre del paquete';
@override
String get advancedDatabaseVersion => 'Versión de la base de datos';
@override
String get advancedPlatform => 'Plataforma';
@override
String get advancedCopyToClipboard => 'Copiar al portapapeles';
@override
String get advancedCopyToClipboardSubtitle =>
'Copiar toda la información de depuración para informes de errores';
@override
String get advancedDebugInfoCopied =>
'Información de depuración copiada al portapapeles';
@override
String get advancedFailedToLoadInfo => 'Error al cargar la información';
@override
String get aboutTitle => 'Acerca de';
@override
String get aboutVersion => 'Versión';
@override
String get aboutVersionUnknown => 'desconocida';
@override
String get aboutSourceCode => 'Código fuente';
@override
String get aboutReportIssue => 'Reportar un problema';
@override
String get aboutReportIssueSubtitle => 'Abrir un informe en el repositorio';
@override
String get devTestsTitle => 'Pruebas de desarrollo';
@override
String get devTestsSnackBars => 'Barras de notificación';
@override
String get devTestsSuccess => 'Éxito';
@override
String get devTestsError => 'Error';
@override
String get devTestsWarning => 'Advertencia';
@override
String get devTestsInfo => 'Información';
@override
String get devTestsSuccessMessage => 'Este es un mensaje de éxito';
@override
String get devTestsErrorMessage => 'Este es un mensaje de error';
@override
String get devTestsWarningMessage => 'Este es un mensaje de advertencia';
@override
String get devTestsInfoMessage => 'Este es un mensaje informativo';
@override
String get serverListTitle => 'Mis servidores';
@override
String get serverListEmpty => 'Sin servidores';
@override
String get serverListEmptySubtitle =>
'Añade tu primer servidor OPDS para empezar a explorar y leer';
@override
String get serverListOffline =>
'No hay conexión. Conéctate a internet para explorar servidores.';
@override
String serverListErrorLoading(String error) {
return 'Error al cargar servidores: $error';
}
@override
String get serverListRetry => 'Reintentar';
@override
String get serverListAddServer => 'Añadir servidor';
@override
String get serverDeleteTitle => 'Eliminar servidor';
@override
String serverDeleteConfirmation(String name) {
return '¿Seguro que quieres eliminar \"$name\"?';
}
@override
String serverDeleted(String name) {
return '$name eliminado';
}
@override
String get addServerTitle => 'Añadir servidor';
@override
String get addServerNameLabel => 'Nombre del servidor';
@override
String get addServerNameHint => 'Mi biblioteca';
@override
String get addServerUrlLabel => 'URL del servidor';
@override
String get addServerUrlHint => 'https://ejemplo.com/opds';
@override
String get addServerUrlHintKavita => 'https://kavita.ejemplo.com';
@override
String get addServerServerType => 'Tipo de servidor';
@override
String get addServerServerTypeSubtitle =>
'Detectado automáticamente desde la URL. Cambia si es necesario.';
@override
String get serverTypeGeneric => 'OPDS genérico';
@override
String get serverTypeKavita => 'Kavita';
@override
String get addServerAuth => 'Autenticación';
@override
String get addServerAuthSubtitle => 'Credenciales para acceder al servidor';
@override
String get addServerRequiresAuth => 'Requiere autenticación';
@override
String get addServerRequiresAuthSubtitle =>
'Activar si el servidor requiere inicio de sesión';
@override
String get addServerUsername => 'Usuario';
@override
String get addServerPassword => 'Contraseña';
@override
String get addServerValidationNameRequired =>
'Introduce un nombre de servidor';
@override
String get addServerValidationUrlRequired => 'Introduce una URL de servidor';
@override
String get addServerValidationUrlInvalid => 'Introduce una URL válida';
@override
String get addServerValidationUrlScheme =>
'La URL debe empezar con http:// o https://';
@override
String get addServerValidationUsernameRequired =>
'Introduce un nombre de usuario';
@override
String get addServerValidationPasswordRequired => 'Introduce una contraseña';
@override
String get addServerHelp =>
'Introduce la URL raíz de tu servidor OPDS. Las credenciales se almacenarán de forma segura en tu dispositivo.';
@override
String get testConnectionButton => 'Probar conexión';
@override
String get testConnectionTesting => 'Probando...';
@override
String get testConnectionSuccess => '¡Conexión exitosa!';
@override
String testConnectionError(String error) {
return 'Conexión fallida: $error';
}
@override
String get addServerButton => 'Añadir servidor';
@override
String get addServerDuplicate => 'Ya existe un servidor con esta URL';
@override
String addServerSuccess(String name) {
return '$name añadido correctamente';
}
@override
String addServerError(String error) {
return 'Error al añadir servidor: $error';
}
@override
String get editServerTitle => 'Editar servidor';
@override
String get editServerNotFound => 'Servidor no encontrado';
@override
String get editServerInfo => 'Información del servidor';
@override
String get editServerAdded => 'Añadido';
@override
String get editServerLastSynced => 'Última sincronización';
@override
String get editServerSaveButton => 'Guardar cambios';
@override
String editServerSuccess(String name) {
return '$name actualizado correctamente';
}
@override
String editServerError(String error) {
return 'Error al actualizar servidor: $error';
}
@override
String editServerErrorLoading(String error) {
return 'Error al cargar servidor: $error';
}
@override
String get readerError => 'Error';
@override
String get readerNoStreamLink =>
'Esta publicación no se puede leer (sin enlace de transmisión)';
@override
String get readerServerNotFound => 'Servidor no encontrado';
@override
String readerErrorLoadingServer(String error) {
return 'Error al cargar servidor: $error';
}
@override
String readerReadingDirectionWithMode(String mode) {
return 'Dirección de lectura ($mode)';
}
@override
String readerPageOf(int current, int total) {
return 'Página $current de $total';
}
@override
String readerPagesOf(int start, int end, int total) {
return 'Páginas $start-$end de $total';
}
@override
String get epubPreparing => 'Preparando...';
@override
String get epubLoadingFromCache => 'Cargando desde caché...';
@override
String epubDownloading(int percent) {
return 'Descargando... $percent%';
}
@override
String get epubProcessing => 'Procesando EPUB...';
@override
String get epubOpeningReader => 'Abriendo lector...';
@override
String epubErrorLoading(String error) {
return 'Error al cargar EPUB: $error';
}
@override
String get epubGoBack => 'Volver';
@override
String get epubSearch => 'Buscar';
@override
String get epubSearchHint => 'Introduce un término de búsqueda...';
@override
String get epubNoResults => 'No se encontraron resultados';
@override
String epubSearchResults(int count, String query) {
return '$count resultados para \"$query\"';
}
@override
String epubSearchFailed(String error) {
return 'Error en la búsqueda: $error';
}
@override
String get epubChapters => 'Capítulos';
@override
String get epubBack => 'Atrás';
@override
String get epubSettings => 'Ajustes';
@override
String get epubFontSize => 'Tamaño de fuente';
@override
String get epubFontSizeReset => 'Restablecer';
@override
String get libraryTitle => 'Biblioteca';
@override
String get libraryRecentlyRead => 'Leídos recientemente';
@override
String get libraryNoServers => 'Sin servidores configurados';
@override
String get libraryNoServersSubtitle =>
'Añade un servidor OPDS para empezar a leer libros';
@override
String get libraryAddServer => 'Añadir servidor';
@override
String get libraryNoHistory => 'Sin historial de lectura';
@override
String get libraryNoHistorySubtitle =>
'Empieza a leer un libro para verlo aquí';
@override
String get libraryBrowseServers => 'Explorar servidores';
@override
String get libraryErrorLoading => 'Error al cargar la biblioteca';
@override
String get browserLoading => 'Cargando...';
@override
String get browserLibrary => 'Biblioteca';
@override
String get browserNoContent => 'Sin contenido disponible';
@override
String get browserLibraryEmpty => 'Esta biblioteca parece estar vacía';
@override
String get browserCollectionEmpty => 'Esta colección parece estar vacía';
@override
String get browserFailedToLoadLibrary => 'Error al cargar la biblioteca';
@override
String get browserFailedToLoadFeed => 'Error al cargar el feed';
@override
String get browserRetry => 'Reintentar';
@override
String browserFailedToLoadMore(String error) {
return 'Error al cargar más: $error';
}
@override
String get browserOfflineEpubNotCached =>
'Este EPUB no está en caché. Es posible que no puedas leerlo sin conexión.';
@override
String get browserOfflinePagesWarning =>
'No hay conexión. Las páginas podrían no cargarse correctamente.';
@override
String publicationPages(int count) {
return '$count páginas';
}
@override
String get publicationReadingProgress => 'Progreso de lectura';
@override
String publicationPageOfTotal(int current, int total) {
return 'Página $current de $total';
}
@override
String publicationLastRead(String time) {
return 'Última lectura: $time';
}
@override
String get publicationCannotRead =>
'Esta publicación no se puede leer en la aplicación';
@override
String publicationContinueFromPage(int page) {
return 'Continuar leyendo desde la página $page';
}
@override
String get publicationStartReading => 'Empezar a leer';
@override
String get publicationContinueReading => 'Continuar leyendo';
@override
String get publicationReadAgain => 'Leer de nuevo';
@override
String get publicationStartFromBeginning => 'Empezar desde el principio';
@override
String get publicationCollection => 'Colección';
@override
String get recentlyReadPublicationNotFound => 'Publicación no encontrada';
@override
String get recentlyReadErrorLoading => 'Error al cargar la publicación';
@override
String get recentlyReadViewRawData => 'Ver datos sin procesar';
@override
String get recentlyReadRemove => 'Eliminar de leídos recientes';
@override
String get recentlyReadRemoveTitle => 'Eliminar de leídos recientes';
@override
String recentlyReadRemoveConfirmation(String title) {
return '¿Eliminar \"$title\" de tu historial de lectura?\n\nEsto no eliminará el libro de tu biblioteca.';
}
@override
String get recentlyReadRemoved => 'Eliminado de leídos recientes';
@override
String recentlyReadRemoveFailed(String error) {
return 'Error al eliminar: $error';
}
@override
String get recentlyReadRawData => 'Datos sin procesar';
@override
String get recentlyReadOfflineEpubNotCached =>
'Este EPUB no está en caché. Conéctate a internet para descargarlo.';
@override
String get recentlyReadOfflinePagesWarning =>
'No hay conexión. Las páginas podrían no cargarse.';
@override
String get recentlyReadUnsupportedFormat => 'Formato no compatible';
@override
String get serverCardEdit => 'Editar';
@override
String get serverCardDelete => 'Eliminar';
@override
String get serverCardAuthenticated => 'Autenticado';
@override
String serverCardLastSynced(String time) {
return 'Última sincronización: $time';
}
@override
String get offlineSemanticLabel => 'Sin conexión';
@override
String get nextInSeriesNext => 'Siguiente';
@override
String get nextInSeriesFinished => 'Terminado';
@override
String get nextInSeriesBackToDetails => 'Volver a detalles';
@override
String get nextInSeriesBackToLibrary => 'Volver a la biblioteca';
@override
String routeNotFound(String uri) {
return 'Página no encontrada: $uri';
}
@override
String get commonCancel => 'Cancelar';
@override
String get commonDelete => 'Eliminar';
@override
String get commonRemove => 'Eliminar';
@override
String get timeJustNow => 'ahora mismo';
@override
String timeMinutesAgo(int minutes) {
return 'hace $minutes min';
}
@override
String timeHoursAgo(int hours) {
return 'hace $hours h';
}
@override
String timeDaysAgo(int days) {
return 'hace $days d';
}
@override
String timeWeeksAgo(int weeks) {
return 'hace $weeks sem';
}
@override
String timeMonthsAgo(int months) {
return 'hace $months mes(es)';
}
@override
String timeYearsAgo(int years) {
return 'hace $years año(s)';
}
@override
String get timeToday => 'Hoy';
@override
String get timeYesterday => 'Ayer';
@override
String timeMinAgo(int minutes) {
return 'hace $minutes min';
}
@override
String timeHoursAgoLong(int count) {
String _temp0 = intl.Intl.pluralLogic(
count,
locale: localeName,
other: 'horas',
one: 'hora',
);
return 'hace $count $_temp0';
}
@override
String timeDaysAgoLong(int days) {
return 'hace $days días';
}
@override
String get downloadAll => 'Descargar todo';
@override
String get downloadChapter => 'Descargar capítulo';
@override
String get downloadCancel => 'Cancelar descarga';
@override
String get downloadDelete => 'Eliminar descarga';
@override
String get downloadDeleteSeries => 'Eliminar serie descargada';
@override
String downloadDeleteSeriesConfirmation(String title) {
return '¿Eliminar \"$title\" y todos sus archivos descargados? Esta acción no se puede deshacer.';
}
@override
String downloadDeleteChapterConfirmation(String title) {
return '¿Eliminar el archivo descargado de \"$title\"?';
}
@override
String get downloadStarting => 'Iniciando descarga...';
@override
String get downloadComplete => 'Descarga completada';
@override
String get downloadFailed => 'Error en la descarga';
@override
String get downloadCancelled => 'Descarga cancelada';
@override
String get downloadInProgress => 'Descargando...';
@override
String downloadChaptersCount(int downloaded, int total) {
return '$downloaded/$total capítulos';
}
@override
String get downloadConfirmTitle => 'Descargar serie';
@override
String downloadConfirmMessage(int count) {
return '¿Descargar $count capítulos para lectura sin conexión?';
}
@override
String get downloadConfirmStart => 'Descargar';
@override
String get libraryDownloaded => 'Descargados';
@override
String get libraryNoDownloads => 'Sin descargas';
@override
String get libraryNoDownloadsSubtitle =>
'Descarga series desde la pantalla de exploración para leer sin conexión';
@override
String get downloadedSeriesDetailTitle => 'Serie descargada';
@override
String downloadedSeriesChapters(int count) {
return '$count capítulos';
}
@override
String get downloadedChapterReady => 'Listo para leer';
@override
String get downloadedChapterPending => 'Pendiente';
@override
String get downloadedChapterFailed => 'Error';
@override
String get downloadRetryAll => 'Reintentar todos los fallidos';
@override
String get downloadRetryFailed => 'Error - toca para reintentar';
@override
String downloadingPages(int downloaded, int total) {
return 'Página $downloaded/$total';
}
@override
String downloadFailedCount(int count) {
return '$count fallidos';
}
@override
String get settingsDownloadedContent => 'Contenido descargado';
@override
String get settingsDownloadedContentSubtitle =>
'Gestionar descargas sin conexión';
@override
String get settingsClearAllDownloads => 'Borrar todas las descargas';
@override
String get settingsClearAllDownloadsConfirmation =>
'¿Eliminar todo el contenido descargado? Esta acción no se puede deshacer.';
@override
String settingsDownloadSize(String size) {
return 'Usando $size';
}
@override
String get settingsDownloadsCleared => 'Todas las descargas eliminadas';
}