diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 851b74c4..551c889a 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -14,9 +14,8 @@ if (keystorePropertiesFile.exists()) { keystoreProperties.load(FileInputStream(keystorePropertiesFile)) } - android { - namespace ="com.resonate.resonate" + namespace = "com.resonate.resonate" compileSdk = 36 ndkVersion = "28.0.12433566" @@ -30,35 +29,41 @@ android { jvmTarget = "21" } -val projectId: String = System.getenv("APPWRITE_PROJECT_ID") ?: "resonate" -println("PROJECT_ID: $projectId") + val projectId: String = System.getenv("APPWRITE_PROJECT_ID") ?: "resonate" + println("PROJECT_ID: $projectId") + defaultConfig { - // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId = "com.resonate.resonate" - // You can update the following values to match your application needs. - // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. minSdk = flutter.minSdkVersion targetSdk = flutter.targetSdkVersion versionCode = flutter.versionCode.toInt() versionName = flutter.versionName - manifestPlaceholders += mapOf("auth0Domain" to "dev-5w4x3qxvszw8f0u6.us.auth0.com", "auth0Scheme" to "resonate", "PROJECT_ID" to projectId ) + manifestPlaceholders += mapOf( + "auth0Domain" to "dev-5w4x3qxvszw8f0u6.us.auth0.com", + "auth0Scheme" to "resonate", + "PROJECT_ID" to projectId + ) } - buildTypes { - signingConfigs { + // Move signingConfigs to the top level (inside android) + signingConfigs { create("release") { - keyAlias = keystoreProperties["keyAlias"] as String - keyPassword = keystoreProperties["keyPassword"] as String + // Safely read properties, providing fallbacks or throwing clear errors + keyAlias = keystoreProperties["keyAlias"] as? String + ?: throw GradleException("Missing keyAlias in key.properties") + keyPassword = keystoreProperties["keyPassword"] as? String + ?: throw GradleException("Missing keyPassword in key.properties") storeFile = keystoreProperties["storeFile"]?.let { file(it) } - storePassword = keystoreProperties["storePassword"] as String + ?: throw GradleException("Missing storeFile in key.properties") + storePassword = keystoreProperties["storePassword"] as? String + ?: throw GradleException("Missing storePassword in key.properties") } } + + buildTypes { release { - // TODO: Add your own signing config for the release build. - // Signing with the debug keys for now, so `flutter run --release` works. isMinifyEnabled = false isShrinkResources = false - signingConfig = signingConfigs.getByName("debug") signingConfig = signingConfigs.getByName("release") } } @@ -69,7 +74,7 @@ flutter { } dependencies { - coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4") - implementation("androidx.window:window:1.0.0") - implementation("androidx.window:window-java:1.0.0") -} + coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4") + implementation("androidx.window:window:1.0.0") + implementation("androidx.window:window-java:1.0.0") +} \ No newline at end of file diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index a342efd7..cf93fd3c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -8,6 +8,7 @@ hi en + es gu kn mr diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb new file mode 100644 index 00000000..af944781 --- /dev/null +++ b/lib/l10n/app_es.arb @@ -0,0 +1,1761 @@ +{ + "@@locale": "es", + "title": "Resonate", + "@title": { + "description": "El título de la aplicación." + }, + "roomDescription": "Sé educado y respeta la opinión de los demás. Evita comentarios groseros.", + "@roomDescription": { + "description": "Mensaje de guía para los usuarios en una sala de chat." + }, + "hidePassword": "Ocultar contraseña", + "@hidePassword": { + "description": "Texto del botón para ocultar el campo de contraseña." + }, + "showPassword": "Mostrar contraseña", + "@showPassword": { + "description": "Texto del botón para revelar el campo de contraseña." + }, + "passwordEmpty": "La contraseña no puede estar vacía", + "@passwordEmpty": { + "description": "Mensaje de error cuando el campo de contraseña está vacío." + }, + "password": "Contraseña", + "@password": { + "description": "Etiqueta para el campo de entrada de contraseña." + }, + "confirmPassword": "Confirmar contraseña", + "@confirmPassword": { + "description": "Etiqueta para el campo de confirmación de contraseña." + }, + "passwordsNotMatch": "Las contraseñas no coinciden", + "@passwordsNotMatch": { + "description": "Mensaje de error cuando la contraseña y su confirmación no coinciden." + }, + "userCreatedStories": "Historias creadas por el usuario", + "@userCreatedStories": { + "description": "Encabezado para la sección que muestra las historias creadas por otro usuario." + }, + "yourStories": "Tus historias", + "@yourStories": { + "description": "Encabezado para la sección que muestra las historias creadas por el usuario actual." + }, + "userNoStories": "El usuario no ha creado ninguna historia", + "@userNoStories": { + "description": "Mensaje mostrado al ver el perfil de otro usuario y no tiene historias." + }, + "youNoStories": "No has creado ninguna historia", + "@youNoStories": { + "description": "Mensaje mostrado en el perfil del usuario actual cuando no tiene historias." + }, + "follow": "Seguir", + "@follow": { + "description": "Texto del botón para seguir a un usuario." + }, + "editProfile": "Editar perfil", + "@editProfile": { + "description": "Texto del botón para navegar a la pantalla de edición de perfil." + }, + "verifyEmail": "Verificar correo", + "@verifyEmail": { + "description": "Texto del botón o enlace para iniciar el proceso de verificación de correo electrónico." + }, + "verified": "Verificado", + "@verified": { + "description": "Etiqueta de estado que indica que el correo del usuario ha sido verificado." + }, + "profile": "Perfil", + "@profile": { + "description": "Etiqueta para la sección o página de perfil del usuario." + }, + "userLikedStories": "Historias que le gustan al usuario", + "@userLikedStories": { + "description": "Encabezado para la sección que muestra las historias que le gustan a otro usuario." + }, + "yourLikedStories": "Historias que te gustan", + "@yourLikedStories": { + "description": "Encabezado para la sección que muestra las historias que le gustan al usuario actual." + }, + "userNoLikedStories": "Al usuario no le ha gustado ninguna historia", + "@userNoLikedStories": { + "description": "Mensaje mostrado al ver el perfil de otro usuario y no tiene historias que le gusten." + }, + "youNoLikedStories": "No te ha gustado ninguna historia", + "@youNoLikedStories": { + "description": "Mensaje mostrado en el perfil del usuario actual cuando no tiene historias que le gusten." + }, + "live": "En vivo", + "@live": { + "description": "Pestaña o etiqueta para salas de audio en vivo." + }, + "upcoming": "Próximas", + "@upcoming": { + "description": "Pestaña o etiqueta para salas de audio programadas/próximas." + }, + "noAvailableRoom": "{isRoom, select, true{No hay sala disponible} false{No hay salas próximas disponibles} other{No hay información de sala disponible}}\n¡Empieza añadiendo una abajo!", + "@noAvailableRoom": { + "description": "Mensaje cuando no hay sala o sala próxima disponible, con una llamada a la acción.", + "placeholders": { + "isRoom": { + "type": "String", + "example": "true" + } + } + }, + "user1": "Usuario 1", + "@user1": { + "description": "Nombre genérico de marcador de posición para un usuario." + }, + "user2": "Usuario 2", + "@user2": { + "description": "Segundo nombre genérico de marcador de posición para un usuario." + }, + "you": "Tú", + "@you": { + "description": "Etiqueta para identificar al usuario actual en una lista o chat." + }, + "areYouSure": "¿Estás seguro?", + "@areYouSure": { + "description": "Título de la ventana de confirmación." + }, + "loggingOut": "Estás cerrando sesión en Resonate.", + "@loggingOut": { + "description": "Mensaje de confirmación para cerrar sesión." + }, + "yes": "Sí", + "@yes": { + "description": "Texto genérico del botón de confirmación." + }, + "no": "No", + "@no": { + "description": "Texto genérico del botón de cancelación." + }, + "incorrectEmailOrPassword": "Correo o contraseña incorrectos", + "@incorrectEmailOrPassword": { + "description": "Mensaje de error para intento de inicio de sesión fallido." + }, + "passwordShort": "La contraseña tiene menos de 8 caracteres", + "@passwordShort": { + "description": "Mensaje de error para una contraseña demasiado corta." + }, + "tryAgain": "¡Inténtalo de nuevo!", + "@tryAgain": { + "description": "Texto del botón para reintentar una acción fallida." + }, + "success": "Éxito", + "@success": { + "description": "Título genérico para una operación exitosa." + }, + "passwordResetSent": "¡Correo de restablecimiento de contraseña enviado!", + "@passwordResetSent": { + "description": "Mensaje de éxito después de enviar un correo para restablecer la contraseña." + }, + "error": "Error", + "@error": { + "description": "Título genérico para una operación fallida." + }, + "resetPassword": "Restablecer contraseña", + "@resetPassword": { + "description": "Título o texto del botón para la función de restablecer contraseña." + }, + "enterNewPassword": "Ingresa tu nueva contraseña", + "@enterNewPassword": { + "description": "Texto instructivo en la pantalla de restablecimiento de contraseña." + }, + "newPassword": "Nueva contraseña", + "@newPassword": { + "description": "Etiqueta para el campo de entrada de nueva contraseña." + }, + "setNewPassword": "Establecer nueva contraseña", + "@setNewPassword": { + "description": "Texto del botón para confirmar el establecimiento de una nueva contraseña." + }, + "emailChanged": "Correo cambiado", + "@emailChanged": { + "description": "Título del diálogo de éxito después de un cambio de correo." + }, + "emailChangeSuccess": "¡Correo cambiado exitosamente!", + "@emailChangeSuccess": { + "description": "Mensaje de éxito después de cambiar el correo del usuario." + }, + "failed": "Fallido", + "@failed": { + "description": "Título genérico para una operación fallida." + }, + "emailChangeFailed": "No se pudo cambiar el correo", + "@emailChangeFailed": { + "description": "Mensaje de error cuando falla la operación de cambio de correo." + }, + "oops": "¡Ups!", + "@oops": { + "description": "Título informal para un mensaje de error o advertencia." + }, + "emailExists": "El correo ya existe", + "@emailExists": { + "description": "Mensaje de error cuando un usuario intenta registrarse o cambiar a un correo que ya está en uso." + }, + "changeEmail": "Cambiar correo", + "@changeEmail": { + "description": "Título o texto del botón para la función de cambiar correo." + }, + "enterValidEmail": "Por favor ingresa una dirección de correo válida", + "@enterValidEmail": { + "description": "Mensaje de error para un formato de correo inválido." + }, + "newEmail": "Nuevo correo", + "@newEmail": { + "description": "Etiqueta para el campo de entrada de nuevo correo." + }, + "currentPassword": "Contraseña actual", + "@currentPassword": { + "description": "Etiqueta para el campo de entrada de contraseña actual, usado para verificación." + }, + "emailChangeInfo": "Por seguridad adicional, debes proporcionar la contraseña actual de tu cuenta al cambiar tu dirección de correo. Después de cambiar el correo, usa el correo actualizado para futuros inicios de sesión.", + "@emailChangeInfo": { + "description": "Texto informativo que explica el proceso y los requisitos de seguridad para cambiar una dirección de correo para usuarios estándar." + }, + "oauthUsersMessage": "(Solo para usuarios que iniciaron sesión con Google o Github)", + "@oauthUsersMessage": { + "description": "Mensaje para especificar que las siguientes instrucciones son para usuarios OAuth." + }, + "oauthUsersEmailChangeInfo": "Para cambiar tu correo, ingresa una nueva contraseña en el campo \"Contraseña actual\". Asegúrate de recordar esta contraseña, ya que la necesitarás para futuros cambios de correo. En adelante, puedes iniciar sesión usando Google/GitHub o tu nueva combinación de correo y contraseña.", + "@oauthUsersEmailChangeInfo": { + "description": "Texto informativo que explica cómo los usuarios que se registraron con Google o GitHub pueden cambiar su correo estableciendo una nueva contraseña." + }, + "resonateTagline": "Entra en un mundo de conversaciones\nsin límites.", + "@resonateTagline": { + "description": "El lema de la aplicación, usado en pantallas de inicio o inicio de sesión." + }, + "signInWithEmail": "Iniciar sesión con correo", + "@signInWithEmail": { + "description": "Texto del botón para iniciar sesión usando correo y contraseña." + }, + "or": "O", + "@or": { + "description": "Texto separador, típicamente usado entre diferentes opciones de inicio de sesión." + }, + "continueWith": "Continuar con", + "@continueWith": { + "description": "Texto informativo que precede a una lista de proveedores de inicio de sesión de terceros." + }, + "continueWithGoogle": "Continuar con Google", + "@continueWithGoogle": { + "description": "Texto del botón para iniciar sesión con una cuenta de Google." + }, + "continueWithGitHub": "Continuar con GitHub", + "@continueWithGitHub": { + "description": "Texto del botón para iniciar sesión con una cuenta de GitHub." + }, + "resonateLogo": "Logo de Resonate", + "@resonateLogo": { + "description": "Texto de accesibilidad para el logo de la aplicación Resonate." + }, + "iAlreadyHaveAnAccount": "Ya tengo una cuenta", + "@iAlreadyHaveAnAccount": { + "description": "Texto para un enlace o botón que navega a la pantalla de inicio de sesión desde la pantalla de registro." + }, + "createNewAccount": "Crear nueva cuenta", + "@createNewAccount": { + "description": "Texto para un enlace o botón que navega a la pantalla de registro desde la pantalla de inicio de sesión." + }, + "userProfile": "Perfil de usuario", + "@userProfile": { + "description": "Texto de accesibilidad para la foto de perfil o avatar de un usuario." + }, + "passwordIsStrong": "La contraseña es segura", + "@passwordIsStrong": { + "description": "Mensaje de validación que indica que la contraseña ingresada cumple con todos los requisitos de seguridad." + }, + "admin": "Administrador", + "@admin": { + "description": "Etiqueta para el rol de Administrador en una sala." + }, + "moderator": "Moderador", + "@moderator": { + "description": "Etiqueta para el rol de Moderador en una sala." + }, + "speaker": "Orador", + "@speaker": { + "description": "Etiqueta para el rol de Orador en una sala." + }, + "listener": "Oyente", + "@listener": { + "description": "Etiqueta para el rol de Oyente en una sala." + }, + "removeModerator": "Quitar moderador", + "@removeModerator": { + "description": "Texto del elemento de menú para revocar privilegios de moderador a un usuario." + }, + "kickOut": "Expulsar", + "@kickOut": { + "description": "Texto del elemento de menú para eliminar a un usuario de una sala." + }, + "addModerator": "Agregar moderador", + "@addModerator": { + "description": "Texto del elemento de menú para otorgar privilegios de moderador a un usuario." + }, + "addSpeaker": "Agregar orador", + "@addSpeaker": { + "description": "Texto del elemento de menú para otorgar privilegios de orador a un oyente." + }, + "makeListener": "Hacer oyente", + "@makeListener": { + "description": "Texto del elemento de menú para cambiar el rol de un orador a oyente." + }, + "pairChat": "Chat por parejas", + "@pairChat": { + "description": "Nombre de una función de chat aleatorio uno a uno." + }, + "chooseIdentity": "Elegir identidad", + "@chooseIdentity": { + "description": "Solicitud para que el usuario elija su identidad, por ejemplo, anónimo o público." + }, + "selectLanguage": "Seleccionar idioma", + "@selectLanguage": { + "description": "Etiqueta para la configuración de selección de idioma." + }, + "noConnection": "Sin conexión", + "@noConnection": { + "description": "Título que indica que no hay conexión a internet." + }, + "loadingDialog": "Diálogo de carga", + "@loadingDialog": { + "description": "Texto de accesibilidad para un indicador de carga o spinner." + }, + "createAccount": "Crear cuenta", + "@createAccount": { + "description": "Texto del botón o título de la pantalla para la creación de cuenta." + }, + "enterValidEmailAddress": "Ingresa una dirección de correo válida", + "@enterValidEmailAddress": { + "description": "Mensaje de error mostrado para un formato de correo inválido." + }, + "email": "Correo", + "@email": { + "description": "Etiqueta para el campo de entrada de correo." + }, + "passwordRequirements": "La contraseña debe tener al menos 8 caracteres", + "@passwordRequirements": { + "description": "Texto instructivo que enumera los requisitos para una contraseña válida, parte 1." + }, + "includeNumericDigit": "Incluir al menos un dígito numérico", + "@includeNumericDigit": { + "description": "Texto instructivo que enumera los requisitos para una contraseña válida, parte 2." + }, + "includeUppercase": "Incluir al menos una letra mayúscula", + "@includeUppercase": { + "description": "Texto instructivo que enumera los requisitos para una contraseña válida, parte 3." + }, + "includeLowercase": "Incluir al menos una letra minúscula", + "@includeLowercase": { + "description": "Texto instructivo que enumera los requisitos para una contraseña válida, parte 4." + }, + "includeSymbol": "Incluir al menos un símbolo", + "@includeSymbol": { + "description": "Texto instructivo que enumera los requisitos para una contraseña válida, parte 5." + }, + "signedUpSuccessfully": "Registro exitoso", + "@signedUpSuccessfully": { + "description": "Título para un mensaje de éxito después de la creación de cuenta." + }, + "newAccountCreated": "Has creado una nueva cuenta exitosamente", + "@newAccountCreated": { + "description": "Mensaje de éxito que confirma que se ha creado una nueva cuenta." + }, + "signUp": "Registrarse", + "@signUp": { + "description": "Texto del botón para enviar el formulario de registro." + }, + "login": "Iniciar sesión", + "@login": { + "description": "Texto del botón para enviar el formulario de inicio de sesión." + }, + "settings": "Configuración", + "@settings": { + "description": "Título para la página de configuración." + }, + "accountSettings": "Configuración de la cuenta", + "@accountSettings": { + "description": "Subencabezado para configuraciones relacionadas con la cuenta." + }, + "account": "Cuenta", + "@account": { + "description": "Etiqueta para la sección de configuración de la cuenta." + }, + "appSettings": "Configuración de la app", + "@appSettings": { + "description": "Subencabezado para configuraciones relacionadas con la aplicación." + }, + "themes": "Temas", + "@themes": { + "description": "Etiqueta para la configuración de selección de tema." + }, + "about": "Acerca de", + "@about": { + "description": "Etiqueta para la sección o página 'Acerca de' de la app o una historia." + }, + "other": "Otro", + "@other": { + "description": "Etiqueta de categoría genérica para configuraciones o elementos varios." + }, + "contribute": "Contribuir", + "@contribute": { + "description": "Etiqueta para una sección que anima a los usuarios a contribuir al proyecto." + }, + "appPreferences": "Preferencias de la app", + "@appPreferences": { + "description": "Etiqueta para la página de configuración de preferencias de la aplicación." + }, + "transcriptionModel": "Modelo de transcripción", + "@transcriptionModel": { + "description": "Título de sección para elegir el modelo de IA de transcripción." + }, + "transcriptionModelDescription": "Elige el modelo de IA para la transcripción de voz. Los modelos más grandes son más precisos pero más lentos y requieren más almacenamiento.", + "@transcriptionModelDescription": { + "description": "Texto descriptivo que explica las opciones del modelo de transcripción." + }, + "whisperModelTiny": "Diminuto", + "@whisperModelTiny": { + "description": "Nombre del modelo Whisper AI más pequeño." + }, + "whisperModelTinyDescription": "Más rápido, menos preciso (~39 MB)", + "@whisperModelTinyDescription": { + "description": "Descripción del rendimiento y tamaño del modelo Tiny Whisper." + }, + "whisperModelBase": "Base", + "@whisperModelBase": { + "description": "Nombre del modelo base de Whisper AI." + }, + "whisperModelBaseDescription": "Velocidad y precisión equilibradas (~74 MB)", + "@whisperModelBaseDescription": { + "description": "Descripción del rendimiento y tamaño del modelo Base Whisper." + }, + "whisperModelSmall": "Pequeño", + "@whisperModelSmall": { + "description": "Nombre del modelo pequeño de Whisper AI." + }, + "whisperModelSmallDescription": "Buena precisión, más lento (~244 MB)", + "@whisperModelSmallDescription": { + "description": "Descripción del rendimiento y tamaño del modelo Small Whisper." + }, + "whisperModelMedium": "Mediano", + "@whisperModelMedium": { + "description": "Nombre del modelo mediano de Whisper AI." + }, + "whisperModelMediumDescription": "Alta precisión, más lento (~769 MB)", + "@whisperModelMediumDescription": { + "description": "Descripción del rendimiento y tamaño del modelo Medium Whisper." + }, + "whisperModelLargeV1": "Grande V1", + "@whisperModelLargeV1": { + "description": "Nombre del modelo grande V1 de Whisper AI." + }, + "whisperModelLargeV1Description": "Más preciso, más lento (~1.55 GB)", + "@whisperModelLargeV1Description": { + "description": "Descripción del rendimiento y tamaño del modelo Large V1 Whisper." + }, + "whisperModelLargeV2": "Grande V2", + "@whisperModelLargeV2": { + "description": "Nombre del modelo grande V2 de Whisper AI." + }, + "whisperModelLargeV2Description": "Modelo grande mejorado con mayor precisión (~1.55 GB)", + "@whisperModelLargeV2Description": { + "description": "Descripción del rendimiento y tamaño del modelo Large V2 Whisper." + }, + "modelDownloadInfo": "Los modelos se descargan la primera vez que se usan. Recomendamos usar Base, Pequeño o Mediano. Los modelos grandes requieren dispositivos de gama muy alta.", + "@modelDownloadInfo": { + "description": "Mensaje informativo sobre la descarga del modelo." + }, + "logOut": "Cerrar sesión", + "@logOut": { + "description": "Texto del botón para cerrar la sesión del usuario." + }, + "participants": "Participantes", + "@participants": { + "description": "Etiqueta o título para la lista de participantes en una sala." + }, + "delete": "eliminar", + "@delete": { + "description": "Texto genérico del botón para una acción de eliminar. Parámetro para toRoomAction." + }, + "leave": "salir", + "@leave": { + "description": "Texto genérico del botón para una acción de salir. Parámetro para toRoomAction." + }, + "leaveButton": "Salir", + "@leaveButton": { + "description": "Texto del botón para salir de una sala o conversación." + }, + "findingRandomPartner": "Buscando un compañero aleatorio para ti", + "@findingRandomPartner": { + "description": "Mensaje de estado que se muestra mientras se busca un compañero de chat aleatorio." + }, + "quickFact": "Dato rápido", + "@quickFact": { + "description": "Encabezado para un dato rápido o consejo, a menudo mostrado durante la carga." + }, + "cancel": "Cancelar", + "@cancel": { + "description": "Texto genérico del botón para una acción de cancelar." + }, + "hide": "Eliminar", + "@hide": { + "description": "Texto del botón para eliminar un elemento de la vista." + }, + "removeRoom": "Eliminar sala", + "@removeRoom": { + "description": "Título del diálogo para eliminar una sala próxima." + }, + "removeRoomFromList": "Eliminar de la lista", + "@removeRoomFromList": { + "description": "Texto de información sobre herramientas para el botón de eliminar sala." + }, + "removeRoomConfirmation": "¿Estás seguro de que quieres eliminar esta sala próxima de tu lista?", + "@removeRoomConfirmation": { + "description": "Mensaje de confirmación que pregunta si el usuario quiere eliminar una sala próxima de su lista." + }, + "completeYourProfile": "Completa tu perfil", + "@completeYourProfile": { + "description": "Título de página o indicación para que el usuario termine de configurar su perfil." + }, + "uploadProfilePicture": "Subir foto de perfil", + "@uploadProfilePicture": { + "description": "Texto instructivo o botón para subir una foto de perfil." + }, + "enterValidName": "Ingresa un nombre válido", + "@enterValidName": { + "description": "Mensaje de error para un formato de nombre inválido." + }, + "name": "Nombre", + "@name": { + "description": "Etiqueta para el campo de entrada de nombre." + }, + "username": "Nombre de usuario", + "@username": { + "description": "Etiqueta para el campo de entrada de nombre de usuario." + }, + "enterValidDOB": "Ingresa una fecha de nacimiento válida", + "@enterValidDOB": { + "description": "Mensaje de error para una fecha de nacimiento inválida." + }, + "dateOfBirth": "Fecha de nacimiento", + "@dateOfBirth": { + "description": "Etiqueta para el campo de entrada de fecha de nacimiento." + }, + "forgotPassword": "¿Olvidaste tu contraseña?", + "@forgotPassword": { + "description": "Texto de enlace para usuarios que olvidaron su contraseña." + }, + "next": "Siguiente", + "@next": { + "description": "Texto del botón para continuar al siguiente paso en un proceso." + }, + "noStoriesExist": "No existen historias para presentar", + "@noStoriesExist": { + "description": "Mensaje mostrado cuando no hay historias disponibles en una lista." + }, + "enterVerificationCode": "Ingresa tu\ncódigo de verificación", + "@enterVerificationCode": { + "description": "Solicitud para que el usuario ingrese el código de verificación enviado a su correo." + }, + "verificationCodeSent": "Enviamos un código de verificación de 6 dígitos a\n", + "@verificationCodeSent": { + "description": "Mensaje informando que se ha enviado un código de verificación. La dirección de correo se añade en el código." + }, + "verificationComplete": "Verificación completa", + "@verificationComplete": { + "description": "Título para un mensaje de éxito después de la verificación de correo." + }, + "verificationCompleteMessage": "Felicidades, has verificado tu correo", + "@verificationCompleteMessage": { + "description": "Mensaje de éxito que confirma la verificación de correo." + }, + "verificationFailed": "Verificación fallida", + "@verificationFailed": { + "description": "Título para un mensaje de error cuando falla la verificación." + }, + "otpMismatch": "El OTP no coincide, por favor intenta de nuevo", + "@otpMismatch": { + "description": "Mensaje de error cuando el OTP ingresado es incorrecto." + }, + "otpResent": "OTP reenviado", + "@otpResent": { + "description": "Mensaje de confirmación de que el OTP ha sido reenviado." + }, + "requestNewCode": "Solicitar un nuevo código", + "@requestNewCode": { + "description": "Texto del botón para solicitar un nuevo código de verificación." + }, + "requestNewCodeIn": "Solicitar un nuevo código en", + "@requestNewCodeIn": { + "description": "Texto mostrado antes de un contador regresivo para solicitar un nuevo código." + }, + "clickPictureCamera": "Tomar foto con la cámara", + "@clickPictureCamera": { + "description": "Opción para tomar una nueva foto usando la cámara del dispositivo." + }, + "pickImageGallery": "Elegir imagen de la galería", + "@pickImageGallery": { + "description": "Opción para elegir una imagen existente de la galería del dispositivo." + }, + "deleteMyAccount": "Eliminar mi cuenta", + "@deleteMyAccount": { + "description": "Texto del botón para la función de eliminación de cuenta." + }, + "createNewRoom": "Crear nueva sala", + "@createNewRoom": { + "description": "Texto del botón o título de página para crear una nueva sala de audio." + }, + "pleaseEnterScheduledDateTime": "Por favor ingresa la fecha y hora programadas", + "@pleaseEnterScheduledDateTime": { + "description": "Mensaje de error cuando no se proporciona la fecha y hora programada para una sala." + }, + "scheduleDateTimeLabel": "Fecha y hora programadas", + "@scheduleDateTimeLabel": { + "description": "Etiqueta para el campo de entrada para programar la fecha y hora de una sala." + }, + "enterTags": "Ingresa etiquetas", + "@enterTags": { + "description": "Marcador de posición o etiqueta para el campo de entrada para agregar etiquetas a una sala o historia." + }, + "joinCommunity": "Unirse a la comunidad", + "@joinCommunity": { + "description": "Texto del botón o encabezado para la sección de la comunidad." + }, + "followUsOnX": "Síguenos en X", + "@followUsOnX": { + "description": "Texto del enlace al perfil de la empresa en X (anteriormente Twitter)." + }, + "joinDiscordServer": "Unirse al servidor de Discord", + "@joinDiscordServer": { + "description": "Texto del enlace para unirse al servidor de Discord del proyecto." + }, + "noLyrics": "Sin letra", + "@noLyrics": { + "description": "Mensaje mostrado cuando no hay letra disponible para un archivo de audio." + }, + "noStoriesInCategory": "Actualmente no existen historias en la categoría {categoryName} para presentar", + "@noStoriesInCategory": { + "description": "Mensaje cuando no hay historias en una categoría específica.", + "placeholders": { + "categoryName": { + "type": "String", + "example": "drama" + } + } + }, + "newChapters": "Nuevos capítulos", + "@newChapters": { + "description": "Encabezado o etiqueta para la sección para agregar o ver nuevos capítulos de una historia." + }, + "helpToGrow": "Ayuda a crecer", + "@helpToGrow": { + "description": "Una llamada a la acción pidiendo a los usuarios que ayuden a crecer a la plataforma, a menudo un encabezado para compartir/calificar." + }, + "share": "Compartir", + "@share": { + "description": "Texto del botón para compartir contenido." + }, + "rate": "Calificar", + "@rate": { + "description": "Texto del botón para calificar la aplicación o el contenido." + }, + "aboutResonate": "Acerca de Resonate", + "@aboutResonate": { + "description": "Título para la página 'Acerca de' de la aplicación Resonate." + }, + "description": "Descripción", + "@description": { + "description": "Etiqueta para un campo de descripción." + }, + "confirm": "Confirmar", + "@confirm": { + "description": "Texto genérico del botón para una acción de confirmar." + }, + "classic": "Clásico", + "@classic": { + "description": "Nombre de una opción de tema." + }, + "time": "Tiempo", + "@time": { + "description": "Nombre de una opción de tema." + }, + "vintage": "Vintage", + "@vintage": { + "description": "Nombre de una opción de tema." + }, + "amber": "Ámbar", + "@amber": { + "description": "Nombre de una opción de tema." + }, + "forest": "Bosque", + "@forest": { + "description": "Nombre de una opción de tema." + }, + "cream": "Crema", + "@cream": { + "description": "Nombre de una opción de tema." + }, + "none": "ninguno", + "@none": { + "description": "Texto que representa ninguna selección o ausencia de un valor." + }, + "checkOutGitHub": "Echa un vistazo a nuestro repositorio de GitHub: {url}", + "@checkOutGitHub": { + "description": "Mensaje para compartir el repositorio de GitHub, incluyendo un marcador de posición para la URL.", + "placeholders": { + "url": { + "type": "String", + "example": "https://github.com/AOSSIE-Org/Resonate" + } + } + }, + "aossie": "AOSSIE", + "@aossie": { + "description": "El nombre de la organización." + }, + "aossieLogo": "logo de aossie", + "@aossieLogo": { + "description": "Texto de accesibilidad para el logo de la organización AOSSIE." + }, + "errorLoadPackageInfo": "No se pudo cargar la información del paquete", + "@errorLoadPackageInfo": { + "description": "Mensaje de error cuando la aplicación no puede cargar su información de paquete (por ejemplo, versión)." + }, + "searchFailed": "No se pudieron buscar salas. Por favor intenta de nuevo.", + "@searchFailed": { + "description": "Mensaje de error cuando falla la búsqueda de salas." + }, + "updateAvailable": "Actualización disponible", + "@updateAvailable": { + "description": "Título que indica que hay una nueva versión de la aplicación disponible." + }, + "newVersionAvailable": "¡Una nueva versión está disponible!", + "@newVersionAvailable": { + "description": "Mensaje informando al usuario sobre una actualización disponible." + }, + "upToDate": "Actualizado", + "@upToDate": { + "description": "Título que indica que la aplicación está en la última versión." + }, + "latestVersion": "Estás usando la versión más reciente", + "@latestVersion": { + "description": "Mensaje que confirma que el usuario tiene la última versión de la aplicación." + }, + "profileCreatedSuccessfully": "Perfil creado exitosamente", + "@profileCreatedSuccessfully": { + "description": "Mensaje de éxito después de que se crea el perfil de un usuario." + }, + "invalidScheduledDateTime": "Fecha y hora programadas inválidas", + "@invalidScheduledDateTime": { + "description": "Mensaje de error para un formato de fecha y hora inválido." + }, + "scheduledDateTimePast": "La fecha y hora programadas no pueden estar en el pasado", + "@scheduledDateTimePast": { + "description": "Mensaje de error cuando el usuario selecciona una fecha y hora pasada para un evento programado." + }, + "joinRoom": "Unirse a la sala", + "@joinRoom": { + "description": "Texto del botón para unirse a una sala de audio." + }, + "unknownUser": "Desconocido", + "@unknownUser": { + "description": "Texto de marcador de posición para un usuario cuyo nombre no está disponible." + }, + "canceled": "cancelado", + "@canceled": { + "description": "Etiqueta de estado que indica que una acción fue cancelada." + }, + "english": "en", + "@english": { + "description": "El código de idioma para inglés." + }, + "emailVerificationRequired": "Verificación de correo requerida", + "@emailVerificationRequired": { + "description": "Título o mensaje que indica que se necesita verificación de correo para continuar." + }, + "verify": "Verificar", + "@verify": { + "description": "Texto del botón para iniciar un proceso de verificación." + }, + "audioRoom": "Sala de audio", + "@audioRoom": { + "description": "Título genérico para una sala de audio." + }, + "toRoomAction": "Para {action} la sala", + "@toRoomAction": { + "description": "Mensaje dinámico para confirmar una acción en una sala, como eliminar o salir.", + "placeholders": { + "action": { + "type": "String", + "example": "eliminar" + } + } + }, + "mailSentMessage": "correo enviado", + "@mailSentMessage": { + "description": "Mensaje de confirmación que indica que se ha enviado un correo." + }, + "disconnected": "desconectado", + "@disconnected": { + "description": "Etiqueta de estado que indica una pérdida de conexión." + }, + "micOn": "micrófono", + "@micOn": { + "description": "Etiqueta de accesibilidad para el botón del micrófono cuando está encendido." + }, + "speakerOn": "altavoz", + "@speakerOn": { + "description": "Etiqueta de accesibilidad para el botón del altavoz cuando está encendido." + }, + "endChat": "finalizar-chat", + "@endChat": { + "description": "Etiqueta de accesibilidad para el botón de finalizar chat/llamada." + }, + "monthJan": "Ene", + "@monthJan": { + "description": "Abreviatura de enero." + }, + "monthFeb": "Feb", + "@monthFeb": { + "description": "Abreviatura de febrero." + }, + "monthMar": "Mar", + "@monthMar": { + "description": "Abreviatura de marzo." + }, + "monthApr": "Abr", + "@monthApr": { + "description": "Abreviatura de abril." + }, + "monthMay": "May", + "@monthMay": { + "description": "Abreviatura de mayo." + }, + "monthJun": "Jun", + "@monthJun": { + "description": "Abreviatura de junio." + }, + "monthJul": "Jul", + "@monthJul": { + "description": "Abreviatura de julio." + }, + "monthAug": "Ago", + "@monthAug": { + "description": "Abreviatura de agosto." + }, + "monthSep": "Sep", + "@monthSep": { + "description": "Abreviatura de septiembre." + }, + "monthOct": "Oct", + "@monthOct": { + "description": "Abreviatura de octubre." + }, + "monthNov": "Nov", + "@monthNov": { + "description": "Abreviatura de noviembre." + }, + "monthDec": "Dic", + "@monthDec": { + "description": "Abreviatura de diciembre." + }, + "register": "Registrarse", + "@register": { + "description": "Texto del botón para registrar una nueva cuenta." + }, + "newToResonate": "¿Nuevo en Resonate? ", + "@newToResonate": { + "description": "Texto que precede al enlace 'Crear nueva cuenta' en la pantalla de inicio de sesión." + }, + "alreadyHaveAccount": "¿Ya tienes una cuenta? ", + "@alreadyHaveAccount": { + "description": "Texto que precede al enlace 'Iniciar sesión' en la pantalla de registro." + }, + "checking": "Verificando...", + "@checking": { + "description": "Mensaje de estado temporal que indica que una verificación está en progreso." + }, + "forgotPasswordMessage": "Ingresa tu dirección de correo registrada para restablecer tu contraseña.", + "@forgotPasswordMessage": { + "description": "Texto instructivo en la pantalla de olvido de contraseña." + }, + "usernameUnavailable": "¡Nombre de usuario no disponible!", + "@usernameUnavailable": { + "description": "Título para el error cuando un nombre de usuario elegido está ocupado." + }, + "usernameInvalidOrTaken": "Este nombre de usuario es inválido o ya está tomado.", + "@usernameInvalidOrTaken": { + "description": "Mensaje de error que explica por qué no se puede usar un nombre de usuario." + }, + "otpResentMessage": "Por favor revisa tu correo para obtener un nuevo OTP.", + "@otpResentMessage": { + "description": "Mensaje informando al usuario que revise su correo para obtener un nuevo OTP." + }, + "connectionError": "Hay un error de conexión. Por favor verifica tu internet e intenta de nuevo.", + "@connectionError": { + "description": "Mensaje de error genérico para problemas de conexión de red." + }, + "seconds": "segundos.", + "@seconds": { + "description": "La palabra 'segundos', a menudo usada después de un número de cuenta regresiva." + }, + "unsavedChangesWarning": "Si continúas sin guardar, los cambios no guardados se perderán.", + "@unsavedChangesWarning": { + "description": "Mensaje de advertencia que se muestra cuando un usuario intenta salir de una pantalla con cambios sin guardar." + }, + "deleteAccountPermanent": "Esta acción eliminará tu cuenta permanentemente. Es un proceso irreversible. Eliminaremos tu nombre de usuario, dirección de correo y todos los demás datos asociados a tu cuenta. No podrás recuperarla.", + "@deleteAccountPermanent": { + "description": "Mensaje de advertencia detallado que explica las consecuencias de eliminar una cuenta." + }, + "giveGreatName": "Dale un gran nombre...", + "@giveGreatName": { + "description": "Texto de marcador de posición para un campo de entrada de nombre, animando a un nombre creativo." + }, + "joinCommunityDescription": "Al unirte a la comunidad puedes aclarar tus dudas, sugerir nuevas funciones, reportar problemas que hayas enfrentado y más.", + "@joinCommunityDescription": { + "description": "Descripción de los beneficios de unirse a la comunidad." + }, + "resonateDescription": "Resonate es una plataforma de redes sociales donde cada voz es valorada. Comparte tus pensamientos, historias y experiencias con otros. Comienza tu viaje de audio ahora. Sumérgete en diversas discusiones y temas. Encuentra salas que resuenen contigo y conviértete en parte de la comunidad. ¡Únete a la conversación! Explora salas, conecta con amigos y comparte tu voz con el mundo.", + "@resonateDescription": { + "description": "Una descripción breve, orientada al usuario, de la aplicación Resonate." + }, + "resonateFullDescription": "Resonate es una plataforma de redes sociales revolucionaria basada en voz donde cada voz importa. \nÚnete a conversaciones de audio en tiempo real, participa en discusiones diversas y conéctate con personas afines. Nuestra plataforma ofrece:\n- Salas de audio en vivo con discusiones basadas en temas\n- Redes sociales fluidas a través de la voz\n- Moderación de contenido impulsada por la comunidad\n- Compatibilidad multiplataforma\n- Conversaciones privadas cifradas de extremo a extremo\n\nDesarrollado por la comunidad de código abierto AOSSIE, priorizamos la privacidad del usuario y el desarrollo impulsado por la comunidad. ¡Únete a nosotros para dar forma al futuro del audio social!", + "@resonateFullDescription": { + "description": "Descripción completa y detallada de la aplicación Resonate, sus características y su misión." + }, + "stable": "Estable", + "@stable": { + "description": "Etiqueta que indica una versión estable, no beta, de la aplicación." + }, + "usernameCharacterLimit": "El nombre de usuario debe contener más de 5 caracteres.", + "@usernameCharacterLimit": { + "description": "Mensaje de error cuando un nombre de usuario elegido es demasiado corto." + }, + "submit": "Enviar", + "@submit": { + "description": "Texto genérico del botón para enviar un formulario." + }, + "anonymous": "Anónimo", + "@anonymous": { + "description": "Etiqueta para un usuario o identidad anónima." + }, + "noSearchResults": "Sin resultados de búsqueda", + "@noSearchResults": { + "description": "Mensaje mostrado cuando una búsqueda no arroja resultados." + }, + "searchRooms": "Buscar salas...", + "@searchRooms": { + "description": "Texto de marcador de posición para el campo de entrada de búsqueda de salas." + }, + "searchingRooms": "Buscando salas...", + "@searchingRooms": { + "description": "Mensaje de carga que se muestra mientras se buscan salas." + }, + "clearSearch": "Limpiar búsqueda", + "@clearSearch": { + "description": "Texto para el botón de limpiar resultados de búsqueda." + }, + "searchError": "Error de búsqueda", + "@searchError": { + "description": "Título para mensajes de error de búsqueda." + }, + "searchRoomsError": "No se pudieron buscar las salas. Por favor intenta de nuevo.", + "@searchRoomsError": { + "description": "Mensaje de error cuando falla la búsqueda de salas." + }, + "searchUpcomingRoomsError": "No se pudieron buscar las salas próximas. Por favor intenta de nuevo.", + "@searchUpcomingRoomsError": { + "description": "Mensaje de error cuando falla la búsqueda de salas próximas." + }, + "search": "Buscar", + "@search": { + "description": "Texto de información sobre herramientas para el botón de búsqueda." + }, + "clear": "Limpiar", + "@clear": { + "description": "Texto de información sobre herramientas para el botón de limpiar." + }, + "shareRoomMessage": "🚀 ¡Echa un vistazo a esta increíble sala: {roomName}!\n\n📖 Descripción: {description}\n👥 ¡Únete a {participants} participantes ahora!", + "@shareRoomMessage": { + "description": "La plantilla de mensaje predeterminada utilizada al compartir una sala.", + "placeholders": { + "roomName": { + "type": "String", + "example": "Sala de discusión" + }, + "description": { + "type": "String", + "example": "Un gran lugar para discutir" + }, + "participants": { + "type": "int", + "example": "5" + } + } + }, + "participantsCount": "{count} Participantes", + "@participantsCount": { + "description": "Muestra el número de participantes en una sala.", + "placeholders": { + "count": { + "type": "int", + "example": "5" + } + } + }, + "join": "Unirse", + "@join": { + "description": "Texto genérico del botón para unirse a una actividad o grupo." + }, + "invalidTags": "Etiqueta inválida:", + "@invalidTags": { + "description": "Prefijo de mensaje de error para una etiqueta inválida." + }, + "cropImage": "Recortar imagen", + "@cropImage": { + "description": "Título o texto del botón para la herramienta de recorte de imagen." + }, + "profileSavedSuccessfully": "Perfil actualizado", + "@profileSavedSuccessfully": { + "description": "Mensaje corto de éxito que indica que los cambios del perfil se han guardado." + }, + "profileUpdatedSuccessfully": "Todos los cambios se guardaron exitosamente.", + "@profileUpdatedSuccessfully": { + "description": "Mensaje de éxito detallado que confirma la actualización del perfil." + }, + "profileUpToDate": "Perfil actualizado", + "@profileUpToDate": { + "description": "Título para el mensaje cuando no hay cambios que guardar en el perfil." + }, + "noChangesToSave": "No se hicieron nuevos cambios, nada que guardar.", + "@noChangesToSave": { + "description": "Mensaje mostrado cuando el usuario intenta guardar su perfil sin realizar cambios." + }, + "connectionFailed": "Conexión fallida", + "@connectionFailed": { + "description": "Título genérico para errores relacionados con la conexión." + }, + "unableToJoinRoom": "No se pudo unir a la sala. Por favor verifica tu red e intenta de nuevo.", + "@unableToJoinRoom": { + "description": "Mensaje de error cuando un usuario no puede unirse a una sala debido a problemas de conexión." + }, + "connectionLost": "Conexión perdida", + "@connectionLost": { + "description": "Título que indica que se perdió la conexión con un servicio." + }, + "unableToReconnect": "No se pudo reconectar a la sala. Por favor intenta volver a unirte.", + "@unableToReconnect": { + "description": "Mensaje de error cuando la aplicación no puede reconectar al usuario a una sala." + }, + "invalidFormat": "¡Formato inválido!", + "@invalidFormat": { + "description": "Mensaje de error genérico para datos con un formato incorrecto." + }, + "usernameAlphanumeric": "El nombre de usuario debe ser alfanumérico y no debe contener caracteres especiales.", + "@usernameAlphanumeric": { + "description": "Mensaje de error que detalla los requisitos de caracteres para un nombre de usuario válido." + }, + "userProfileCreatedSuccessfully": "Tu perfil de usuario se ha creado exitosamente.", + "@userProfileCreatedSuccessfully": { + "description": "Mensaje de éxito después de que un usuario completa la configuración de su perfil." + }, + "emailVerificationMessage": "Para continuar, verifica tu dirección de correo.", + "@emailVerificationMessage": { + "description": "Mensaje instructivo que solicita al usuario que verifique su correo." + }, + "addNewChaptersToStory": "Agregar nuevos capítulos a {storyName}", + "@addNewChaptersToStory": { + "description": "Título para la pantalla donde se agregan nuevos capítulos a una historia existente.", + "placeholders": { + "storyName": { + "type": "String", + "example": "Mi historia" + } + } + }, + "currentChapters": "Capítulos actuales", + "@currentChapters": { + "description": "Encabezado para la lista de capítulos existentes en una historia." + }, + "sourceCodeOnGitHub": "Código fuente en GitHub", + "@sourceCodeOnGitHub": { + "description": "Texto del enlace al código fuente del proyecto en GitHub." + }, + "createAChapter": "Crear un capítulo", + "@createAChapter": { + "description": "Título para la pantalla donde se crea un nuevo capítulo." + }, + "chapterTitle": "Título del capítulo *", + "@chapterTitle": { + "description": "Etiqueta para el campo de entrada del título del capítulo, indicando que es obligatorio." + }, + "aboutRequired": "Acerca de *", + "@aboutRequired": { + "description": "Etiqueta para el campo 'Acerca de' o descripción, indicando que es obligatorio." + }, + "changeCoverImage": "Cambiar imagen de portada", + "@changeCoverImage": { + "description": "Texto del botón para cambiar la imagen de portada de una historia o capítulo." + }, + "uploadAudioFile": "Subir archivo de audio", + "@uploadAudioFile": { + "description": "Texto del botón para subir un archivo de audio." + }, + "uploadLyricsFile": "Subir archivo de letra", + "@uploadLyricsFile": { + "description": "Texto del botón para subir un archivo de letra." + }, + "createChapter": "Crear capítulo", + "@createChapter": { + "description": "Texto del botón para finalizar y crear un nuevo capítulo." + }, + "audioFileSelected": "Archivo de audio seleccionado: {fileName}", + "@audioFileSelected": { + "description": "Mensaje mostrado después de que se ha seleccionado un archivo de audio para subir.", + "placeholders": { + "fileName": { + "type": "String", + "example": "audio.mp3" + } + } + }, + "lyricsFileSelected": "Archivo de letra seleccionado: {fileName}", + "@lyricsFileSelected": { + "description": "Mensaje mostrado después de que se ha seleccionado un archivo de letra para subir.", + "placeholders": { + "fileName": { + "type": "String", + "example": "lyrics.txt" + } + } + }, + "fillAllRequiredFields": "Por favor completa todos los campos obligatorios y sube tu archivo de audio y archivo de letra", + "@fillAllRequiredFields": { + "description": "Mensaje de error cuando faltan campos o archivos obligatorios en un formulario." + }, + "scheduled": "Programada", + "@scheduled": { + "description": "Etiqueta de estado que indica que un evento está programado para el futuro." + }, + "ok": "OK", + "@ok": { + "description": "Texto genérico del botón de confirmación, a menudo para cerrar un diálogo." + }, + "roomDescriptionOptional": "Descripción de la sala (opcional)", + "@roomDescriptionOptional": { + "description": "Etiqueta para el campo de entrada de descripción de la sala, indicando que no es obligatorio." + }, + "deleteAccount": "Eliminar cuenta", + "@deleteAccount": { + "description": "Texto del botón para iniciar el proceso de eliminación de cuenta." + }, + "createYourStory": "Crea tu historia", + "@createYourStory": { + "description": "Título para la pantalla donde se crea una nueva historia." + }, + "titleRequired": "Título *", + "@titleRequired": { + "description": "Etiqueta para el campo de entrada del título, indicando que es obligatorio." + }, + "category": "Categoría *", + "@category": { + "description": "Etiqueta para la selección de categoría, indicando que es obligatorio." + }, + "addChapter": "Agregar capítulo", + "@addChapter": { + "description": "Texto del botón para agregar un capítulo a una historia." + }, + "createStory": "Crear historia", + "@createStory": { + "description": "Texto del botón para finalizar y crear una nueva historia." + }, + "fillAllRequiredFieldsAndChapter": "Por favor completa todos los campos obligatorios, agrega al menos un capítulo y selecciona una imagen de portada.", + "@fillAllRequiredFieldsAndChapter": { + "description": "Mensaje de error para el formulario de creación de historia cuando no se cumplen los requisitos." + }, + "toConfirmType": "Para confirmar, escribe", + "@toConfirmType": { + "description": "Texto instructivo en un diálogo de confirmación, que precede al texto a escribir." + }, + "inTheBoxBelow": "en el cuadro de abajo", + "@inTheBoxBelow": { + "description": "Texto instructivo en un diálogo de confirmación, que sigue al texto a escribir." + }, + "iUnderstandDeleteMyAccount": "Entiendo, eliminar mi cuenta", + "@iUnderstandDeleteMyAccount": { + "description": "La frase específica que el usuario debe escribir para confirmar la eliminación de la cuenta." + }, + "whatDoYouWantToListenTo": "¿Qué quieres escuchar?", + "@whatDoYouWantToListenTo": { + "description": "Un mensaje en la pantalla principal, que anima a la participación del usuario." + }, + "categories": "Categorías", + "@categories": { + "description": "Encabezado para la lista de categorías." + }, + "stories": "Historias", + "@stories": { + "description": "Encabezado para la lista de historias." + }, + "someSuggestions": "Algunas sugerencias", + "@someSuggestions": { + "description": "Encabezado para una lista de contenido sugerido." + }, + "getStarted": "Comenzar", + "@getStarted": { + "description": "Texto del botón en una pantalla de bienvenida para comenzar a usar la aplicación." + }, + "skip": "Omitir", + "@skip": { + "description": "Texto del botón para omitir un paso opcional, como la bienvenida." + }, + "welcomeToResonate": "Bienvenido a Resonate", + "@welcomeToResonate": { + "description": "Título de la pantalla de bienvenida." + }, + "exploreDiverseConversations": "Explora conversaciones diversas", + "@exploreDiverseConversations": { + "description": "Destacado de función en una pantalla de bienvenida." + }, + "yourVoiceMatters": "Tu voz importa", + "@yourVoiceMatters": { + "description": "Destacado de función en una pantalla de bienvenida." + }, + "joinConversationExploreRooms": "¡Únete a la conversación! Explora salas, conecta con amigos y comparte tu voz con el mundo.", + "@joinConversationExploreRooms": { + "description": "Texto descriptivo en una pantalla de bienvenida." + }, + "diveIntoDiverseDiscussions": "Sumérgete en diversas discusiones y temas. \nEncuentra salas que resuenen contigo y conviértete en parte de la comunidad.", + "@diveIntoDiverseDiscussions": { + "description": "Texto descriptivo en una pantalla de bienvenida." + }, + "atResonateEveryVoiceValued": "En Resonate, cada voz es valorada. Comparte tus pensamientos, historias y experiencias con otros. Comienza tu viaje de audio ahora.", + "@atResonateEveryVoiceValued": { + "description": "Texto descriptivo en una pantalla de bienvenida." + }, + "notifications": "Notificaciones", + "@notifications": { + "description": "Título para la pantalla de notificaciones." + }, + "taggedYouInUpcomingRoom": "{username} te mencionó en una sala próxima: {subject}", + "@taggedYouInUpcomingRoom": { + "description": "Mensaje de notificación cuando te mencionan en una sala próxima.", + "placeholders": { + "username": { + "type": "String", + "example": "john_doe" + }, + "subject": { + "type": "String", + "example": "Sala de discusión" + } + } + }, + "taggedYouInRoom": "{username} te mencionó en la sala: {subject}", + "@taggedYouInRoom": { + "description": "Mensaje de notificación cuando te mencionan en una sala en vivo.", + "placeholders": { + "username": { + "type": "String", + "example": "john_doe" + }, + "subject": { + "type": "String", + "example": "Sala de discusión" + } + } + }, + "likedYourStory": "A {username} le gustó tu historia: {subject}", + "@likedYourStory": { + "description": "Mensaje de notificación cuando a alguien le gusta tu historia.", + "placeholders": { + "username": { + "type": "String", + "example": "john_doe" + }, + "subject": { + "type": "String", + "example": "Mi historia" + } + } + }, + "subscribedToYourRoom": "{username} se suscribió a tu sala: {subject}", + "@subscribedToYourRoom": { + "description": "Mensaje de notificación cuando alguien se suscribe a tu sala.", + "placeholders": { + "username": { + "type": "String", + "example": "john_doe" + }, + "subject": { + "type": "String", + "example": "Mi sala" + } + } + }, + "startedFollowingYou": "{username} comenzó a seguirte", + "@startedFollowingYou": { + "description": "Mensaje de notificación cuando alguien comienza a seguirte.", + "placeholders": { + "username": { + "type": "String", + "example": "john_doe" + } + } + }, + "youHaveNewNotification": "Tienes una nueva notificación", + "@youHaveNewNotification": { + "description": "Título genérico para una nueva notificación." + }, + "hangOnGoodThingsTakeTime": "Espera, las cosas buenas toman tiempo 🔍", + "@hangOnGoodThingsTakeTime": { + "description": "Mensaje amigable mostrado durante un proceso de carga largo." + }, + "resonateOpenSourceProject": "Resonate es un proyecto de código abierto mantenido por AOSSIE. Visita nuestro github para contribuir.", + "@resonateOpenSourceProject": { + "description": "Texto informativo sobre la naturaleza de código abierto del proyecto." + }, + "mute": "Silenciar", + "@mute": { + "description": "Texto del botón para silenciar el micrófono." + }, + "speakerLabel": "Altavoz", + "@speakerLabel": { + "description": "Etiqueta para el interruptor del altavoz." + }, + "end": "Terminar", + "@end": { + "description": "Texto del botón para finalizar una llamada o sesión." + }, + "saveChanges": "Guardar cambios", + "@saveChanges": { + "description": "Texto del botón para guardar configuraciones o información de perfil modificadas." + }, + "discard": "DESCARTAR", + "@discard": { + "description": "Texto del botón para descartar cambios." + }, + "save": "GUARDAR", + "@save": { + "description": "Texto del botón para guardar cambios." + }, + "changeProfilePicture": "Cambiar foto de perfil", + "@changeProfilePicture": { + "description": "Texto del botón para abrir las opciones de selección de foto de perfil." + }, + "camera": "Cámara", + "@camera": { + "description": "Opción para usar la cámara y tomar una foto." + }, + "gallery": "Galería", + "@gallery": { + "description": "Opción para elegir una foto de la galería." + }, + "remove": "Eliminar", + "@remove": { + "description": "Texto del botón para eliminar un elemento, como una foto de perfil." + }, + "created": "Creado {date}", + "@created": { + "description": "Muestra la fecha de creación de una historia o contenido.", + "placeholders": { + "date": { + "type": "String", + "example": "15 ene 2023" + } + } + }, + "chapters": "Capítulos", + "@chapters": { + "description": "Encabezado para la lista de capítulos en una historia." + }, + "deleteStory": "Eliminar historia", + "@deleteStory": { + "description": "Texto del botón para eliminar una historia." + }, + "createdBy": "Creado por {creatorName}", + "@createdBy": { + "description": "Muestra el nombre del creador del contenido.", + "placeholders": { + "creatorName": { + "type": "String", + "example": "Juan Pérez" + } + } + }, + "start": "Comenzar", + "@start": { + "description": "Texto del botón para comenzar una actividad o sesión." + }, + "unsubscribe": "Cancelar suscripción", + "@unsubscribe": { + "description": "Texto del botón para cancelar la suscripción a una sala o notificación." + }, + "subscribe": "Suscribirse", + "@subscribe": { + "description": "Texto del botón para suscribirse a una sala o notificación." + }, + "storyCategory": "{category, select, drama{Drama} comedy{Comedia} horror{Terror} romance{Romance} thriller{Suspenso} spiritual{Espiritual} other{Otro}}", + "@storyCategory": { + "description": "Selecciona el nombre de categoría apropiado para una historia basado en una clave.", + "placeholders": { + "category": { + "type": "String", + "example": "drama" + } + } + }, + "chooseTheme": "{category, select, classicTheme{Clásico} timeTheme{Tiempo} vintageTheme{Vintage} amberTheme{Ámbar} forestTheme{Bosque} creamTheme{Crema} other{Otro}}", + "@chooseTheme": { + "description": "Selecciona el nombre de tema apropiado basado en una clave.", + "placeholders": { + "category": { + "type": "String", + "example": "classic" + } + } + }, + "minutesAgo": "{count, plural, =1{hace 1 minuto} other{hace {count} minutos}}", + "@minutesAgo": { + "description": "Muestra el tiempo en formato relativo para minutos.", + "placeholders": { + "count": { + "type": "int", + "example": "5" + } + } + }, + "hoursAgo": "{count, plural, =1{hace 1 hora} other{hace {count} horas}}", + "@hoursAgo": { + "description": "Muestra el tiempo en formato relativo para horas.", + "placeholders": { + "count": { + "type": "int", + "example": "2" + } + } + }, + "daysAgo": "{count, plural, =1{hace 1 día} other{hace {count} días}}", + "@daysAgo": { + "description": "Muestra el tiempo en formato relativo para días.", + "placeholders": { + "count": { + "type": "int", + "example": "3" + } + } + }, + "by": "por", + "@by": { + "description": "Una preposición, típicamente usada entre el título de un contenido y el nombre del autor." + }, + "likes": "Me gusta", + "@likes": { + "description": "Etiqueta para el número de me gusta." + }, + "lengthMinutes": "min", + "@lengthMinutes": { + "description": "Abreviatura de 'minutos', usada para mostrar la duración del audio." + }, + "requiredField": "Campo obligatorio", + "@requiredField": { + "description": "Mensaje de error para un campo obligatorio que se dejó vacío." + }, + "onlineUsers": "Usuarios en línea", + "@onlineUsers": { + "description": "Encabezado para la lista de usuarios que están actualmente en línea." + }, + "noOnlineUsers": "No hay usuarios en línea actualmente", + "@noOnlineUsers": { + "description": "Mensaje mostrado cuando no hay usuarios en línea." + }, + "chooseUser": "Elige un usuario para chatear", + "@chooseUser": { + "description": "Texto instructivo para seleccionar un usuario para iniciar un chat." + }, + "quickMatch": "Emparejamiento rápido", + "@quickMatch": { + "description": "Texto del botón para una función que empareja rápidamente al usuario con un compañero de chat aleatorio." + }, + "story": "Historia", + "@story": { + "description": "Etiqueta para una historia." + }, + "user": "Usuario", + "@user": { + "description": "Etiqueta para un usuario." + }, + "following": "Siguiendo", + "@following": { + "description": "Etiqueta para la lista de usuarios a los que sigue el usuario actual." + }, + "followers": "Seguidores", + "@followers": { + "description": "Etiqueta para la lista de usuarios que siguen al usuario actual." + }, + "friendRequests": "Solicitudes de amistad", + "@friendRequests": { + "description": "Encabezado para la lista de solicitudes de amistad entrantes." + }, + "friendRequestSent": "Solicitud de amistad enviada", + "@friendRequestSent": { + "description": "Título para el mensaje de confirmación después de enviar una solicitud de amistad." + }, + "friendRequestSentTo": "Tu solicitud de amistad a {username} ha sido enviada.", + "@friendRequestSentTo": { + "description": "Mensaje de confirmación después de enviar una solicitud de amistad a un usuario específico.", + "placeholders": { + "username": { + "type": "String", + "example": "john_doe" + } + } + }, + "friendRequestCancelled": "Solicitud de amistad cancelada", + "@friendRequestCancelled": { + "description": "Título para el mensaje de confirmación después de cancelar una solicitud de amistad." + }, + "friendRequestCancelledTo": "Tu solicitud de amistad a {username} ha sido cancelada.", + "@friendRequestCancelledTo": { + "description": "Mensaje de confirmación después de cancelar una solicitud de amistad a un usuario específico.", + "placeholders": { + "username": { + "type": "String", + "example": "john_doe" + } + } + }, + "requested": "Solicitada", + "@requested": { + "description": "Etiqueta de estado en un botón que indica que se ha enviado una solicitud de amistad." + }, + "friends": "Amigos", + "@friends": { + "description": "Etiqueta de estado o encabezado para la lista de amigos." + }, + "addFriend": "Agregar amigo", + "@addFriend": { + "description": "Texto del botón para enviar una solicitud de amistad." + }, + "friendRequestAccepted": "Solicitud de amistad aceptada", + "@friendRequestAccepted": { + "description": "Título para el mensaje de confirmación después de aceptar una solicitud de amistad." + }, + "friendRequestAcceptedTo": "Ahora eres amigo de {username}.", + "@friendRequestAcceptedTo": { + "description": "Mensaje de confirmación después de aceptar una solicitud de amistad de un usuario específico.", + "placeholders": { + "username": { + "type": "String", + "example": "john_doe" + } + } + }, + "friendRequestDeclined": "Solicitud de amistad rechazada", + "@friendRequestDeclined": { + "description": "Título para el mensaje de confirmación después de rechazar una solicitud de amistad." + }, + "friendRequestDeclinedTo": "Has rechazado la solicitud de amistad de {username}.", + "@friendRequestDeclinedTo": { + "description": "Mensaje de confirmación después de rechazar una solicitud de amistad de un usuario específico.", + "placeholders": { + "username": { + "type": "String", + "example": "john_doe" + } + } + }, + "accept": "Aceptar", + "@accept": { + "description": "Texto del botón para aceptar una solicitud o invitación." + }, + "callDeclined": "Llamada rechazada", + "@callDeclined": { + "description": "Título para el mensaje cuando se rechaza una llamada." + }, + "callDeclinedTo": "El usuario {username} rechazó la llamada.", + "@callDeclinedTo": { + "description": "Mensaje que indica que un usuario específico rechazó una llamada.", + "placeholders": { + "username": { + "type": "String", + "example": "john_doe" + } + } + }, + "checkForUpdates": "Buscar actualizaciones", + "@checkForUpdates": { + "description": "Texto del botón para buscar manualmente actualizaciones de la aplicación." + }, + "updateNow": "Actualizar ahora", + "@updateNow": { + "description": "Texto del botón para iniciar el proceso de actualización." + }, + "updateLater": "Más tarde", + "@updateLater": { + "description": "Texto del botón para posponer una actualización." + }, + "updateSuccessful": "Actualización exitosa", + "@updateSuccessful": { + "description": "Título para el mensaje de éxito después de una actualización." + }, + "updateSuccessfulMessage": "¡Resonate se ha actualizado exitosamente!", + "@updateSuccessfulMessage": { + "description": "Mensaje de éxito que confirma que la aplicación se ha actualizado." + }, + "updateCancelled": "Actualización cancelada", + "@updateCancelled": { + "description": "Título para el mensaje cuando se cancela una actualización." + }, + "updateCancelledMessage": "El usuario canceló la actualización", + "@updateCancelledMessage": { + "description": "Mensaje que indica que el usuario canceló el proceso de actualización." + }, + "updateFailed": "Actualización fallida", + "@updateFailed": { + "description": "Título para el mensaje cuando falla una actualización." + }, + "updateFailedMessage": "Error al actualizar. Por favor intenta actualizar manualmente desde Play Store.", + "@updateFailedMessage": { + "description": "Mensaje de error cuando falla una actualización dentro de la aplicación, sugiriendo una actualización manual." + }, + "updateError": "Error de actualización", + "@updateError": { + "description": "Título genérico para un error relacionado con la actualización." + }, + "updateErrorMessage": "Ocurrió un error durante la actualización. Por favor intenta de nuevo.", + "@updateErrorMessage": { + "description": "Mensaje de error genérico para una actualización que falló debido a un error desconocido." + }, + "platformNotSupported": "Plataforma no soportada", + "@platformNotSupported": { + "description": "Título para un error cuando una función no es compatible con la plataforma actual." + }, + "platformNotSupportedMessage": "La verificación de actualizaciones solo está disponible en dispositivos Android", + "@platformNotSupportedMessage": { + "description": "Mensaje que explica que la función de actualización dentro de la aplicación es específica de la plataforma." + }, + "updateCheckFailed": "Error al verificar actualización", + "@updateCheckFailed": { + "description": "Título para un error cuando la aplicación no puede verificar actualizaciones." + }, + "updateCheckFailedMessage": "No se pudo verificar si hay actualizaciones. Por favor intenta de nuevo más tarde.", + "@updateCheckFailedMessage": { + "description": "Mensaje de error cuando falla el proceso de verificación de actualizaciones." + }, + "upToDateTitle": "¡Estás actualizado!", + "@upToDateTitle": { + "description": "Título para el mensaje cuando la aplicación ya está actualizada." + }, + "upToDateMessage": "Estás usando la versión más reciente de Resonate", + "@upToDateMessage": { + "description": "Mensaje que confirma que no se necesita actualización." + }, + "updateAvailableTitle": "¡Actualización disponible!", + "@updateAvailableTitle": { + "description": "Título para el diálogo que informa al usuario sobre una nueva actualización." + }, + "updateAvailableMessage": "Una nueva versión de Resonate está disponible en Play Store", + "@updateAvailableMessage": { + "description": "Mensaje que solicita al usuario actualizar la aplicación desde Play Store." + }, + "updateFeaturesImprovement": "¡Obtén las últimas funciones y mejoras!", + "@updateFeaturesImprovement": { + "description": "Mensaje que destaca el beneficio de actualizar la aplicación." + }, + "failedToRemoveRoom": "Error al eliminar la sala", + "@failedToRemoveRoom": { + "description": "Mensaje de error cuando no se puede eliminar una sala de la lista" + }, + "roomRemovedSuccessfully": "Sala eliminada de tu lista exitosamente", + "@roomRemovedSuccessfully": { + "description": "Mensaje de éxito cuando una sala se elimina correctamente de la lista del usuario" + }, + "alert": "Alerta", + "@alert": { + "description": "Título para un diálogo de alerta." + }, + "removedFromRoom": "Has sido reportado o eliminado de la sala", + "@removedFromRoom": { + "description": "Mensaje mostrado cuando un usuario es eliminado o reportado de una sala." + }, + "reportType": "{type, select, harassment{Acoso / Discurso de odio} abuse{Contenido abusivo / Violencia} spam{Spam / Estafas / Fraude} impersonation{Suplantación de identidad / Cuentas falsas} illegal{Actividades ilegales} selfharm{Autolesión / Suicidio / Salud mental} misuse{Uso indebido de la plataforma} other{Otro}}", + "@reportType": { + "description": "Selecciona la etiqueta de tipo de reporte apropiada basada en una clave.", + "placeholders": { + "type": { + "type": "String", + "example": "harassment" + } + } + }, + "userBlockedFromResonate": "Has recibido múltiples reportes de usuarios y has sido bloqueado de usar Resonate. Por favor contacta a AOSSIE si crees que esto es un error.", + "@userBlockedFromResonate": { + "description": "Mensaje mostrado cuando un usuario es bloqueado de usar Resonate." + }, + "reportParticipant": "Reportar participante", + "@reportParticipant": { + "description": "Etiqueta para el botón de reportar a un participante." + }, + "selectReportType": "Por favor selecciona un tipo de reporte", + "@selectReportType": { + "description": "Solicitud para que el usuario seleccione un tipo de reporte." + }, + "reportSubmitted": "Reporte enviado exitosamente", + "@reportSubmitted": { + "description": "Mensaje mostrado cuando un reporte se envía exitosamente." + }, + "reportFailed": "Error al enviar el reporte", + "@reportFailed": { + "description": "Mensaje mostrado cuando falla el envío de un reporte." + }, + "additionalDetailsOptional": "Detalles adicionales (opcional)", + "@additionalDetailsOptional": { + "description": "Etiqueta para un campo de entrada opcional para detalles adicionales en un reporte." + }, + "submitReport": "Enviar reporte", + "@submitReport": { + "description": "Texto del botón para enviar un reporte." + }, + "actionBlocked": "Acción bloqueada", + "@actionBlocked": { + "description": "Título para un mensaje que indica que una acción de usuario está bloqueada." + }, + "cannotStopRecording": "No puedes detener la grabación manualmente, la grabación se detendrá cuando se cierre la sala.", + "@cannotStopRecording": { + "description": "Mensaje que explica por qué un usuario no puede detener una grabación manualmente." + }, + "liveChapter": "Capítulo en vivo", + "@liveChapter": { + "description": "Etiqueta que indica que un capítulo está actualmente en vivo." + }, + "viewOrEditLyrics": "Ver o editar letra", + "@viewOrEditLyrics": { + "description": "Texto del botón para ver o editar la letra de un capítulo." + }, + "close": "Cerrar", + "@close": { + "description": "Etiqueta para el botón de cerrar un diálogo." + }, + "verifyChapterDetails": "Verificar detalles del capítulo", + "@verifyChapterDetails": { + "description": "Título para la pantalla donde se verifican los detalles del capítulo en vivo antes de publicar." + }, + "author": "Autor", + "@author": { + "description": "Etiqueta para el autor de una historia o capítulo." + }, + "startLiveChapter": "Iniciar un capítulo en vivo", + "@startLiveChapter": { + "description": "Título para la pantalla donde se inicia un capítulo en vivo." + }, + "fillAllFields": "Por favor completa todos los campos obligatorios", + "@fillAllFields": { + "description": "Mensaje de error cuando no se completan todos los campos obligatorios en un formulario." + }, + "noRecordingError": "No has grabado nada para el capítulo. Por favor graba un capítulo antes de salir de la sala", + "@noRecordingError": { + "description": "Mensaje de error cuando se intenta salir de una sala de capítulo en vivo sin ninguna grabación." + } +} diff --git a/lib/l10n/app_localizations.dart b/lib/l10n/app_localizations.dart index 798100bd..b3b9a1c7 100644 --- a/lib/l10n/app_localizations.dart +++ b/lib/l10n/app_localizations.dart @@ -6,6 +6,7 @@ import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:intl/intl.dart' as intl; import 'app_localizations_en.dart'; +import 'app_localizations_es.dart'; import 'app_localizations_gu.dart'; import 'app_localizations_hi.dart'; import 'app_localizations_kn.dart'; @@ -98,6 +99,7 @@ abstract class AppLocalizations { /// A list of this localizations delegate's supported locales. static const List supportedLocales = [ Locale('en'), + Locale('es'), Locale('gu'), Locale('hi'), Locale('kn'), @@ -2477,8 +2479,14 @@ class _AppLocalizationsDelegate } @override - bool isSupported(Locale locale) => - ['en', 'gu', 'hi', 'kn', 'mr'].contains(locale.languageCode); + bool isSupported(Locale locale) => [ + 'en', + 'es', + 'gu', + 'hi', + 'kn', + 'mr', + ].contains(locale.languageCode); @override bool shouldReload(_AppLocalizationsDelegate old) => false; @@ -2489,6 +2497,8 @@ AppLocalizations lookupAppLocalizations(Locale locale) { switch (locale.languageCode) { case 'en': return AppLocalizationsEn(); + case 'es': + return AppLocalizationsEs(); case 'gu': return AppLocalizationsGu(); case 'hi': diff --git a/lib/l10n/app_localizations_es.dart b/lib/l10n/app_localizations_es.dart new file mode 100644 index 00000000..a6ea981f --- /dev/null +++ b/lib/l10n/app_localizations_es.dart @@ -0,0 +1,1361 @@ +// 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 title => 'Resonate'; + + @override + String get roomDescription => + 'Sé educado y respeta la opinión de los demás. Evita comentarios groseros.'; + + @override + String get hidePassword => 'Ocultar contraseña'; + + @override + String get showPassword => 'Mostrar contraseña'; + + @override + String get passwordEmpty => 'La contraseña no puede estar vacía'; + + @override + String get password => 'Contraseña'; + + @override + String get confirmPassword => 'Confirmar contraseña'; + + @override + String get passwordsNotMatch => 'Las contraseñas no coinciden'; + + @override + String get userCreatedStories => 'Historias creadas por el usuario'; + + @override + String get yourStories => 'Tus historias'; + + @override + String get userNoStories => 'El usuario no ha creado ninguna historia'; + + @override + String get youNoStories => 'No has creado ninguna historia'; + + @override + String get follow => 'Seguir'; + + @override + String get editProfile => 'Editar perfil'; + + @override + String get verifyEmail => 'Verificar correo'; + + @override + String get verified => 'Verificado'; + + @override + String get profile => 'Perfil'; + + @override + String get userLikedStories => 'Historias que le gustan al usuario'; + + @override + String get yourLikedStories => 'Historias que te gustan'; + + @override + String get userNoLikedStories => + 'Al usuario no le ha gustado ninguna historia'; + + @override + String get youNoLikedStories => 'No te ha gustado ninguna historia'; + + @override + String get live => 'En vivo'; + + @override + String get upcoming => 'Próximas'; + + @override + String noAvailableRoom(String isRoom) { + String _temp0 = intl.Intl.selectLogic(isRoom, { + 'true': 'No hay sala disponible', + 'false': 'No hay salas próximas disponibles', + 'other': 'No hay información de sala disponible', + }); + return '$_temp0\n¡Empieza añadiendo una abajo!'; + } + + @override + String get user1 => 'Usuario 1'; + + @override + String get user2 => 'Usuario 2'; + + @override + String get you => 'Tú'; + + @override + String get areYouSure => '¿Estás seguro?'; + + @override + String get loggingOut => 'Estás cerrando sesión en Resonate.'; + + @override + String get yes => 'Sí'; + + @override + String get no => 'No'; + + @override + String get incorrectEmailOrPassword => 'Correo o contraseña incorrectos'; + + @override + String get passwordShort => 'La contraseña tiene menos de 8 caracteres'; + + @override + String get tryAgain => '¡Inténtalo de nuevo!'; + + @override + String get success => 'Éxito'; + + @override + String get passwordResetSent => + '¡Correo de restablecimiento de contraseña enviado!'; + + @override + String get error => 'Error'; + + @override + String get resetPassword => 'Restablecer contraseña'; + + @override + String get enterNewPassword => 'Ingresa tu nueva contraseña'; + + @override + String get newPassword => 'Nueva contraseña'; + + @override + String get setNewPassword => 'Establecer nueva contraseña'; + + @override + String get emailChanged => 'Correo cambiado'; + + @override + String get emailChangeSuccess => '¡Correo cambiado exitosamente!'; + + @override + String get failed => 'Fallido'; + + @override + String get emailChangeFailed => 'No se pudo cambiar el correo'; + + @override + String get oops => '¡Ups!'; + + @override + String get emailExists => 'El correo ya existe'; + + @override + String get changeEmail => 'Cambiar correo'; + + @override + String get enterValidEmail => + 'Por favor ingresa una dirección de correo válida'; + + @override + String get newEmail => 'Nuevo correo'; + + @override + String get currentPassword => 'Contraseña actual'; + + @override + String get emailChangeInfo => + 'Por seguridad adicional, debes proporcionar la contraseña actual de tu cuenta al cambiar tu dirección de correo. Después de cambiar el correo, usa el correo actualizado para futuros inicios de sesión.'; + + @override + String get oauthUsersMessage => + '(Solo para usuarios que iniciaron sesión con Google o Github)'; + + @override + String get oauthUsersEmailChangeInfo => + 'Para cambiar tu correo, ingresa una nueva contraseña en el campo \"Contraseña actual\". Asegúrate de recordar esta contraseña, ya que la necesitarás para futuros cambios de correo. En adelante, puedes iniciar sesión usando Google/GitHub o tu nueva combinación de correo y contraseña.'; + + @override + String get resonateTagline => + 'Entra en un mundo de conversaciones\nsin límites.'; + + @override + String get signInWithEmail => 'Iniciar sesión con correo'; + + @override + String get or => 'O'; + + @override + String get continueWith => 'Continuar con'; + + @override + String get continueWithGoogle => 'Continuar con Google'; + + @override + String get continueWithGitHub => 'Continuar con GitHub'; + + @override + String get resonateLogo => 'Logo de Resonate'; + + @override + String get iAlreadyHaveAnAccount => 'Ya tengo una cuenta'; + + @override + String get createNewAccount => 'Crear nueva cuenta'; + + @override + String get userProfile => 'Perfil de usuario'; + + @override + String get passwordIsStrong => 'La contraseña es segura'; + + @override + String get admin => 'Administrador'; + + @override + String get moderator => 'Moderador'; + + @override + String get speaker => 'Orador'; + + @override + String get listener => 'Oyente'; + + @override + String get removeModerator => 'Quitar moderador'; + + @override + String get kickOut => 'Expulsar'; + + @override + String get addModerator => 'Agregar moderador'; + + @override + String get addSpeaker => 'Agregar orador'; + + @override + String get makeListener => 'Hacer oyente'; + + @override + String get pairChat => 'Chat por parejas'; + + @override + String get chooseIdentity => 'Elegir identidad'; + + @override + String get selectLanguage => 'Seleccionar idioma'; + + @override + String get noConnection => 'Sin conexión'; + + @override + String get loadingDialog => 'Diálogo de carga'; + + @override + String get createAccount => 'Crear cuenta'; + + @override + String get enterValidEmailAddress => 'Ingresa una dirección de correo válida'; + + @override + String get email => 'Correo'; + + @override + String get passwordRequirements => + 'La contraseña debe tener al menos 8 caracteres'; + + @override + String get includeNumericDigit => 'Incluir al menos un dígito numérico'; + + @override + String get includeUppercase => 'Incluir al menos una letra mayúscula'; + + @override + String get includeLowercase => 'Incluir al menos una letra minúscula'; + + @override + String get includeSymbol => 'Incluir al menos un símbolo'; + + @override + String get signedUpSuccessfully => 'Registro exitoso'; + + @override + String get newAccountCreated => 'Has creado una nueva cuenta exitosamente'; + + @override + String get signUp => 'Registrarse'; + + @override + String get login => 'Iniciar sesión'; + + @override + String get settings => 'Configuración'; + + @override + String get accountSettings => 'Configuración de la cuenta'; + + @override + String get account => 'Cuenta'; + + @override + String get appSettings => 'Configuración de la app'; + + @override + String get themes => 'Temas'; + + @override + String get about => 'Acerca de'; + + @override + String get other => 'Otro'; + + @override + String get contribute => 'Contribuir'; + + @override + String get appPreferences => 'Preferencias de la app'; + + @override + String get transcriptionModel => 'Modelo de transcripción'; + + @override + String get transcriptionModelDescription => + 'Elige el modelo de IA para la transcripción de voz. Los modelos más grandes son más precisos pero más lentos y requieren más almacenamiento.'; + + @override + String get whisperModelTiny => 'Diminuto'; + + @override + String get whisperModelTinyDescription => + 'Más rápido, menos preciso (~39 MB)'; + + @override + String get whisperModelBase => 'Base'; + + @override + String get whisperModelBaseDescription => + 'Velocidad y precisión equilibradas (~74 MB)'; + + @override + String get whisperModelSmall => 'Pequeño'; + + @override + String get whisperModelSmallDescription => + 'Buena precisión, más lento (~244 MB)'; + + @override + String get whisperModelMedium => 'Mediano'; + + @override + String get whisperModelMediumDescription => + 'Alta precisión, más lento (~769 MB)'; + + @override + String get whisperModelLargeV1 => 'Grande V1'; + + @override + String get whisperModelLargeV1Description => + 'Más preciso, más lento (~1.55 GB)'; + + @override + String get whisperModelLargeV2 => 'Grande V2'; + + @override + String get whisperModelLargeV2Description => + 'Modelo grande mejorado con mayor precisión (~1.55 GB)'; + + @override + String get modelDownloadInfo => + 'Los modelos se descargan la primera vez que se usan. Recomendamos usar Base, Pequeño o Mediano. Los modelos grandes requieren dispositivos de gama muy alta.'; + + @override + String get logOut => 'Cerrar sesión'; + + @override + String get participants => 'Participantes'; + + @override + String get delete => 'eliminar'; + + @override + String get leave => 'salir'; + + @override + String get leaveButton => 'Salir'; + + @override + String get findingRandomPartner => 'Buscando un compañero aleatorio para ti'; + + @override + String get quickFact => 'Dato rápido'; + + @override + String get cancel => 'Cancelar'; + + @override + String get hide => 'Eliminar'; + + @override + String get removeRoom => 'Eliminar sala'; + + @override + String get removeRoomFromList => 'Eliminar de la lista'; + + @override + String get removeRoomConfirmation => + '¿Estás seguro de que quieres eliminar esta sala próxima de tu lista?'; + + @override + String get completeYourProfile => 'Completa tu perfil'; + + @override + String get uploadProfilePicture => 'Subir foto de perfil'; + + @override + String get enterValidName => 'Ingresa un nombre válido'; + + @override + String get name => 'Nombre'; + + @override + String get username => 'Nombre de usuario'; + + @override + String get enterValidDOB => 'Ingresa una fecha de nacimiento válida'; + + @override + String get dateOfBirth => 'Fecha de nacimiento'; + + @override + String get forgotPassword => '¿Olvidaste tu contraseña?'; + + @override + String get next => 'Siguiente'; + + @override + String get noStoriesExist => 'No existen historias para presentar'; + + @override + String get enterVerificationCode => 'Ingresa tu\ncódigo de verificación'; + + @override + String get verificationCodeSent => + 'Enviamos un código de verificación de 6 dígitos a\n'; + + @override + String get verificationComplete => 'Verificación completa'; + + @override + String get verificationCompleteMessage => + 'Felicidades, has verificado tu correo'; + + @override + String get verificationFailed => 'Verificación fallida'; + + @override + String get otpMismatch => 'El OTP no coincide, por favor intenta de nuevo'; + + @override + String get otpResent => 'OTP reenviado'; + + @override + String get requestNewCode => 'Solicitar un nuevo código'; + + @override + String get requestNewCodeIn => 'Solicitar un nuevo código en'; + + @override + String get clickPictureCamera => 'Tomar foto con la cámara'; + + @override + String get pickImageGallery => 'Elegir imagen de la galería'; + + @override + String get deleteMyAccount => 'Eliminar mi cuenta'; + + @override + String get createNewRoom => 'Crear nueva sala'; + + @override + String get pleaseEnterScheduledDateTime => + 'Por favor ingresa la fecha y hora programadas'; + + @override + String get scheduleDateTimeLabel => 'Fecha y hora programadas'; + + @override + String get enterTags => 'Ingresa etiquetas'; + + @override + String get joinCommunity => 'Unirse a la comunidad'; + + @override + String get followUsOnX => 'Síguenos en X'; + + @override + String get joinDiscordServer => 'Unirse al servidor de Discord'; + + @override + String get noLyrics => 'Sin letra'; + + @override + String noStoriesInCategory(String categoryName) { + return 'Actualmente no existen historias en la categoría $categoryName para presentar'; + } + + @override + String get newChapters => 'Nuevos capítulos'; + + @override + String get helpToGrow => 'Ayuda a crecer'; + + @override + String get share => 'Compartir'; + + @override + String get rate => 'Calificar'; + + @override + String get aboutResonate => 'Acerca de Resonate'; + + @override + String get description => 'Descripción'; + + @override + String get confirm => 'Confirmar'; + + @override + String get classic => 'Clásico'; + + @override + String get time => 'Tiempo'; + + @override + String get vintage => 'Vintage'; + + @override + String get amber => 'Ámbar'; + + @override + String get forest => 'Bosque'; + + @override + String get cream => 'Crema'; + + @override + String get none => 'ninguno'; + + @override + String checkOutGitHub(String url) { + return 'Echa un vistazo a nuestro repositorio de GitHub: $url'; + } + + @override + String get aossie => 'AOSSIE'; + + @override + String get aossieLogo => 'logo de aossie'; + + @override + String get errorLoadPackageInfo => + 'No se pudo cargar la información del paquete'; + + @override + String get searchFailed => + 'No se pudieron buscar salas. Por favor intenta de nuevo.'; + + @override + String get updateAvailable => 'Actualización disponible'; + + @override + String get newVersionAvailable => '¡Una nueva versión está disponible!'; + + @override + String get upToDate => 'Actualizado'; + + @override + String get latestVersion => 'Estás usando la versión más reciente'; + + @override + String get profileCreatedSuccessfully => 'Perfil creado exitosamente'; + + @override + String get invalidScheduledDateTime => 'Fecha y hora programadas inválidas'; + + @override + String get scheduledDateTimePast => + 'La fecha y hora programadas no pueden estar en el pasado'; + + @override + String get joinRoom => 'Unirse a la sala'; + + @override + String get unknownUser => 'Desconocido'; + + @override + String get canceled => 'cancelado'; + + @override + String get english => 'en'; + + @override + String get emailVerificationRequired => 'Verificación de correo requerida'; + + @override + String get verify => 'Verificar'; + + @override + String get audioRoom => 'Sala de audio'; + + @override + String toRoomAction(String action) { + return 'Para $action la sala'; + } + + @override + String get mailSentMessage => 'correo enviado'; + + @override + String get disconnected => 'desconectado'; + + @override + String get micOn => 'micrófono'; + + @override + String get speakerOn => 'altavoz'; + + @override + String get endChat => 'finalizar-chat'; + + @override + String get monthJan => 'Ene'; + + @override + String get monthFeb => 'Feb'; + + @override + String get monthMar => 'Mar'; + + @override + String get monthApr => 'Abr'; + + @override + String get monthMay => 'May'; + + @override + String get monthJun => 'Jun'; + + @override + String get monthJul => 'Jul'; + + @override + String get monthAug => 'Ago'; + + @override + String get monthSep => 'Sep'; + + @override + String get monthOct => 'Oct'; + + @override + String get monthNov => 'Nov'; + + @override + String get monthDec => 'Dic'; + + @override + String get register => 'Registrarse'; + + @override + String get newToResonate => '¿Nuevo en Resonate? '; + + @override + String get alreadyHaveAccount => '¿Ya tienes una cuenta? '; + + @override + String get checking => 'Verificando...'; + + @override + String get forgotPasswordMessage => + 'Ingresa tu dirección de correo registrada para restablecer tu contraseña.'; + + @override + String get usernameUnavailable => '¡Nombre de usuario no disponible!'; + + @override + String get usernameInvalidOrTaken => + 'Este nombre de usuario es inválido o ya está tomado.'; + + @override + String get otpResentMessage => + 'Por favor revisa tu correo para obtener un nuevo OTP.'; + + @override + String get connectionError => + 'Hay un error de conexión. Por favor verifica tu internet e intenta de nuevo.'; + + @override + String get seconds => 'segundos.'; + + @override + String get unsavedChangesWarning => + 'Si continúas sin guardar, los cambios no guardados se perderán.'; + + @override + String get deleteAccountPermanent => + 'Esta acción eliminará tu cuenta permanentemente. Es un proceso irreversible. Eliminaremos tu nombre de usuario, dirección de correo y todos los demás datos asociados a tu cuenta. No podrás recuperarla.'; + + @override + String get giveGreatName => 'Dale un gran nombre...'; + + @override + String get joinCommunityDescription => + 'Al unirte a la comunidad puedes aclarar tus dudas, sugerir nuevas funciones, reportar problemas que hayas enfrentado y más.'; + + @override + String get resonateDescription => + 'Resonate es una plataforma de redes sociales donde cada voz es valorada. Comparte tus pensamientos, historias y experiencias con otros. Comienza tu viaje de audio ahora. Sumérgete en diversas discusiones y temas. Encuentra salas que resuenen contigo y conviértete en parte de la comunidad. ¡Únete a la conversación! Explora salas, conecta con amigos y comparte tu voz con el mundo.'; + + @override + String get resonateFullDescription => + 'Resonate es una plataforma de redes sociales revolucionaria basada en voz donde cada voz importa. \nÚnete a conversaciones de audio en tiempo real, participa en discusiones diversas y conéctate con personas afines. Nuestra plataforma ofrece:\n- Salas de audio en vivo con discusiones basadas en temas\n- Redes sociales fluidas a través de la voz\n- Moderación de contenido impulsada por la comunidad\n- Compatibilidad multiplataforma\n- Conversaciones privadas cifradas de extremo a extremo\n\nDesarrollado por la comunidad de código abierto AOSSIE, priorizamos la privacidad del usuario y el desarrollo impulsado por la comunidad. ¡Únete a nosotros para dar forma al futuro del audio social!'; + + @override + String get stable => 'Estable'; + + @override + String get usernameCharacterLimit => + 'El nombre de usuario debe contener más de 5 caracteres.'; + + @override + String get submit => 'Enviar'; + + @override + String get anonymous => 'Anónimo'; + + @override + String get noSearchResults => 'Sin resultados de búsqueda'; + + @override + String get searchRooms => 'Buscar salas...'; + + @override + String get searchingRooms => 'Buscando salas...'; + + @override + String get clearSearch => 'Limpiar búsqueda'; + + @override + String get searchError => 'Error de búsqueda'; + + @override + String get searchRoomsError => + 'No se pudieron buscar las salas. Por favor intenta de nuevo.'; + + @override + String get searchUpcomingRoomsError => + 'No se pudieron buscar las salas próximas. Por favor intenta de nuevo.'; + + @override + String get search => 'Buscar'; + + @override + String get clear => 'Limpiar'; + + @override + String shareRoomMessage( + String roomName, + String description, + int participants, + ) { + return '🚀 ¡Echa un vistazo a esta increíble sala: $roomName!\n\n📖 Descripción: $description\n👥 ¡Únete a $participants participantes ahora!'; + } + + @override + String participantsCount(int count) { + return '$count Participantes'; + } + + @override + String get join => 'Unirse'; + + @override + String get invalidTags => 'Etiqueta inválida:'; + + @override + String get cropImage => 'Recortar imagen'; + + @override + String get profileSavedSuccessfully => 'Perfil actualizado'; + + @override + String get profileUpdatedSuccessfully => + 'Todos los cambios se guardaron exitosamente.'; + + @override + String get profileUpToDate => 'Perfil actualizado'; + + @override + String get noChangesToSave => + 'No se hicieron nuevos cambios, nada que guardar.'; + + @override + String get connectionFailed => 'Conexión fallida'; + + @override + String get unableToJoinRoom => + 'No se pudo unir a la sala. Por favor verifica tu red e intenta de nuevo.'; + + @override + String get connectionLost => 'Conexión perdida'; + + @override + String get unableToReconnect => + 'No se pudo reconectar a la sala. Por favor intenta volver a unirte.'; + + @override + String get invalidFormat => '¡Formato inválido!'; + + @override + String get usernameAlphanumeric => + 'El nombre de usuario debe ser alfanumérico y no debe contener caracteres especiales.'; + + @override + String get userProfileCreatedSuccessfully => + 'Tu perfil de usuario se ha creado exitosamente.'; + + @override + String get emailVerificationMessage => + 'Para continuar, verifica tu dirección de correo.'; + + @override + String addNewChaptersToStory(String storyName) { + return 'Agregar nuevos capítulos a $storyName'; + } + + @override + String get currentChapters => 'Capítulos actuales'; + + @override + String get sourceCodeOnGitHub => 'Código fuente en GitHub'; + + @override + String get createAChapter => 'Crear un capítulo'; + + @override + String get chapterTitle => 'Título del capítulo *'; + + @override + String get aboutRequired => 'Acerca de *'; + + @override + String get changeCoverImage => 'Cambiar imagen de portada'; + + @override + String get uploadAudioFile => 'Subir archivo de audio'; + + @override + String get uploadLyricsFile => 'Subir archivo de letra'; + + @override + String get createChapter => 'Crear capítulo'; + + @override + String audioFileSelected(String fileName) { + return 'Archivo de audio seleccionado: $fileName'; + } + + @override + String lyricsFileSelected(String fileName) { + return 'Archivo de letra seleccionado: $fileName'; + } + + @override + String get fillAllRequiredFields => + 'Por favor completa todos los campos obligatorios y sube tu archivo de audio y archivo de letra'; + + @override + String get scheduled => 'Programada'; + + @override + String get ok => 'OK'; + + @override + String get roomDescriptionOptional => 'Descripción de la sala (opcional)'; + + @override + String get deleteAccount => 'Eliminar cuenta'; + + @override + String get createYourStory => 'Crea tu historia'; + + @override + String get titleRequired => 'Título *'; + + @override + String get category => 'Categoría *'; + + @override + String get addChapter => 'Agregar capítulo'; + + @override + String get createStory => 'Crear historia'; + + @override + String get fillAllRequiredFieldsAndChapter => + 'Por favor completa todos los campos obligatorios, agrega al menos un capítulo y selecciona una imagen de portada.'; + + @override + String get toConfirmType => 'Para confirmar, escribe'; + + @override + String get inTheBoxBelow => 'en el cuadro de abajo'; + + @override + String get iUnderstandDeleteMyAccount => 'Entiendo, eliminar mi cuenta'; + + @override + String get whatDoYouWantToListenTo => '¿Qué quieres escuchar?'; + + @override + String get categories => 'Categorías'; + + @override + String get stories => 'Historias'; + + @override + String get someSuggestions => 'Algunas sugerencias'; + + @override + String get getStarted => 'Comenzar'; + + @override + String get skip => 'Omitir'; + + @override + String get welcomeToResonate => 'Bienvenido a Resonate'; + + @override + String get exploreDiverseConversations => 'Explora conversaciones diversas'; + + @override + String get yourVoiceMatters => 'Tu voz importa'; + + @override + String get joinConversationExploreRooms => + '¡Únete a la conversación! Explora salas, conecta con amigos y comparte tu voz con el mundo.'; + + @override + String get diveIntoDiverseDiscussions => + 'Sumérgete en diversas discusiones y temas. \nEncuentra salas que resuenen contigo y conviértete en parte de la comunidad.'; + + @override + String get atResonateEveryVoiceValued => + 'En Resonate, cada voz es valorada. Comparte tus pensamientos, historias y experiencias con otros. Comienza tu viaje de audio ahora.'; + + @override + String get notifications => 'Notificaciones'; + + @override + String taggedYouInUpcomingRoom(String username, String subject) { + return '$username te mencionó en una sala próxima: $subject'; + } + + @override + String taggedYouInRoom(String username, String subject) { + return '$username te mencionó en la sala: $subject'; + } + + @override + String likedYourStory(String username, String subject) { + return 'A $username le gustó tu historia: $subject'; + } + + @override + String subscribedToYourRoom(String username, String subject) { + return '$username se suscribió a tu sala: $subject'; + } + + @override + String startedFollowingYou(String username) { + return '$username comenzó a seguirte'; + } + + @override + String get youHaveNewNotification => 'Tienes una nueva notificación'; + + @override + String get hangOnGoodThingsTakeTime => + 'Espera, las cosas buenas toman tiempo 🔍'; + + @override + String get resonateOpenSourceProject => + 'Resonate es un proyecto de código abierto mantenido por AOSSIE. Visita nuestro github para contribuir.'; + + @override + String get mute => 'Silenciar'; + + @override + String get speakerLabel => 'Altavoz'; + + @override + String get end => 'Terminar'; + + @override + String get saveChanges => 'Guardar cambios'; + + @override + String get discard => 'DESCARTAR'; + + @override + String get save => 'GUARDAR'; + + @override + String get changeProfilePicture => 'Cambiar foto de perfil'; + + @override + String get camera => 'Cámara'; + + @override + String get gallery => 'Galería'; + + @override + String get remove => 'Eliminar'; + + @override + String created(String date) { + return 'Creado $date'; + } + + @override + String get chapters => 'Capítulos'; + + @override + String get deleteStory => 'Eliminar historia'; + + @override + String createdBy(String creatorName) { + return 'Creado por $creatorName'; + } + + @override + String get start => 'Comenzar'; + + @override + String get unsubscribe => 'Cancelar suscripción'; + + @override + String get subscribe => 'Suscribirse'; + + @override + String storyCategory(String category) { + String _temp0 = intl.Intl.selectLogic(category, { + 'drama': 'Drama', + 'comedy': 'Comedia', + 'horror': 'Terror', + 'romance': 'Romance', + 'thriller': 'Suspenso', + 'spiritual': 'Espiritual', + 'other': 'Otro', + }); + return '$_temp0'; + } + + @override + String chooseTheme(String category) { + String _temp0 = intl.Intl.selectLogic(category, { + 'classicTheme': 'Clásico', + 'timeTheme': 'Tiempo', + 'vintageTheme': 'Vintage', + 'amberTheme': 'Ámbar', + 'forestTheme': 'Bosque', + 'creamTheme': 'Crema', + 'other': 'Otro', + }); + return '$_temp0'; + } + + @override + String minutesAgo(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'hace $count minutos', + one: 'hace 1 minuto', + ); + return '$_temp0'; + } + + @override + String hoursAgo(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'hace $count horas', + one: 'hace 1 hora', + ); + return '$_temp0'; + } + + @override + String daysAgo(int count) { + String _temp0 = intl.Intl.pluralLogic( + count, + locale: localeName, + other: 'hace $count días', + one: 'hace 1 día', + ); + return '$_temp0'; + } + + @override + String get by => 'por'; + + @override + String get likes => 'Me gusta'; + + @override + String get lengthMinutes => 'min'; + + @override + String get requiredField => 'Campo obligatorio'; + + @override + String get onlineUsers => 'Usuarios en línea'; + + @override + String get noOnlineUsers => 'No hay usuarios en línea actualmente'; + + @override + String get chooseUser => 'Elige un usuario para chatear'; + + @override + String get quickMatch => 'Emparejamiento rápido'; + + @override + String get story => 'Historia'; + + @override + String get user => 'Usuario'; + + @override + String get following => 'Siguiendo'; + + @override + String get followers => 'Seguidores'; + + @override + String get friendRequests => 'Solicitudes de amistad'; + + @override + String get friendRequestSent => 'Solicitud de amistad enviada'; + + @override + String friendRequestSentTo(String username) { + return 'Tu solicitud de amistad a $username ha sido enviada.'; + } + + @override + String get friendRequestCancelled => 'Solicitud de amistad cancelada'; + + @override + String friendRequestCancelledTo(String username) { + return 'Tu solicitud de amistad a $username ha sido cancelada.'; + } + + @override + String get requested => 'Solicitada'; + + @override + String get friends => 'Amigos'; + + @override + String get addFriend => 'Agregar amigo'; + + @override + String get friendRequestAccepted => 'Solicitud de amistad aceptada'; + + @override + String friendRequestAcceptedTo(String username) { + return 'Ahora eres amigo de $username.'; + } + + @override + String get friendRequestDeclined => 'Solicitud de amistad rechazada'; + + @override + String friendRequestDeclinedTo(String username) { + return 'Has rechazado la solicitud de amistad de $username.'; + } + + @override + String get accept => 'Aceptar'; + + @override + String get callDeclined => 'Llamada rechazada'; + + @override + String callDeclinedTo(String username) { + return 'El usuario $username rechazó la llamada.'; + } + + @override + String get checkForUpdates => 'Buscar actualizaciones'; + + @override + String get updateNow => 'Actualizar ahora'; + + @override + String get updateLater => 'Más tarde'; + + @override + String get updateSuccessful => 'Actualización exitosa'; + + @override + String get updateSuccessfulMessage => + '¡Resonate se ha actualizado exitosamente!'; + + @override + String get updateCancelled => 'Actualización cancelada'; + + @override + String get updateCancelledMessage => 'El usuario canceló la actualización'; + + @override + String get updateFailed => 'Actualización fallida'; + + @override + String get updateFailedMessage => + 'Error al actualizar. Por favor intenta actualizar manualmente desde Play Store.'; + + @override + String get updateError => 'Error de actualización'; + + @override + String get updateErrorMessage => + 'Ocurrió un error durante la actualización. Por favor intenta de nuevo.'; + + @override + String get platformNotSupported => 'Plataforma no soportada'; + + @override + String get platformNotSupportedMessage => + 'La verificación de actualizaciones solo está disponible en dispositivos Android'; + + @override + String get updateCheckFailed => 'Error al verificar actualización'; + + @override + String get updateCheckFailedMessage => + 'No se pudo verificar si hay actualizaciones. Por favor intenta de nuevo más tarde.'; + + @override + String get upToDateTitle => '¡Estás actualizado!'; + + @override + String get upToDateMessage => + 'Estás usando la versión más reciente de Resonate'; + + @override + String get updateAvailableTitle => '¡Actualización disponible!'; + + @override + String get updateAvailableMessage => + 'Una nueva versión de Resonate está disponible en Play Store'; + + @override + String get updateFeaturesImprovement => + '¡Obtén las últimas funciones y mejoras!'; + + @override + String get failedToRemoveRoom => 'Error al eliminar la sala'; + + @override + String get roomRemovedSuccessfully => + 'Sala eliminada de tu lista exitosamente'; + + @override + String get alert => 'Alerta'; + + @override + String get removedFromRoom => 'Has sido reportado o eliminado de la sala'; + + @override + String reportType(String type) { + String _temp0 = intl.Intl.selectLogic(type, { + 'harassment': 'Acoso / Discurso de odio', + 'abuse': 'Contenido abusivo / Violencia', + 'spam': 'Spam / Estafas / Fraude', + 'impersonation': 'Suplantación de identidad / Cuentas falsas', + 'illegal': 'Actividades ilegales', + 'selfharm': 'Autolesión / Suicidio / Salud mental', + 'misuse': 'Uso indebido de la plataforma', + 'other': 'Otro', + }); + return '$_temp0'; + } + + @override + String get userBlockedFromResonate => + 'Has recibido múltiples reportes de usuarios y has sido bloqueado de usar Resonate. Por favor contacta a AOSSIE si crees que esto es un error.'; + + @override + String get reportParticipant => 'Reportar participante'; + + @override + String get selectReportType => 'Por favor selecciona un tipo de reporte'; + + @override + String get reportSubmitted => 'Reporte enviado exitosamente'; + + @override + String get reportFailed => 'Error al enviar el reporte'; + + @override + String get additionalDetailsOptional => 'Detalles adicionales (opcional)'; + + @override + String get submitReport => 'Enviar reporte'; + + @override + String get actionBlocked => 'Acción bloqueada'; + + @override + String get cannotStopRecording => + 'No puedes detener la grabación manualmente, la grabación se detendrá cuando se cierre la sala.'; + + @override + String get liveChapter => 'Capítulo en vivo'; + + @override + String get viewOrEditLyrics => 'Ver o editar letra'; + + @override + String get close => 'Cerrar'; + + @override + String get verifyChapterDetails => 'Verificar detalles del capítulo'; + + @override + String get author => 'Autor'; + + @override + String get startLiveChapter => 'Iniciar un capítulo en vivo'; + + @override + String get fillAllFields => + 'Por favor completa todos los campos obligatorios'; + + @override + String get noRecordingError => + 'No has grabado nada para el capítulo. Por favor graba un capítulo antes de salir de la sala'; +} diff --git a/lib/views/screens/chapter_play_screen.dart b/lib/views/screens/chapter_play_screen.dart index 91e548ef..5df77c73 100644 --- a/lib/views/screens/chapter_play_screen.dart +++ b/lib/views/screens/chapter_play_screen.dart @@ -23,23 +23,8 @@ class _ChapterPlayScreenState extends State { @override void didChangeDependencies() { super.didChangeDependencies(); - bool themeIsDark = Theme.of(context).brightness == Brightness.dark; - lyricUI = UINetease( - highlightColor: themeIsDark ? Colors.white : Colors.black, - playingMainTextStyle: TextStyle( - fontSize: UiSizes.size_20, - fontWeight: FontWeight.bold, - color: themeIsDark - ? const Color.fromARGB(255, 223, 222, 222) - : Colors.grey[600], - ), - otherMainTextStyle: TextStyle( - fontSize: UiSizes.size_18, - color: themeIsDark - ? const Color.fromARGB(255, 223, 222, 222) - : Colors.grey[600], - ), - ); + // FIXED: Remove unsupported parameters playingMainTextStyle and otherMainTextStyle + lyricUI = UINetease(); } @override @@ -133,7 +118,6 @@ class _ChapterPlayScreenState extends State { IconButton( onPressed: () { confirm.call(); - controller.audioPlayer?.seek( Duration(milliseconds: progress), ); @@ -163,8 +147,6 @@ class _ChapterPlayScreenState extends State { ), ), ), - - // added a second extra to cover up the error of the meta data library Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( diff --git a/lib/views/widgets/snackbar.dart b/lib/views/widgets/snackbar.dart index 7be9dedc..7c623bcf 100644 --- a/lib/views/widgets/snackbar.dart +++ b/lib/views/widgets/snackbar.dart @@ -8,6 +8,10 @@ SnackbarController customSnackbar( LogType messageType, { int snackbarDuration = 3, }) { + if (Get.testMode) { + return SnackbarController(GetSnackBar()); + } + Color messageTypeColor() { switch (messageType) { case LogType.success: @@ -21,10 +25,14 @@ SnackbarController customSnackbar( } } + final context = Get.context; + return Get.snackbar( title, message, - backgroundColor: Theme.of(Get.context!).colorScheme.surface, + backgroundColor: context != null + ? Theme.of(context).colorScheme.surface + : Colors.grey.shade900, titleText: Text( title, style: TextStyle( @@ -37,4 +45,4 @@ SnackbarController customSnackbar( borderWidth: 1, duration: Duration(seconds: snackbarDuration), ); -} +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index c2c912f3..380f21c7 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -269,10 +269,10 @@ packages: dependency: transitive description: name: characters - sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803 + sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" charset: dependency: transitive description: @@ -686,11 +686,10 @@ packages: flutter_lyric: dependency: "direct main" description: - path: "." - ref: master - resolved-ref: "2cf076d0ae4a2d6c00d6a521e35b97782ab24887" - url: "https://github.com/Aarush-Acharya/flutter_lyric.git" - source: git + name: flutter_lyric + sha256: "5d7e6c46c07b96842a05d5d8af385cb9d715feb7e0f1db1983bc128813c420d7" + url: "https://pub.dev" + source: hosted version: "2.0.4+6" flutter_native_splash: dependency: "direct main" @@ -1162,18 +1161,18 @@ packages: dependency: transitive description: name: matcher - sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2 + sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 url: "https://pub.dev" source: hosted - version: "0.12.17" + version: "0.12.19" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec + sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" url: "https://pub.dev" source: hosted - version: "0.11.1" + version: "0.13.0" meilisearch: dependency: "direct main" description: @@ -1186,10 +1185,10 @@ packages: dependency: transitive description: name: meta - sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c + sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" url: "https://pub.dev" source: hosted - version: "1.16.0" + version: "1.17.0" mime: dependency: transitive description: @@ -1687,10 +1686,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.10" textfield_tags: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 978d8920..82797ee4 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -78,10 +78,7 @@ dependencies: git: url: https://github.com/lionelmennig/textfield_tags.git ref: fixes/allow-controller-re-registration - flutter_lyric: - git: - url: https://github.com/Aarush-Acharya/flutter_lyric.git - ref: master + flutter_lyric: ^2.0.0 url_launcher: ^6.3.2 uuid: ^4.5.2 audio_metadata_reader: ^1.4.2 diff --git a/test/controllers/change_email_controller_test.dart b/test/controllers/change_email_controller_test.dart index 5c580f19..039159ea 100644 --- a/test/controllers/change_email_controller_test.dart +++ b/test/controllers/change_email_controller_test.dart @@ -4,6 +4,7 @@ import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:get/get.dart'; import 'package:get/get_navigation/src/root/get_material_app.dart'; import 'package:mockito/annotations.dart'; import 'package:mockito/mockito.dart'; @@ -20,6 +21,7 @@ void main() { MockAccount mockAccount = MockAccount(); MockClient mockClient = MockClient(); MockFirebaseMessaging mockMessaging = MockFirebaseMessaging(); + AuthStateController authStateController = AuthStateController( account: mockAccount, databases: mockDatabases, @@ -32,6 +34,7 @@ void main() { databases: mockDatabases, authStateController: authStateController, ); + final User mockUser = User( $id: '123', name: 'Test User', @@ -53,6 +56,7 @@ void main() { targets: [], hashOptions: {}, ); + final Document mockUserDocument = Document( $collectionId: usersCollectionID, $createdAt: DateTime.now().toIso8601String(), @@ -102,9 +106,7 @@ void main() { $createdAt: DateTime.now().toIso8601String(), $updatedAt: DateTime.now().toIso8601String(), $permissions: ['any'], - data: Map.from( - invocation.namedArguments[#data] as Map, - ), + data: Map.from(invocation.namedArguments[#data] as Map), $sequence: 0, ); }); @@ -112,10 +114,9 @@ void main() { mockAccount.updateEmail(email: 'test2@test.com', password: "anyPassword"), ).thenAnswer((_) => Future.value(mockUser)); }); + test('test isEmailAvailable', () async { - final result = await changeEmailController.isEmailAvailable( - 'test2@test.com', - ); + final result = await changeEmailController.isEmailAvailable('test2@test.com'); expect(result, true); }); @@ -162,48 +163,57 @@ void main() { }); testWidgets('test changeEmail', (WidgetTester tester) async { - await tester.pumpWidget( - GetMaterialApp( - localizationsDelegates: [ - AppLocalizations.delegate, - GlobalMaterialLocalizations.delegate, - GlobalWidgetsLocalizations.delegate, - GlobalCupertinoLocalizations.delegate, - ], - supportedLocales: [Locale('en'), Locale('hi')], - home: Form( + Get.testMode = true; + + await tester.pumpWidget( + GetMaterialApp( + localizationsDelegates: [ + AppLocalizations.delegate, + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + GlobalCupertinoLocalizations.delegate, + ], + supportedLocales: const [Locale('en'), Locale('hi')], + home: Scaffold( + body: Form( key: changeEmailController.changeEmailFormKey, child: Builder( builder: (context) => ElevatedButton( onPressed: () async { await changeEmailController.changeEmail(context); }, - child: Text("Test"), + child: const Text("Test"), ), ), ), ), - ); + ), + ); - changeEmailController.passwordController.text = 'anyPassword'; - changeEmailController.emailController.text = 'test2@test.com'; - await tester.tap(find.text('Test')); - await tester.pumpAndSettle(); - verify( - mockAccount.updateEmail(email: 'test2@test.com', password: "anyPassword"), - ).called(1); + await tester.pumpAndSettle(); - await tester.pumpAndSettle(const Duration(seconds: 4)); + changeEmailController.passwordController.text = 'anyPassword'; + changeEmailController.emailController.text = 'test2@test.com'; - verify( - mockDatabases.updateDocument( - databaseId: userDatabaseID, - collectionId: usernameCollectionID, - documentId: 'TestUser', - data: {'email': 'test2@test.com'}, - ), - ).called(1); - expect(authStateController.email, 'test2@test.com'); - expect(changeEmailController.isLoading.value, false); - }); -} + await tester.tap(find.text('Test')); + await tester.pumpAndSettle(); + + verify( + mockAccount.updateEmail(email: 'test2@test.com', password: "anyPassword"), + ).called(1); + + await tester.pumpAndSettle(const Duration(seconds: 4)); + + verify( + mockDatabases.updateDocument( + databaseId: userDatabaseID, + collectionId: usernameCollectionID, + documentId: 'TestUser', + data: {'email': 'test2@test.com'}, + ), + ).called(1); + + expect(authStateController.email, 'test2@test.com'); + expect(changeEmailController.isLoading.value, false); +}); +} \ No newline at end of file