diff --git a/js/app/components/mobile/badge-picker.tsx b/js/app/components/mobile/badge-picker.tsx
index 3c7f27d9d..4f6f6f4de 100644
--- a/js/app/components/mobile/badge-picker.tsx
+++ b/js/app/components/mobile/badge-picker.tsx
@@ -23,12 +23,7 @@ import { useNameColorPicker } from "components/name-color-picker/name-color-pick
import { Image } from "expo-image";
import { Check, SwatchBook } from "lucide-react-native";
import { useCallback, useEffect, useRef, useState } from "react";
-import {
- ActivityIndicator,
- Pressable,
- TouchableOpacity,
- View,
-} from "react-native";
+import { ActivityIndicator, TouchableOpacity, View } from "react-native";
import { useStore } from "store";
import { useUserProfile } from "store/hooks";
import type { PlaceStreamBadgeDefs } from "streamplace";
@@ -349,7 +344,7 @@ function BadgeTriggerButton({
const [hover, setHover] = useState(false);
return (
- setHover(true)}
- onHoverOut={() => setHover(false)}
+ onPointerEnter={() => setHover(true)}
+ onPointerLeave={() => setHover(false)}
>
{loading ? (
@@ -384,7 +379,7 @@ function BadgeTriggerButton({
}}
/>
)}
-
+
);
}
diff --git a/js/app/components/mobile/chat.tsx b/js/app/components/mobile/chat.tsx
index f3dd571ed..937018eb2 100644
--- a/js/app/components/mobile/chat.tsx
+++ b/js/app/components/mobile/chat.tsx
@@ -195,7 +195,6 @@ export function MobileChatPanel({
}) {
const insets = useSafeAreaInsets();
- console.log("porteaitVideoTranslateY", portraitVideoTranslateY);
// create fixed style
const fixedStyle = useAnimatedStyle(() => ({
marginTop: portraitVideoTranslateY ? portraitVideoTranslateY.value : 0,
diff --git a/js/app/components/settings/badge-selection-manager.tsx b/js/app/components/settings/badge-selection-manager.tsx
index 4736053d9..c3f75b135 100644
--- a/js/app/components/settings/badge-selection-manager.tsx
+++ b/js/app/components/settings/badge-selection-manager.tsx
@@ -14,7 +14,7 @@ import {
} from "@streamplace/components/src/components/chat/badge";
import { borderRadius as radiusTokens } from "@streamplace/components/src/lib/theme/tokens";
import { usePDSAgent } from "@streamplace/components/src/streamplace-store/xrpc";
-import { flex } from "@streamplace/components/src/ui";
+import { flex, mt, pt } from "@streamplace/components/src/ui";
import { Image } from "expo-image";
import { Check } from "lucide-react-native";
import { useCallback, useEffect, useRef, useState } from "react";
@@ -278,6 +278,7 @@ export function BadgeSelectionManager() {
+
{hasStreamerBadges && (
diff --git a/js/components/locales/en-US/settings.ftl b/js/components/locales/en-US/settings.ftl
index 8a489a597..2920f1060 100644
--- a/js/components/locales/en-US/settings.ftl
+++ b/js/components/locales/en-US/settings.ftl
@@ -272,3 +272,41 @@ backup-error-save-failed = Failed to save storage settings
backup-error-missing-secret = Cannot update S3 settings without the secret key. Please re-enter it.
backup-segment-duration-placeholder = 6
backup-connection-url-placeholder = Must be a valid S3 URL in the format s3+https://ACCESS_KEY:SECRET_KEY@region.endpoi.nt/bucket
+
+## Badges
+badges = Badges
+badges-cosmetic-section = Cosmetic Badges
+badges-empty-state = You haven't been issued any badges yet.
+badges-failed-load = Failed to load badges
+badges-failed-update = Failed to update badge selection
+badges-issued-by = Issued by { $issuer }
+badges-streamer-section = Streamer Badges
+
+## Issue Badges
+issue-badges = Issue Badges
+issue-badges-back-to-definitions = Badge Definitions
+issue-badges-badge-name = Badge Name
+issue-badges-badge-name-placeholder = e.g. VIP, Supporter
+issue-badges-badge-type = Badge Type
+issue-badges-choose-image = Choose Image
+issue-badges-create-definition = Create Badge Definition
+issue-badges-create-definition-description = Define a new badge type that can be issued to viewers
+issue-badges-create-definition-subtitle = Define a new badge type
+issue-badges-definition-created = Badge definition created
+issue-badges-description-optional = Description (optional)
+issue-badges-description-placeholder = Optional description for this badge
+issue-badges-failed-create = Failed to create badge definition
+issue-badges-failed-issue = Failed to issue badge
+issue-badges-failed-load = Failed to load badge definitions
+issue-badges-image-optional = Image (optional)
+issue-badges-image-too-large = Image must be under 256KB
+issue-badges-image-web-only = Image upload is only available on web
+issue-badges-issue-badge = Issue Badge
+issue-badges-issue-badge-description = Issue the "{ $name }" badge to a viewer by their DID
+issue-badges-issued = Badge issued
+issue-badges-issued-to = Issued to { $did }
+issue-badges-manage-description = Create badge definitions and issue them to viewers
+issue-badges-recipient-did = Recipient DID
+issue-badges-recipient-did-placeholder = did:plc:...
+issue-badges-tap-to-issue = Tap to issue
+issue-badges-your-definitions = Your Badge Definitions
diff --git a/js/components/locales/es-ES/common.ftl b/js/components/locales/es-ES/common.ftl
index 353254ded..33f6c40df 100644
--- a/js/components/locales/es-ES/common.ftl
+++ b/js/components/locales/es-ES/common.ftl
@@ -60,3 +60,15 @@ viewer-count = { $count ->
[1] 1 espectador
*[other] { $count } espectadores
}
+
+## PDS Host Selector
+pds-selector-title = ¿Nuevo en Atmosphere?
+pds-selector-description = Necesitarás seleccionar un PDS (Servidor de Datos Personal) para acceder a apps en Atmosphere, como Bluesky, Tangled y Spark.
+pds-selector-custom-label = Otro PDS
+pds-selector-custom-description = Introduce la URL de tu propio servidor PDS
+pds-selector-custom-url-label = URL de PDS personalizado
+pds-selector-custom-url-placeholder = https://pds.ejemplo.com
+pds-selector-learn-more = Más información sobre el autoalojamiento
+pds-selector-info = Cada servidor tiene sus propias políticas y estándares de fiabilidad. Tus datos ATProto viven en el servidor que elijas y puedes migrar más tarde. Nota: Streamplace tiene sus propias reglas de moderación; puedes ser expulsado de Streamplace independientemente del servidor que elijas.
+pds-selector-read-policies = Lee los Términos de Servicio y la Política de Privacidad de { $label } antes de continuar.
+pds-selector-handle-policy-checkbox = He leído y acepto la política de identificadores
diff --git a/js/components/locales/es-ES/settings.ftl b/js/components/locales/es-ES/settings.ftl
index c75556d2d..21db93e9a 100644
--- a/js/components/locales/es-ES/settings.ftl
+++ b/js/components/locales/es-ES/settings.ftl
@@ -177,3 +177,154 @@ backup-error-update-failed = Error al actualizar el estado de la copia de seguri
backup-error-save-failed = Error al guardar los ajustes de almacenamiento
backup-error-missing-secret = No se pueden actualizar los ajustes de S3 sin la clave secreta. Por favor, vuelva a introducirla.
backup-segment-duration-placeholder = 6
+
+## Backup Settings
+backup = Copia de seguridad
+backup-enabled = S3 Backup
+backup-enabled-description = Respaldar automáticamente las grabaciones en almacenamiento compatible con S3
+backup-connection-url = URL de conexión
+backup-connection-url-placeholder = s3+https://ACCESS_KEY:SECRET_KEY@s3.example.com/bucket
+backup-endpoint = Punto de conexión
+backup-endpoint-placeholder = s3.example.com
+backup-bucket = Contenedor
+backup-bucket-placeholder = my-backup-bucket
+backup-access-key = Clave de acceso
+backup-access-key-placeholder = AKIAIOSFODNN7EXAMPLE
+backup-secret-key = Clave secreta
+backup-secret-key-placeholder = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
+show-password-in-url = Mostrar contraseña en la URL
+show-password-in-url-description = Mostrar la clave secreta en la URL de conexión (si se introduce)
+
+## Recommendations
+recommendations-to-others = Recomendaciones a otros
+recommendations-description = Comparte hasta 8 streamers que recomiendas a tus espectadores
+no-recommendations-yet = No hay recomendaciones configuradas todavía
+
+## Multistreaming
+multistream = Multi-transmisión
+multistream-targets = Objetivos de multi-transmisión
+multistream-description = Envía automáticamente tus transmisiones en directo de Streamplace a otros servicios de streaming como Twitch o YouTube.
+create-multistream-target = Crear objetivo de multi-transmisión
+untitled-multistream-target = Objetivo sin título
+failed-load-multistream-targets = Error al cargar los objetivos de multi-transmisión. Por favor, inténtalo de nuevo.
+failed-toggle-multistream-target = Error al cambiar el estado del objetivo de multi-transmisión. Por favor, inténtalo de nuevo.
+no-multistream-targets-yet = ¡Aún no hay objetivos!
+multistream-targets-count = { $count ->
+ [one] { $count } objetivo
+ [many] { $count } objetivos
+ *[other] { $count } objetivos
+}
+multistream-delete-target-confirmation = ¿Estás seguro de que quieres eliminar "{ $target }"?
+this-action-cannot-be-undone = Esta acción no se puede deshacer.
+rtmp-target-name = Objetivo RTMP
+rtmp-target-url = URL de RTMP
+rtmp-target-name-placeholder = Mi objetivo de multi-transmisión
+multistream-create-target = Crear objetivo
+multistream-edit-target = Editar objetivo
+created = creado
+status = estado
+
+## Branding Administration
+branding = Branding
+branding-admin = Administración de branding
+branding-admin-description = Personaliza tu instancia de Streamplace. Ten en cuenta que la configuración puede tardar varias horas en propagarse.
+branding-login-required = Por favor, inicia sesión para gestionar el branding
+branding-configuration = Configuración
+branding-text-settings = Configuración de texto
+branding-colors = Colores
+branding-legal-links = Vínculos legales
+branding-images = Imágenes
+
+## Branding Fields
+branding-broadcaster-did = DID del radiodifusor
+branding-broadcaster-did-description = Dejar vacío para usar el valor predeterminado del servidor
+branding-site-title = Título del sitio
+branding-site-title-placeholder = Introduce un nuevo título de sitio
+branding-site-description = Descripción del sitio
+branding-site-description-placeholder = Introduce la descripción del sitio
+branding-default-streamer = Streamer predeterminado
+branding-default-streamer-none = Ninguno
+branding-default-streamer-placeholder = did:plc:...
+branding-clear-default-streamer = Quitar streamer predeterminado
+branding-primary-color = Color principal
+branding-primary-color-placeholder = #6366f1
+branding-accent-color = Color de acento
+branding-accent-color-placeholder = #8b5cf6
+branding-main-logo = Logo principal
+branding-main-logo-description = SVG, PNG o JPEG (máx. 500KB)
+branding-favicon = Favicon
+branding-favicon-description = SVG, PNG o ICO (máx. 100KB)
+branding-sidebar-bg = Imagen de fondo de la barra lateral
+branding-sidebar-bg-description = SVG, PNG o JPEG (máx. 500kb) - aparece alineada en la parte inferior de la barra lateral, a todo el ancho. Sube una imagen con opacidad para mejores resultados, ya que actualmente no hay una opción de opacidad separada.
+branding-current = Actual: { $value }
+branding-dimensions = { $height } x { $width }
+
+## Branding Actions
+branding-upload-logo = Subir logo
+branding-delete-logo = Eliminar logo
+branding-upload-favicon = Subir favicon
+branding-delete-favicon = Eliminar favicon
+branding-upload-background = Subir imagen de fondo
+branding-delete-background = Eliminar imagen de fondo
+branding-web-only = La subida de imágenes solo está disponible en la web.
+
+## Branding Legal Links
+refresh-branding = Actualizar recursos de branding
+branding-add-legal-link = Agregar vínculo legal
+branding-edit-legal-link = Editar vínculo legal
+branding-legal-link-text-placeholder = Texto del vínculo (ej., Política de Privacidad)
+branding-legal-link-url-placeholder = URL (ej., https://ejemplo.com/privacidad)
+add = Agregar
+active = Activo
+optional = opcional
+
+## Branding Toast Messages
+branding-not-authenticated = Por favor, inicia sesión primero
+branding-empty-value = Por favor, introduce un valor
+branding-update-success = { $key } actualizado correctamente
+branding-upload-success = { $key } subido correctamente
+branding-delete-success = { $key } eliminado correctamente
+branding-upload-failed = Error al subir
+branding-delete-failed = Error al eliminar
+branding-not-available = La subida de archivos solo está disponible en la web
+
+## Navigation Categories (About Page)
+node-legal-documents = Documentos específicos del radiodifusor
+
+## Badges
+badges = Insignias
+badges-cosmetic-section = Insignias cosméticas
+badges-empty-state = Aún no te han otorgado ninguna insignia.
+badges-failed-load = Error al cargar las insignias
+badges-failed-update = Error al actualizar la selección de insignias
+badges-issued-by = Otorgada por { $issuer }
+badges-streamer-section = Insignias del streamer
+
+## Issue Badges
+issue-badges = Emitir insignias
+issue-badges-back-to-definitions = Definiciones de insignias
+issue-badges-badge-name = Nombre de la insignia
+issue-badges-badge-name-placeholder = ej. VIP, Colaborador
+issue-badges-badge-type = Tipo de insignia
+issue-badges-choose-image = Elegir imagen
+issue-badges-create-definition = Crear definición de insignia
+issue-badges-create-definition-description = Define un nuevo tipo de insignia que se puede otorgar a los espectadores
+issue-badges-create-definition-subtitle = Define un nuevo tipo de insignia
+issue-badges-definition-created = Definición de insignia creada
+issue-badges-description-optional = Descripción (opcional)
+issue-badges-description-placeholder = Descripción opcional para esta insignia
+issue-badges-failed-create = Error al crear la definición de insignia
+issue-badges-failed-issue = Error al emitir la insignia
+issue-badges-failed-load = Error al cargar las definiciones de insignias
+issue-badges-image-optional = Imagen (opcional)
+issue-badges-image-too-large = La imagen debe ser menor de 256KB
+issue-badges-image-web-only = La subida de imágenes solo está disponible en la web
+issue-badges-issue-badge = Emitir insignia
+issue-badges-issue-badge-description = Emite la insignia "{ $name }" a un espectador mediante su DID
+issue-badges-issued = Insignia emitida
+issue-badges-issued-to = Emitida a { $did }
+issue-badges-manage-description = Crea definiciones de insignias y emítelas a los espectadores
+issue-badges-recipient-did = DID del destinatario
+issue-badges-recipient-did-placeholder = did:plc:...
+issue-badges-tap-to-issue = Toca para emitir
+issue-badges-your-definitions = Tus definiciones de insignias
diff --git a/js/components/locales/fr-FR/common.ftl b/js/components/locales/fr-FR/common.ftl
index df6bce4aa..2f375fd27 100644
--- a/js/components/locales/fr-FR/common.ftl
+++ b/js/components/locales/fr-FR/common.ftl
@@ -60,3 +60,15 @@ viewer-count = { $count ->
[1] 1 spectateur
*[other] { $count } spectateurs
}
+
+## PDS Host Selector
+pds-selector-title = Nouveau sur Atmosphere ?
+pds-selector-description = Vous devrez sélectionner un PDS (Serveur de Données Personnel) pour accéder aux applications sur Atmosphere, comme Bluesky, Tangled et Spark.
+pds-selector-custom-label = Un autre PDS
+pds-selector-custom-description = Saisissez l'URL de votre propre hôte PDS
+pds-selector-custom-url-label = URL PDS personnalisée
+pds-selector-custom-url-placeholder = https://pds.exemple.com
+pds-selector-learn-more = En savoir plus sur l'auto-hébergement
+pds-selector-info = Chaque hôte a ses propres politiques et normes de fiabilité. Vos données ATProto se trouvent sur l'hôte que vous choisissez et vous pouvez migrer ultérieurement. Remarque : Streamplace a ses propres règles de modération — vous pouvez être banni de Streamplace quel que soit l'hôte choisi.
+pds-selector-read-policies = Lisez les Conditions d'utilisation et la Politique de confidentialité de { $label } avant de continuer.
+pds-selector-handle-policy-checkbox = J'ai lu et j'accepte la politique des identifiants
diff --git a/js/components/locales/fr-FR/settings.ftl b/js/components/locales/fr-FR/settings.ftl
index 619c1eeda..2f338953e 100644
--- a/js/components/locales/fr-FR/settings.ftl
+++ b/js/components/locales/fr-FR/settings.ftl
@@ -174,3 +174,154 @@ backup-error-update-failed = Échec de la mise à jour de l'état de la sauvegar
backup-error-save-failed = Échec de l'enregistrement des paramètres de stockage
backup-error-missing-secret = Impossible de mettre à jour les paramètres S3 sans la clé secrète. Veuillez la saisir à nouveau.
backup-segment-duration-placeholder = 6
+
+## Backup Settings
+backup = Sauvegarde
+backup-enabled = S3 Backup
+backup-enabled-description = Sauvegarder automatiquement les enregistrements dans un stockage compatible S3
+backup-connection-url = URL de connexion
+backup-connection-url-placeholder = s3+https://ACCESS_KEY:SECRET_KEY@s3.example.com/bucket
+backup-endpoint = Point de terminaison
+backup-endpoint-placeholder = s3.example.com
+backup-bucket = Compartiment
+backup-bucket-placeholder = my-backup-bucket
+backup-access-key = Clé d'accès
+backup-access-key-placeholder = AKIAIOSFODNN7EXAMPLE
+backup-secret-key = Clé secrète
+backup-secret-key-placeholder = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
+show-password-in-url = Afficher le mot de passe dans l'URL
+show-password-in-url-description = Afficher la clé secrète dans l'URL de connexion (si saisie)
+
+## Recommendations
+recommendations-to-others = Recommandations aux autres
+recommendations-description = Partagez jusqu'à 8 streameurs que vous recommandez à vos spectateurs
+no-recommendations-yet = Aucune recommandation configurée pour le moment
+
+## Multistreaming
+multistream = Multidiffusion
+multistream-targets = Cibles de multidiffusion
+multistream-description = Envoyez automatiquement vos diffusions en direct Streamplace vers d'autres services comme Twitch ou YouTube.
+create-multistream-target = Créer une cible de multidiffusion
+untitled-multistream-target = Cible sans titre
+failed-load-multistream-targets = Échec du chargement des cibles de multidiffusion. Veuillez réessayer.
+failed-toggle-multistream-target = Échec du basculement de la cible de multidiffusion. Veuillez réessayer.
+no-multistream-targets-yet = Aucune cible pour le moment !
+multistream-targets-count = { $count ->
+ [one] { $count } cible
+ [many] { $count } cibles
+ *[other] { $count } cibles
+}
+multistream-delete-target-confirmation = Êtes-vous sûr de vouloir supprimer "{ $target }" ?
+this-action-cannot-be-undone = Cette action ne peut pas être annulée.
+rtmp-target-name = Cible RTMP
+rtmp-target-url = URL RTMP
+rtmp-target-name-placeholder = Ma cible de multidiffusion
+multistream-create-target = Créer la cible
+multistream-edit-target = Modifier la cible
+created = créé
+status = statut
+
+## Branding Administration
+branding = Image de marque
+branding-admin = Administration de l'image de marque
+branding-admin-description = Personnalisez votre instance Streamplace. Notez que les paramètres peuvent prendre quelques heures à se propager.
+branding-login-required = Veuillez vous connecter pour gérer l'image de marque
+branding-configuration = Configuration
+branding-text-settings = Paramètres de texte
+branding-colors = Couleurs
+branding-legal-links = Liens légaux
+branding-images = Images
+
+## Branding Fields
+branding-broadcaster-did = DID du diffuseur
+branding-broadcaster-did-description = Laisser vide pour utiliser la valeur par défaut du serveur
+branding-site-title = Titre du site
+branding-site-title-placeholder = Saisir un nouveau titre de site
+branding-site-description = Description du site
+branding-site-description-placeholder = Saisir la description du site
+branding-default-streamer = Streameur par défaut
+branding-default-streamer-none = Aucun
+branding-default-streamer-placeholder = did:plc:...
+branding-clear-default-streamer = Effacer le streameur par défaut
+branding-primary-color = Couleur principale
+branding-primary-color-placeholder = #6366f1
+branding-accent-color = Couleur d'accent
+branding-accent-color-placeholder = #8b5cf6
+branding-main-logo = Logo principal
+branding-main-logo-description = SVG, PNG ou JPEG (max 500 Ko)
+branding-favicon = Favicon
+branding-favicon-description = SVG, PNG ou ICO (max 100 Ko)
+branding-sidebar-bg = Image d'arrière-plan de la barre latérale
+branding-sidebar-bg-description = SVG, PNG ou JPEG (max 500 ko) - apparaît aligné en bas de la barre latérale, pleine largeur. Téléchargez une image avec opacité pour de meilleurs résultats, car il n'existe pas actuellement d'option d'opacité séparée.
+branding-current = Actuel : { $value }
+branding-dimensions = { $height } x { $width }
+
+## Branding Actions
+branding-upload-logo = Télécharger le logo
+branding-delete-logo = Supprimer le logo
+branding-upload-favicon = Télécharger le favicon
+branding-delete-favicon = Supprimer le favicon
+branding-upload-background = Télécharger l'arrière-plan
+branding-delete-background = Supprimer l'arrière-plan
+branding-web-only = Les téléchargements d'images ne sont disponibles que sur le web.
+
+## Branding Legal Links
+refresh-branding = Actualiser les ressources de l'image de marque
+branding-add-legal-link = Ajouter un lien légal
+branding-edit-legal-link = Modifier le lien légal
+branding-legal-link-text-placeholder = Texte du lien (ex., Politique de confidentialité)
+branding-legal-link-url-placeholder = URL (ex., https://exemple.com/confidentialite)
+add = Ajouter
+active = Actif
+optional = optionnel
+
+## Branding Toast Messages
+branding-not-authenticated = Veuillez d'abord vous connecter
+branding-empty-value = Veuillez saisir une valeur
+branding-update-success = { $key } mis à jour avec succès
+branding-upload-success = { $key } téléchargé avec succès
+branding-delete-success = { $key } supprimé avec succès
+branding-upload-failed = Échec du téléchargement
+branding-delete-failed = Échec de la suppression
+branding-not-available = Les téléchargements de fichiers ne sont disponibles que sur le web
+
+## Navigation Categories (About Page)
+node-legal-documents = Documents spécifiques au diffuseur
+
+## Badges
+badges = Badges
+badges-cosmetic-section = Badges cosmétiques
+badges-empty-state = Vous n'avez pas encore reçu de badges.
+badges-failed-load = Échec du chargement des badges
+badges-failed-update = Échec de la mise à jour de la sélection de badges
+badges-issued-by = Délivré par { $issuer }
+badges-streamer-section = Badges du streameur
+
+## Issue Badges
+issue-badges = Délivrer des badges
+issue-badges-back-to-definitions = Définitions de badges
+issue-badges-badge-name = Nom du badge
+issue-badges-badge-name-placeholder = ex. VIP, Supporter
+issue-badges-badge-type = Type de badge
+issue-badges-choose-image = Choisir une image
+issue-badges-create-definition = Créer une définition de badge
+issue-badges-create-definition-description = Définissez un nouveau type de badge qui peut être délivré aux spectateurs
+issue-badges-create-definition-subtitle = Définir un nouveau type de badge
+issue-badges-definition-created = Définition de badge créée
+issue-badges-description-optional = Description (optionnelle)
+issue-badges-description-placeholder = Description optionnelle pour ce badge
+issue-badges-failed-create = Échec de la création de la définition de badge
+issue-badges-failed-issue = Échec de la délivrance du badge
+issue-badges-failed-load = Échec du chargement des définitions de badges
+issue-badges-image-optional = Image (optionnelle)
+issue-badges-image-too-large = L'image doit faire moins de 256 Ko
+issue-badges-image-web-only = Le téléchargement d'images n'est disponible que sur le web
+issue-badges-issue-badge = Délivrer un badge
+issue-badges-issue-badge-description = Délivrez le badge "{ $name }" à un spectateur par son DID
+issue-badges-issued = Badge délivré
+issue-badges-issued-to = Délivré à { $did }
+issue-badges-manage-description = Créez des définitions de badges et délivrez-les aux spectateurs
+issue-badges-recipient-did = DID du destinataire
+issue-badges-recipient-did-placeholder = did:plc:...
+issue-badges-tap-to-issue = Appuyer pour délivrer
+issue-badges-your-definitions = Vos définitions de badges
diff --git a/js/components/locales/pt-BR/common.ftl b/js/components/locales/pt-BR/common.ftl
index 27f8f4ef3..096313b42 100644
--- a/js/components/locales/pt-BR/common.ftl
+++ b/js/components/locales/pt-BR/common.ftl
@@ -60,3 +60,15 @@ viewer-count = { $count ->
[1] 1 espectador
*[other] { $count } espectadores
}
+
+## PDS Host Selector
+pds-selector-title = Novo no Atmosphere?
+pds-selector-description = Você precisará selecionar um PDS (Servidor de Dados Pessoal) para acessar apps no Atmosphere, como Bluesky, Tangled e Spark.
+pds-selector-custom-label = Outro PDS
+pds-selector-custom-description = Digite a URL do seu próprio host PDS
+pds-selector-custom-url-label = URL do PDS personalizado
+pds-selector-custom-url-placeholder = https://pds.exemplo.com
+pds-selector-learn-more = Saiba mais sobre auto-hospedagem
+pds-selector-info = Cada host tem suas próprias políticas e padrões de confiabilidade. Seus dados ATProto ficam no host que você escolher e você pode migrar depois. Nota: O Streamplace tem suas próprias regras de moderação — você pode ser banido do Streamplace independentemente do host escolhido.
+pds-selector-read-policies = Leia os Termos de Serviço e a Política de Privacidade de { $label } antes de continuar.
+pds-selector-handle-policy-checkbox = Li e concordo com a política de identificadores
diff --git a/js/components/locales/pt-BR/settings.ftl b/js/components/locales/pt-BR/settings.ftl
index a7e391181..08712eeb4 100644
--- a/js/components/locales/pt-BR/settings.ftl
+++ b/js/components/locales/pt-BR/settings.ftl
@@ -175,3 +175,154 @@ backup-error-update-failed = Falha ao atualizar o status do backup
backup-error-save-failed = Falha ao salvar as configurações de armazenamento
backup-error-missing-secret = Não é possível atualizar as configurações do S3 sem a chave secreta. Por favor, insira-a novamente.
backup-segment-duration-placeholder = 6
+
+## Backup Settings
+backup = Backup
+backup-enabled = S3 Backup
+backup-enabled-description = Fazer backup automaticamente das gravações em armazenamento compatível com S3
+backup-connection-url = URL de conexão
+backup-connection-url-placeholder = s3+https://ACCESS_KEY:SECRET_KEY@s3.example.com/bucket
+backup-endpoint = Endpoint
+backup-endpoint-placeholder = s3.example.com
+backup-bucket = Bucket
+backup-bucket-placeholder = my-backup-bucket
+backup-access-key = Chave de acesso
+backup-access-key-placeholder = AKIAIOSFODNN7EXAMPLE
+backup-secret-key = Chave secreta
+backup-secret-key-placeholder = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
+show-password-in-url = Mostrar senha na URL
+show-password-in-url-description = Exibir a chave secreta na URL de conexão (se inserida)
+
+## Recommendations
+recommendations-to-others = Recomendações para outros
+recommendations-description = Compartilhe até 8 streamers que você recomenda aos seus espectadores
+no-recommendations-yet = Nenhuma recomendação configurada ainda
+
+## Multistreaming
+multistream = Multitransmissão
+multistream-targets = Destinos de multitransmissão
+multistream-description = Envie automaticamente suas transmissões ao vivo do Streamplace para outros serviços como Twitch ou YouTube.
+create-multistream-target = Criar destino de multitransmissão
+untitled-multistream-target = Destino sem título
+failed-load-multistream-targets = Falha ao carregar os destinos de multitransmissão. Por favor, tente novamente.
+failed-toggle-multistream-target = Falha ao alternar o destino de multitransmissão. Por favor, tente novamente.
+no-multistream-targets-yet = Nenhum destino ainda!
+multistream-targets-count = { $count ->
+ [one] { $count } destino
+ [many] { $count } destinos
+ *[other] { $count } destinos
+}
+multistream-delete-target-confirmation = Tem certeza de que deseja excluir "{ $target }"?
+this-action-cannot-be-undone = Esta ação não pode ser desfeita.
+rtmp-target-name = Destino RTMP
+rtmp-target-url = URL RTMP
+rtmp-target-name-placeholder = Meu destino de multitransmissão
+multistream-create-target = Criar destino
+multistream-edit-target = Editar destino
+created = criado
+status = status
+
+## Branding Administration
+branding = Identidade visual
+branding-admin = Administração de identidade visual
+branding-admin-description = Personalize sua instância do Streamplace. As configurações podem levar algumas horas para se propagar.
+branding-login-required = Faça login para gerenciar a identidade visual
+branding-configuration = Configuração
+branding-text-settings = Configurações de texto
+branding-colors = Cores
+branding-legal-links = Links legais
+branding-images = Imagens
+
+## Branding Fields
+branding-broadcaster-did = DID do transmissor
+branding-broadcaster-did-description = Deixe vazio para usar o padrão do servidor
+branding-site-title = Título do site
+branding-site-title-placeholder = Digite o novo título do site
+branding-site-description = Descrição do site
+branding-site-description-placeholder = Digite a descrição do site
+branding-default-streamer = Streamer padrão
+branding-default-streamer-none = Nenhum
+branding-default-streamer-placeholder = did:plc:...
+branding-clear-default-streamer = Limpar streamer padrão
+branding-primary-color = Cor principal
+branding-primary-color-placeholder = #6366f1
+branding-accent-color = Cor de destaque
+branding-accent-color-placeholder = #8b5cf6
+branding-main-logo = Logo principal
+branding-main-logo-description = SVG, PNG ou JPEG (máx. 500KB)
+branding-favicon = Favicon
+branding-favicon-description = SVG, PNG ou ICO (máx. 100KB)
+branding-sidebar-bg = Imagem de fundo da barra lateral
+branding-sidebar-bg-description = SVG, PNG ou JPEG (máx. 500kb) - aparece alinhada na parte inferior da barra lateral, largura total. Faça upload de uma imagem com opacidade para melhores resultados, pois atualmente não há uma opção de opacidade separada.
+branding-current = Atual: { $value }
+branding-dimensions = { $height } x { $width }
+
+## Branding Actions
+branding-upload-logo = Enviar logo
+branding-delete-logo = Excluir logo
+branding-upload-favicon = Enviar favicon
+branding-delete-favicon = Excluir favicon
+branding-upload-background = Enviar plano de fundo
+branding-delete-background = Excluir plano de fundo
+branding-web-only = O upload de imagens só está disponível na web.
+
+## Branding Legal Links
+refresh-branding = Atualizar recursos de identidade visual
+branding-add-legal-link = Adicionar link legal
+branding-edit-legal-link = Editar link legal
+branding-legal-link-text-placeholder = Texto do link (ex., Política de Privacidade)
+branding-legal-link-url-placeholder = URL (ex., https://exemplo.com/privacidade)
+add = Adicionar
+active = Ativo
+optional = opcional
+
+## Branding Toast Messages
+branding-not-authenticated = Faça login primeiro
+branding-empty-value = Por favor, insira um valor
+branding-update-success = { $key } atualizado com sucesso
+branding-upload-success = { $key } enviado com sucesso
+branding-delete-success = { $key } excluído com sucesso
+branding-upload-failed = Falha ao enviar
+branding-delete-failed = Falha ao excluir
+branding-not-available = O upload de arquivos só está disponível na web
+
+## Navigation Categories (About Page)
+node-legal-documents = Documentos específicos do transmissor
+
+## Badges
+badges = Emblemas
+badges-cosmetic-section = Emblemas cosméticos
+badges-empty-state = Você ainda não recebeu nenhum emblema.
+badges-failed-load = Falha ao carregar emblemas
+badges-failed-update = Falha ao atualizar a seleção de emblemas
+badges-issued-by = Emitido por { $issuer }
+badges-streamer-section = Emblemas do streamer
+
+## Issue Badges
+issue-badges = Emitir emblemas
+issue-badges-back-to-definitions = Definições de emblemas
+issue-badges-badge-name = Nome do emblema
+issue-badges-badge-name-placeholder = ex. VIP, Apoiador
+issue-badges-badge-type = Tipo de emblema
+issue-badges-choose-image = Escolher imagem
+issue-badges-create-definition = Criar definição de emblema
+issue-badges-create-definition-description = Defina um novo tipo de emblema que pode ser emitido para espectadores
+issue-badges-create-definition-subtitle = Defina um novo tipo de emblema
+issue-badges-definition-created = Definição de emblema criada
+issue-badges-description-optional = Descrição (opcional)
+issue-badges-description-placeholder = Descrição opcional para este emblema
+issue-badges-failed-create = Falha ao criar a definição de emblema
+issue-badges-failed-issue = Falha ao emitir o emblema
+issue-badges-failed-load = Falha ao carregar as definições de emblemas
+issue-badges-image-optional = Imagem (opcional)
+issue-badges-image-too-large = A imagem deve ter menos de 256KB
+issue-badges-image-web-only = O upload de imagens só está disponível na web
+issue-badges-issue-badge = Emitir emblema
+issue-badges-issue-badge-description = Emita o emblema "{ $name }" para um espectador pelo seu DID
+issue-badges-issued = Emblema emitido
+issue-badges-issued-to = Emitido para { $did }
+issue-badges-manage-description = Crie definições de emblemas e emita-os para espectadores
+issue-badges-recipient-did = DID do destinatário
+issue-badges-recipient-did-placeholder = did:plc:...
+issue-badges-tap-to-issue = Toque para emitir
+issue-badges-your-definitions = Suas definições de emblemas
diff --git a/js/components/locales/ro-RO/settings.ftl b/js/components/locales/ro-RO/settings.ftl
index 572cd5607..6fa630eb7 100644
--- a/js/components/locales/ro-RO/settings.ftl
+++ b/js/components/locales/ro-RO/settings.ftl
@@ -231,3 +231,41 @@ branding-not-available = Încărcarea de fișiere este disponibilă doar pe web.
## Navigation Categories (About Page)
node-legal-documents = Documente specifice radiodifuzorului
+
+## Badges
+badges = Insigne
+badges-cosmetic-section = Insigne cosmetice
+badges-empty-state = Nu ți-a fost acordată nicio insignă încă.
+badges-failed-load = Nu s-au putut încărca insignele
+badges-failed-update = Nu s-a putut actualiza selecția de insigne
+badges-issued-by = Acordată de { $issuer }
+badges-streamer-section = Insigne de la streameri
+
+## Issue Badges
+issue-badges = Emitere insigne
+issue-badges-back-to-definitions = Definiții insigne
+issue-badges-badge-name = Numele insignei
+issue-badges-badge-name-placeholder = ex. VIP, Susținător
+issue-badges-badge-type = Tipul insignei
+issue-badges-choose-image = Alegeți imaginea
+issue-badges-create-definition = Creare definiție insignă
+issue-badges-create-definition-description = Definiți un nou tip de insignă care poate fi acordată spectatorilor
+issue-badges-create-definition-subtitle = Definiți un nou tip de insignă
+issue-badges-definition-created = Definiție insignă creată
+issue-badges-description-optional = Descriere (opțional)
+issue-badges-description-placeholder = Descriere opțională pentru această insignă
+issue-badges-failed-create = Nu s-a putut crea definiția insignei
+issue-badges-failed-issue = Nu s-a putut emite insigna
+issue-badges-failed-load = Nu s-au putut încărca definițiile insignelor
+issue-badges-image-optional = Imagine (opțional)
+issue-badges-image-too-large = Imaginea trebuie să fie mai mică de 256KB
+issue-badges-image-web-only = Încărcarea imaginilor este disponibilă doar pe web
+issue-badges-issue-badge = Emite insignă
+issue-badges-issue-badge-description = Emite insigna „{ $name }" unui spectator prin DID-ul său
+issue-badges-issued = Insignă emisă
+issue-badges-issued-to = Emisă pentru { $did }
+issue-badges-manage-description = Creați definiții de insigne și emiteți-le spectatorilor
+issue-badges-recipient-did = DID destinatar
+issue-badges-recipient-did-placeholder = did:plc:...
+issue-badges-tap-to-issue = Atingeți pentru a emite
+issue-badges-your-definitions = Definițiile dvs. de insigne
diff --git a/js/components/locales/zh-Hans/settings.ftl b/js/components/locales/zh-Hans/settings.ftl
index 017b4e89a..9235e910b 100644
--- a/js/components/locales/zh-Hans/settings.ftl
+++ b/js/components/locales/zh-Hans/settings.ftl
@@ -260,3 +260,41 @@ backup-error-save-failed = 保存存储设置失败
backup-error-missing-secret = 没有秘密密钥时无法更新 S3 设置。请重新输入。
backup-segment-duration-placeholder = 6
backup-connection-url-placeholder = 必须是格式为 s3+https://ACCESS_KEY:SECRET_KEY@region.endpoi.nt/bucket 的有效 S3 网址
+
+## 徽章
+badges = 徽章
+badges-cosmetic-section = 装饰性徽章
+badges-empty-state = 您还没有获得任何徽章。
+badges-failed-load = 加载徽章失败
+badges-failed-update = 更新徽章选择失败
+badges-issued-by = 由 { $issuer } 颁发
+badges-streamer-section = 主播徽章
+
+## 颁发徽章
+issue-badges = 颁发徽章
+issue-badges-back-to-definitions = 徽章定义
+issue-badges-badge-name = 徽章名称
+issue-badges-badge-name-placeholder = 例如 VIP、支持者
+issue-badges-badge-type = 徽章类型
+issue-badges-choose-image = 选择图片
+issue-badges-create-definition = 创建徽章定义
+issue-badges-create-definition-description = 定义可颁发给观众的新徽章类型
+issue-badges-create-definition-subtitle = 定义新徽章类型
+issue-badges-definition-created = 徽章定义已创建
+issue-badges-description-optional = 描述(可选)
+issue-badges-description-placeholder = 此徽章的可选描述
+issue-badges-failed-create = 创建徽章定义失败
+issue-badges-failed-issue = 颁发徽章失败
+issue-badges-failed-load = 加载徽章定义失败
+issue-badges-image-optional = 图片(可选)
+issue-badges-image-too-large = 图片必须小于 256KB
+issue-badges-image-web-only = 图片上传仅在网页版可用
+issue-badges-issue-badge = 颁发徽章
+issue-badges-issue-badge-description = 通过 DID 将"{ $name }"徽章颁发给观众
+issue-badges-issued = 徽章已颁发
+issue-badges-issued-to = 已颁发给 { $did }
+issue-badges-manage-description = 创建徽章定义并颁发给观众
+issue-badges-recipient-did = 收件人 DID
+issue-badges-recipient-did-placeholder = did:plc:...
+issue-badges-tap-to-issue = 点击颁发
+issue-badges-your-definitions = 您的徽章定义
diff --git a/js/components/locales/zh-Hant/common.ftl b/js/components/locales/zh-Hant/common.ftl
index d8d7ae38c..c92043e9e 100644
--- a/js/components/locales/zh-Hant/common.ftl
+++ b/js/components/locales/zh-Hant/common.ftl
@@ -60,3 +60,15 @@ viewer-count = { $count ->
[1] 1 位觀眾
*[other] { $count } 位觀眾
}
+
+## PDS Host Selector
+pds-selector-title = 初次接觸 Atmosphere?
+pds-selector-description = 您需要選擇一個 PDS(個人資料伺服器)來存取 Atmosphere 上的應用程式,例如 Bluesky、Tangled 和 Spark。
+pds-selector-custom-label = 其他 PDS
+pds-selector-custom-description = 輸入您自己的 PDS 主機網址
+pds-selector-custom-url-label = 自訂 PDS 網址
+pds-selector-custom-url-placeholder = https://pds.example.com
+pds-selector-learn-more = 了解更多關於自行架設的資訊
+pds-selector-info = 每個主機都有自己的政策和可靠性標準。您的 ATProto 資料存放在您選擇的主機上,您可以之後進行遷移。注意:Streamplace 有自己的審核規則——無論您選擇哪個主機,都可能被 Streamplace 封禁。
+pds-selector-read-policies = 在繼續之前,請閱讀 { $label } 的服務條款和隱私政策。
+pds-selector-handle-policy-checkbox = 我已閱讀並同意識別碼政策
diff --git a/js/components/locales/zh-Hant/settings.ftl b/js/components/locales/zh-Hant/settings.ftl
index 5f93b1208..f0522c9cc 100644
--- a/js/components/locales/zh-Hant/settings.ftl
+++ b/js/components/locales/zh-Hant/settings.ftl
@@ -170,3 +170,150 @@ backup-error-update-failed = 更新備份狀態失敗
backup-error-save-failed = 儲存設定失敗
backup-error-missing-secret = 無法在沒有金鑰的情況下更新 S3 設定。請重新輸入。
backup-segment-duration-placeholder = 6
+
+## 備份設定
+backup = 備份
+backup-enabled = S3 備份
+backup-enabled-description = 自動將錄影備份到相容 S3 的儲存空間
+backup-connection-url = 連線網址
+backup-connection-url-placeholder = s3+https://ACCESS_KEY:SECRET_KEY@s3.example.com/bucket
+backup-endpoint = 端點
+backup-endpoint-placeholder = s3.example.com
+backup-bucket = 儲存桶
+backup-bucket-placeholder = my-backup-bucket
+backup-access-key = 存取金鑰
+backup-access-key-placeholder = AKIAIOSFODNN7EXAMPLE
+backup-secret-key = 秘密金鑰
+backup-secret-key-placeholder = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
+show-password-in-url = 在網址中顯示密碼
+show-password-in-url-description = 在連線網址中顯示秘密金鑰(若已輸入)
+
+## 推薦主播
+recommendations-to-others = 向他人推薦主播
+recommendations-description = 向您的觀眾推薦最多 8 位主播
+no-recommendations-yet = 尚未設定推薦
+
+## 多重串流
+multistream = 多重串流
+multistream-targets = 多重串流目標
+multistream-description = 自動將您的 Streamplace 直播推送到 Twitch 或 YouTube 等其他直播平台。
+create-multistream-target = 建立多重串流目標
+untitled-multistream-target = 未命名目標
+failed-load-multistream-targets = 載入多重串流目標失敗。請重試。
+failed-toggle-multistream-target = 切換多重串流目標失敗。請重試。
+no-multistream-targets-yet = 還沒有目標!
+multistream-targets-count = { $count } 個目標
+multistream-delete-target-confirmation = 您確定要刪除「{ $target }」嗎?
+this-action-cannot-be-undone = 此動作無法復原。
+rtmp-target-name = RTMP 目標
+rtmp-target-url = RTMP 網址
+rtmp-target-name-placeholder = 我的多重串流目標
+multistream-create-target = 建立目標
+multistream-edit-target = 編輯目標
+created = 建立於
+status = 狀態
+
+## 品牌識別管理
+branding = 品牌識別
+branding-admin = 品牌識別管理
+branding-admin-description = 自訂您的 Streamplace 執行個體。請注意,設定可能需要幾小時才能生效。
+branding-login-required = 請登入以管理品牌識別
+branding-configuration = 設定
+branding-text-settings = 文字設定
+branding-colors = 顏色
+branding-legal-links = 法律連結
+branding-images = 圖像
+
+## 品牌識別欄位
+branding-broadcaster-did = 主播 DID
+branding-broadcaster-did-description = 留空以使用伺服器預設值
+branding-site-title = 網站標題
+branding-site-title-placeholder = 輸入新網站標題
+branding-site-description = 網站描述
+branding-site-description-placeholder = 輸入網站描述
+branding-default-streamer = 預設主播
+branding-default-streamer-none = 無
+branding-default-streamer-placeholder = did:plc:...
+branding-clear-default-streamer = 清除預設主播
+branding-primary-color = 主要顏色
+branding-primary-color-placeholder = #6366f1
+branding-accent-color = 強調色
+branding-accent-color-placeholder = #8b5cf6
+branding-main-logo = 主標誌
+branding-main-logo-description = SVG、PNG 或 JPEG(最大 500KB)
+branding-favicon = 網站圖示
+branding-favicon-description = SVG、PNG 或 ICO(最大 100KB)
+branding-sidebar-bg = 側邊欄背景圖片
+branding-sidebar-bg-description = SVG、PNG 或 JPEG(最大 500KB)——顯示在側邊欄底部,全寬顯示。為了最佳效果,請上傳帶有透明度的圖片,因為目前沒有單獨的透明度選項。
+branding-current = 目前:{ $value }
+branding-dimensions = { $height } x { $width }
+
+## 品牌識別動作
+branding-upload-logo = 上傳標誌
+branding-delete-logo = 刪除標誌
+branding-upload-favicon = 上傳網站圖示
+branding-delete-favicon = 刪除網站圖示
+branding-upload-background = 上傳背景
+branding-delete-background = 刪除背景
+branding-web-only = 圖片上傳僅在網頁版可用。
+
+## 品牌識別法律連結
+refresh-branding = 更新品牌識別資源
+branding-add-legal-link = 新增法律連結
+branding-edit-legal-link = 編輯法律連結
+branding-legal-link-text-placeholder = 連結文字(例如:隱私政策)
+branding-legal-link-url-placeholder = 網址(例如:https://example.com/privacy)
+add = 新增
+active = 啟用
+optional = 選填
+
+## 品牌識別提示訊息
+branding-not-authenticated = 請先登入
+branding-empty-value = 請輸入一個值
+branding-update-success = { $key } 更新成功
+branding-upload-success = { $key } 上傳成功
+branding-delete-success = { $key } 刪除成功
+branding-upload-failed = 上傳失敗
+branding-delete-failed = 刪除失敗
+branding-not-available = 檔案上傳僅在網頁版可用
+
+## 導航類別(關於頁面)
+node-legal-documents = 主播專屬文件
+
+## 徽章
+badges = 徽章
+badges-cosmetic-section = 裝飾性徽章
+badges-empty-state = 您尚未獲得任何徽章。
+badges-failed-load = 載入徽章失敗
+badges-failed-update = 更新徽章選擇失敗
+badges-issued-by = 由 { $issuer } 頒發
+badges-streamer-section = 主播徽章
+
+## 頒發徽章
+issue-badges = 頒發徽章
+issue-badges-back-to-definitions = 徽章定義
+issue-badges-badge-name = 徽章名稱
+issue-badges-badge-name-placeholder = 例如 VIP、支持者
+issue-badges-badge-type = 徽章類型
+issue-badges-choose-image = 選擇圖片
+issue-badges-create-definition = 建立徽章定義
+issue-badges-create-definition-description = 定義可頒發給觀眾的新徽章類型
+issue-badges-create-definition-subtitle = 定義新徽章類型
+issue-badges-definition-created = 徽章定義已建立
+issue-badges-description-optional = 描述(選填)
+issue-badges-description-placeholder = 此徽章的選填描述
+issue-badges-failed-create = 建立徽章定義失敗
+issue-badges-failed-issue = 頒發徽章失敗
+issue-badges-failed-load = 載入徽章定義失敗
+issue-badges-image-optional = 圖片(選填)
+issue-badges-image-too-large = 圖片必須小於 256KB
+issue-badges-image-web-only = 圖片上傳僅在網頁版可用
+issue-badges-issue-badge = 頒發徽章
+issue-badges-issue-badge-description = 透過 DID 將「{ $name }」徽章頒發給觀眾
+issue-badges-issued = 徽章已頒發
+issue-badges-issued-to = 已頒發給 { $did }
+issue-badges-manage-description = 建立徽章定義並頒發給觀眾
+issue-badges-recipient-did = 收件者 DID
+issue-badges-recipient-did-placeholder = did:plc:...
+issue-badges-tap-to-issue = 點擊頒發
+issue-badges-your-definitions = 您的徽章定義