diff --git a/locales/bg-BG/chat.json b/locales/bg-BG/chat.json index 6abb5f25..58e01826 100644 --- a/locales/bg-BG/chat.json +++ b/locales/bg-BG/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Здравей, нека си поговорим", "helloDance": "Здравей, нека танцуваме заедно", - "market": "Пазар" + "market": "Пазар", + "selectRole": "Изберете роля" } diff --git a/locales/bg-BG/common.json b/locales/bg-BG/common.json index 4c243950..06108be2 100644 --- a/locales/bg-BG/common.json +++ b/locales/bg-BG/common.json @@ -12,6 +12,7 @@ "confirmDel": "Сигурни ли сте, че искате да изтриете?", "copy": "Копиране", "copySuccess": "Копирането е успешно", + "danceMarket": "Пазар за танци", "del": "Изтриване", "delAndRegenerate": "Изтриване и възстановяване", "downloadAvatar": "Изтегляне на аватар", @@ -22,7 +23,6 @@ "downloadSuccess": "Изтеглянето е успешно", "edit": "Редакция", "goBottom": "Към долната част", - "market": "Пазар", "pause": "Пауза", "play": "Пусни", "regenerate": "Възстановяване", @@ -34,6 +34,7 @@ "resetTitle": "Потвърждение за нулиране на всички системни настройки?", "save": "Запазване", "send": "Изпращане", + "sessionCreate": "Създаване на чат", "share": "Споделяне", "subscribe": "Абониране", "subscribeDance": "Абониране за танц", @@ -48,11 +49,13 @@ "cancel": "Отказ", "commonSetting": "Общи настройки", "confirm": "Потвърждение", + "danceList": "Списък с танци", "defaultAssistant": "По подразбиране асистент", "delAlert": "Сигурни ли сте, че искате да изтриете ролята и свързаните с нея сесии? След изтриване те няма да бъдат възстановени, моля, действайте внимателно!", "delRole": "Изтриване на роля", "delSession": "Изтриване на сесия", "delSessionAlert": "Сигурни ли сте, че искате да изтриете сесията? След изтриването, тя няма да бъде възстановена, моля, действайте внимателно!", + "history": "История на чата", "inputStartChat": "Моля, въведете съдържание, за да започнете разговор", "languageModel": "Езиков модел", "loading": "Зареждане...", @@ -69,7 +72,6 @@ "roleModel": "Role GPT модел", "useOwnKey": "Моля, използвайте собствения си ключ за OpenAI" }, - "playlist": "Плейлист", "search": "Търсене", "selectInDanceList": "Моля, изберете от списъка с танци", "selectModel": "Изберете модел", diff --git a/locales/bg-BG/features.json b/locales/bg-BG/features.json index 9fd52171..7ad6645b 100644 --- a/locales/bg-BG/features.json +++ b/locales/bg-BG/features.json @@ -16,9 +16,9 @@ "startTitle": "Персонализиран ключ за API" }, "info": { - "history": "История на чата", + "chat": "Чат", + "dance": "Танц", "motions": "Движения", - "playlist": "Плейлист", "posture": "Поза" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "Изтегляне на модела, моля изчакайте...", "floor": "Превключване на пода", "grid": "Мрежа", - "resetCamera": "Нулиране на камерата" + "resetCamera": "Нулиране на камерата", + "resetToIdle": "Спри танцуването", + "screenShot": "Снимка" } } diff --git a/locales/bg-BG/panel.json b/locales/bg-BG/panel.json index d1a65a6d..262a8165 100644 --- a/locales/bg-BG/panel.json +++ b/locales/bg-BG/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "Списък на движенията на героя", "noAnimations": "Няма налични анимации", + "postureList": "Списък с позиции", "totalCount": "Общо {{total}} елемента" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "Добавено в списъка за възпроизвеждане", "cancelAddPlay": "Сигурни ли сте, че искате да отмените абонамента за музиката {{musicName}}?", "cancelSubscribed": "Отказ от абонамент", + "confirmClearPlayList": "", "findDance": "Намери любимия ти танц", "musicAndDance": "Музика и танци", "noPlayList": "Няма плейлист, можете да се абонирате за танците, които обичате чрез пазара", diff --git a/locales/de-DE/chat.json b/locales/de-DE/chat.json index 11a736b8..c7eee9f9 100644 --- a/locales/de-DE/chat.json +++ b/locales/de-DE/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Hallo, lass uns chatten", "helloDance": "Hallo, lass uns tanzen", - "market": "Entdecken" + "market": "Entdecken", + "selectRole": "Wähle eine Rolle" } diff --git a/locales/de-DE/common.json b/locales/de-DE/common.json index 41cc9afb..406d73be 100644 --- a/locales/de-DE/common.json +++ b/locales/de-DE/common.json @@ -12,6 +12,7 @@ "confirmDel": "Sind Sie sicher, dass Sie löschen möchten?", "copy": "Kopieren", "copySuccess": "Erfolgreich kopiert", + "danceMarket": "Tanzmarkt", "del": "Löschen", "delAndRegenerate": "Löschen und neu generieren", "downloadAvatar": "Avatar herunterladen", @@ -22,7 +23,6 @@ "downloadSuccess": "Download erfolgreich", "edit": "Bearbeiten", "goBottom": "Zurück zum Ende", - "market": "Entdecken", "pause": "Pause", "play": "Abspielen", "regenerate": "Neu generieren", @@ -34,6 +34,7 @@ "resetTitle": "Alle Systemeinstellungen wirklich zurücksetzen?", "save": "Speichern", "send": "Senden", + "sessionCreate": "Chat erstellen", "share": "Teilen", "subscribe": "Abonnieren", "subscribeDance": "Tanz abonnieren", @@ -48,11 +49,13 @@ "cancel": "Abbrechen", "commonSetting": "Allgemeine Einstellungen", "confirm": "Bestätigen", + "danceList": "Tanzliste", "defaultAssistant": "Standardassistent", "delAlert": "Sind Sie sicher, dass Sie die Rolle und die zugehörigen Sitzungsnachrichten löschen möchten? Dies kann nicht rückgängig gemacht werden. Bitte seien Sie vorsichtig!", "delRole": "Rolle löschen", "delSession": "Sitzung löschen", "delSessionAlert": "Sind Sie sicher, dass Sie den Chat löschen möchten? Dies kann nicht rückgängig gemacht werden. Bitte seien Sie vorsichtig!", + "history": "Verlauf", "inputStartChat": "Geben Sie einen Text ein, um das Gespräch zu beginnen", "languageModel": "Sprachmodell", "loading": "Laden...", @@ -69,7 +72,6 @@ "roleModel": "Rollen-GPT-Modell", "useOwnKey": "Bitte verwenden Sie Ihren eigenen OpenAI-Schlüssel" }, - "playlist": "Wiedergabeliste", "search": "Suche", "selectInDanceList": "Bitte wählen Sie aus der Tanzliste aus", "selectModel": "Modell auswählen", diff --git a/locales/de-DE/features.json b/locales/de-DE/features.json index c1ac0dcf..ba5d9ef9 100644 --- a/locales/de-DE/features.json +++ b/locales/de-DE/features.json @@ -16,9 +16,9 @@ "startTitle": "Benutzerdefinierter API-Schlüssel" }, "info": { - "history": "Verlauf", + "chat": "Chat", + "dance": "Tanz", "motions": "Bewegungen", - "playlist": "Wiedergabeliste", "posture": "Haltung" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "Modell wird heruntergeladen, bitte warten...", "floor": "Boden wechseln", "grid": "Raster", - "resetCamera": "Kamera zurücksetzen" + "resetCamera": "Kamera zurücksetzen", + "resetToIdle": "Stoppen Sie den Tanz", + "screenShot": "Screenshot" } } diff --git a/locales/de-DE/panel.json b/locales/de-DE/panel.json index 6f791ede..b00831d3 100644 --- a/locales/de-DE/panel.json +++ b/locales/de-DE/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "Liste der Charakteranimationen", "noAnimations": "Keine Animationen verfügbar", + "postureList": "Haltung Liste", "totalCount": "Insgesamt {{total}} Einträge" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "Zur Wiedergabeliste hinzugefügt", "cancelAddPlay": "Möchten Sie das Abonnement für das Lied {{musicName}} wirklich abbrechen?", "cancelSubscribed": "Abonnement kündigen", + "confirmClearPlayList": "", "findDance": "Finde deinen Lieblingstanz", "musicAndDance": "Musik und Tanz", "noPlayList": "Keine Wiedergabeliste verfügbar. Sie können Ihre Lieblingstänze im Markt abonnieren.", diff --git a/locales/en-US/chat.json b/locales/en-US/chat.json index e5e80520..7cd551a1 100644 --- a/locales/en-US/chat.json +++ b/locales/en-US/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Hello, let's chat", "helloDance": "Hi, let's dance together", - "market": "Discover" + "market": "Discover", + "selectRole": "Select Role" } diff --git a/locales/en-US/common.json b/locales/en-US/common.json index cce23817..e01993c3 100644 --- a/locales/en-US/common.json +++ b/locales/en-US/common.json @@ -12,6 +12,7 @@ "confirmDel": "Are you sure you want to delete?", "copy": "Copy", "copySuccess": "Copy Successful", + "danceMarket": "Dance Market", "del": "Delete", "delAndRegenerate": "Delete and Regenerate", "downloadAvatar": "Download Avatar", @@ -22,7 +23,6 @@ "downloadSuccess": "Download Successful", "edit": "Edit", "goBottom": "Go to Bottom", - "market": "Discover", "pause": "Pause", "play": "Play", "regenerate": "Regenerate", @@ -34,6 +34,7 @@ "resetTitle": "Confirm Reset All System Settings?", "save": "Save", "send": "Send", + "sessionCreate": "Create Chat", "share": "Share", "subscribe": "Subscribe", "subscribeDance": "Subscribe to Dance", @@ -48,11 +49,13 @@ "cancel": "Cancel", "commonSetting": "Common Settings", "confirm": "Confirm", + "danceList": "Dance List", "defaultAssistant": "Default Assistant", "delAlert": "Are you sure you want to delete the role and its associated session messages? This action cannot be undone. Proceed with caution!", "delRole": "Delete Role", "delSession": "Delete Session", "delSessionAlert": "Are you sure you want to delete the conversation? This action cannot be undone. Proceed with caution!", + "history": "Chat History", "inputStartChat": "Please enter content to start chatting", "languageModel": "Language Model", "loading": "Loading...", @@ -69,7 +72,6 @@ "roleModel": "Role GPT Model", "useOwnKey": "Please use your own OpenAI Key" }, - "playlist": "Playlist", "search": "Search", "selectInDanceList": "Please select from the dance list", "selectModel": "Please select a model", diff --git a/locales/en-US/features.json b/locales/en-US/features.json index 293d6051..9ec83bfd 100644 --- a/locales/en-US/features.json +++ b/locales/en-US/features.json @@ -16,9 +16,9 @@ "startTitle": "Customize API Key" }, "info": { - "history": "Chat History", + "chat": "Chat", + "dance": "Dance", "motions": "Motions", - "playlist": "Playlist", "posture": "Posture" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "Model download in progress, please wait...", "floor": "Switch floor", "grid": "Grid", - "resetCamera": "Reset camera" + "resetCamera": "Reset camera", + "resetToIdle": "Stop Dancing", + "screenShot": "Take a Photo" } } diff --git a/locales/en-US/panel.json b/locales/en-US/panel.json index 12ae21d6..6b826cc7 100644 --- a/locales/en-US/panel.json +++ b/locales/en-US/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "Character animation list", "noAnimations": "No animations available", + "postureList": "Posture List", "totalCount": "Total {{total}} items" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "Added to playlist", "cancelAddPlay": "Are you sure you want to cancel subscribing to {{musicName}}?", "cancelSubscribed": "Unsubscribe", + "confirmClearPlayList": "", "findDance": "Find your favorite dance", "musicAndDance": "Music and Dance", "noPlayList": "No playlist available, you can subscribe to your favorite dances through the market", diff --git a/locales/es-ES/chat.json b/locales/es-ES/chat.json index e5e80520..71fec737 100644 --- a/locales/es-ES/chat.json +++ b/locales/es-ES/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Hello, let's chat", "helloDance": "Hi, let's dance together", - "market": "Discover" + "market": "Discover", + "selectRole": "Seleccionar rol" } diff --git a/locales/es-ES/common.json b/locales/es-ES/common.json index 645c7abb..bedac01a 100644 --- a/locales/es-ES/common.json +++ b/locales/es-ES/common.json @@ -12,6 +12,7 @@ "confirmDel": "¿Seguro que deseas eliminar?", "copy": "Copiar", "copySuccess": "¡Copiado exitosamente!", + "danceMarket": "Mercado de baile", "del": "Eliminar", "delAndRegenerate": "Eliminar y regenerar", "downloadAvatar": "Descargar avatar", @@ -22,7 +23,6 @@ "downloadSuccess": "Descarga exitosa", "edit": "Editar", "goBottom": "Ir al fondo", - "market": "Descubrir", "pause": "Pausa", "play": "Reproducir", "regenerate": "Regenerar", @@ -34,6 +34,7 @@ "resetTitle": "¿Confirmar restablecer todas las configuraciones del sistema?", "save": "Guardar", "send": "Enviar", + "sessionCreate": "Crear sesión de chat", "share": "Compartir", "subscribe": "Suscribir", "subscribeDance": "Suscribirse a la danza", @@ -48,11 +49,13 @@ "cancel": "Cancelar", "commonSetting": "Configuración común", "confirm": "Confirmar", + "danceList": "Lista de baile", "defaultAssistant": "Asistente predeterminado", "delAlert": "¿Confirmar eliminar el rol y los mensajes de la sesión relacionados? ¡Esta acción no se puede deshacer, por favor, proceda con precaución!", "delRole": "Eliminar rol", "delSession": "Eliminar sesión", "delSessionAlert": "¿Confirmar eliminar la conversación? ¡Esta acción no se puede deshacer, por favor, proceda con precaución!", + "history": "Historial de chat", "inputStartChat": "Ingresa contenido para comenzar a chatear", "languageModel": "Modelo de lenguaje", "loading": "Cargando...", @@ -69,7 +72,6 @@ "roleModel": "Modelo GPT de rol", "useOwnKey": "Utiliza tu propia clave de OpenAI" }, - "playlist": "Lista de reproducción", "search": "Buscar", "selectInDanceList": "Selecciona de la lista de danzas", "selectModel": "Selecciona un modelo", diff --git a/locales/es-ES/features.json b/locales/es-ES/features.json index 8ea58ad6..9a23985a 100644 --- a/locales/es-ES/features.json +++ b/locales/es-ES/features.json @@ -16,9 +16,9 @@ "startTitle": "Clave de API personalizada" }, "info": { - "history": "Historial de chat", + "chat": "Chat", + "dance": "Baile", "motions": "Movimientos", - "playlist": "Lista de reproducción", "posture": "Postura" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "Descargando modelo, por favor espera...", "floor": "Cambiar piso", "grid": "Cuadrícula", - "resetCamera": "Restablecer cámara" + "resetCamera": "Restablecer cámara", + "resetToIdle": "Detener la acción de baile", + "screenShot": "Captura de pantalla" } } diff --git a/locales/es-ES/panel.json b/locales/es-ES/panel.json index cc3a3e18..84eee0fe 100644 --- a/locales/es-ES/panel.json +++ b/locales/es-ES/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "Lista de Movimientos del Personaje", "noAnimations": "No hay animaciones disponibles", + "postureList": "Lista de posturas", "totalCount": "Total de {{total}} elementos" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "Agregado a la lista de reproducción", "cancelAddPlay": "¿Estás seguro de que quieres cancelar la suscripción a la música {{musicName}}?", "cancelSubscribed": "Cancelar suscripción", + "confirmClearPlayList": "", "findDance": "Encuentra tu baile favorito", "musicAndDance": "Música y baile", "noPlayList": "No hay listas de reproducción disponibles, puedes suscribirte a tus bailes favoritos en el mercado", diff --git a/locales/fr-FR/chat.json b/locales/fr-FR/chat.json index 9b5bb014..0cf2a454 100644 --- a/locales/fr-FR/chat.json +++ b/locales/fr-FR/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Bonjour, commençons à discuter", "helloDance": "Salut, dansons ensemble", - "market": "Découvrir" + "market": "Découvrir", + "selectRole": "Sélectionner un rôle" } diff --git a/locales/fr-FR/common.json b/locales/fr-FR/common.json index ebe11151..f173eca9 100644 --- a/locales/fr-FR/common.json +++ b/locales/fr-FR/common.json @@ -12,6 +12,7 @@ "confirmDel": "Confirmer la suppression ?", "copy": "Copier", "copySuccess": "Copie réussie", + "danceMarket": "Marché de la danse", "del": "Supprimer", "delAndRegenerate": "Supprimer et régénérer", "downloadAvatar": "Télécharger l'avatar", @@ -22,7 +23,6 @@ "downloadSuccess": "Téléchargement réussi", "edit": "Modifier", "goBottom": "Aller en bas", - "market": "Découvrir", "pause": "Pause", "play": "Lire", "regenerate": "Régénérer", @@ -34,6 +34,7 @@ "resetTitle": "Confirmer la réinitialisation de tous les paramètres système ?", "save": "Enregistrer", "send": "Envoyer", + "sessionCreate": "Créer une session de discussion", "share": "Partager", "subscribe": "S'abonner", "subscribeDance": "S'abonner à la danse", @@ -48,11 +49,13 @@ "cancel": "Annuler", "commonSetting": "Paramètres communs", "confirm": "Confirmer", + "danceList": "Liste de danse", "defaultAssistant": "Assistant par défaut", "delAlert": "Confirmer la suppression du rôle et des messages de session associés ? Cette action est irréversible. Veuillez procéder avec prudence !", "delRole": "Supprimer le rôle", "delSession": "Supprimer la session", "delSessionAlert": "Confirmer la suppression de la conversation ? Cette action est irréversible. Veuillez procéder avec prudence !", + "history": "Historique des discussions", "inputStartChat": "Veuillez saisir du texte pour commencer la conversation", "languageModel": "Modèle de langue", "loading": "Chargement...", @@ -69,7 +72,6 @@ "roleModel": "Modèle Role GPT", "useOwnKey": "Veuillez utiliser votre propre clé OpenAI" }, - "playlist": "Liste de lecture", "search": "Rechercher", "selectInDanceList": "Veuillez sélectionner dans la liste de danses", "selectModel": "Veuillez sélectionner un modèle", diff --git a/locales/fr-FR/features.json b/locales/fr-FR/features.json index 4bfc2523..2a19147a 100644 --- a/locales/fr-FR/features.json +++ b/locales/fr-FR/features.json @@ -16,9 +16,9 @@ "startTitle": "Personnaliser la clé d'API" }, "info": { - "history": "Historique de chat", + "chat": "Discussion", + "dance": "Danse", "motions": "Mouvements", - "playlist": "Liste de lecture", "posture": "Posture" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "Téléchargement du modèle en cours, veuillez patienter...", "floor": "Changer de sol", "grid": "Grille", - "resetCamera": "Réinitialiser la caméra" + "resetCamera": "Réinitialiser la caméra", + "resetToIdle": "Arrêter les mouvements de danse", + "screenShot": "Capture d'écran" } } diff --git a/locales/fr-FR/panel.json b/locales/fr-FR/panel.json index 65fae044..4cbc6b03 100644 --- a/locales/fr-FR/panel.json +++ b/locales/fr-FR/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "Liste des mouvements du personnage", "noAnimations": "Aucune animation disponible", + "postureList": "Liste des postures", "totalCount": "Total : {{total}} éléments" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "Ajouté à la liste de lecture", "cancelAddPlay": "Voulez-vous vraiment annuler l'abonnement à la musique {{musicName}}?", "cancelSubscribed": "Annuler l'abonnement", + "confirmClearPlayList": "", "findDance": "Trouvez votre danse préférée", "musicAndDance": "Musique et danse", "noPlayList": "Aucune liste de lecture n'est disponible pour le moment. Vous pouvez vous abonner aux danses que vous aimez sur le marché.", diff --git a/locales/it-IT/chat.json b/locales/it-IT/chat.json index e5e80520..ad5eac11 100644 --- a/locales/it-IT/chat.json +++ b/locales/it-IT/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Hello, let's chat", "helloDance": "Hi, let's dance together", - "market": "Discover" + "market": "Discover", + "selectRole": "Seleziona il ruolo" } diff --git a/locales/it-IT/common.json b/locales/it-IT/common.json index a87fdafa..b49af102 100644 --- a/locales/it-IT/common.json +++ b/locales/it-IT/common.json @@ -12,6 +12,7 @@ "confirmDel": "Sei sicuro di voler eliminare?", "copy": "Copia", "copySuccess": "Copia riuscita", + "danceMarket": "Mercato delle danze", "del": "Elimina", "delAndRegenerate": "Elimina e rigenera", "downloadAvatar": "Scarica avatar", @@ -22,7 +23,6 @@ "downloadSuccess": "Download completato", "edit": "Modifica", "goBottom": "Vai in fondo", - "market": "Scopri", "pause": "Pausa", "play": "Riproduci", "regenerate": "Rigenera", @@ -34,6 +34,7 @@ "resetTitle": "Confermi di voler ripristinare tutte le impostazioni di sistema?", "save": "Salva", "send": "Invia", + "sessionCreate": "Creare una sessione di chat", "share": "Condividi", "subscribe": "Iscriviti", "subscribeDance": "Iscriviti alla danza", @@ -48,11 +49,13 @@ "cancel": "Annulla", "commonSetting": "Impostazioni comuni", "confirm": "Conferma", + "danceList": "Elenco delle danze", "defaultAssistant": "Assistente predefinito", "delAlert": "Confermi l'eliminazione del ruolo e dei messaggi di sessione correlati? L'operazione non può essere annullata, procedere con cautela!", "delRole": "Elimina ruolo", "delSession": "Elimina sessione", "delSessionAlert": "Confermi l'eliminazione della conversazione? L'operazione non può essere annullata, procedere con cautela!", + "history": "Cronologia delle chat", "inputStartChat": "Inserisci il contenuto per iniziare la chat", "languageModel": "Modello linguistico", "loading": "Caricamento in corso...", @@ -69,7 +72,6 @@ "roleModel": "Modello GPT del ruolo", "useOwnKey": "Utilizza la tua chiave OpenAI" }, - "playlist": "Playlist", "search": "Cerca", "selectInDanceList": "Seleziona dalla lista delle danze", "selectModel": "Seleziona modello", diff --git a/locales/it-IT/features.json b/locales/it-IT/features.json index fda53458..39b7260c 100644 --- a/locales/it-IT/features.json +++ b/locales/it-IT/features.json @@ -15,6 +15,12 @@ "startDesc": "Inserisci la tua chiave API di OpenAI per iniziare la sessione. L'applicazione non memorizzerà la tua chiave API", "startTitle": "Personalizza la chiave API" }, + "info": { + "chat": "Chat", + "dance": "Danza", + "motions": "Movimenti", + "posture": "Postura" + }, "mode": { "chat": "Chat", "video": "Video" @@ -62,12 +68,8 @@ "downloadModel": "Download del modello in corso, attendere...", "floor": "Cambia pavimento", "grid": "Griglia", - "info": { - "history": "Cronologia della chat", - "motions": "Movimenti", - "playlist": "Playlist", - "posture": "Postura" - }, - "resetCamera": "Reimposta fotocamera" + "resetCamera": "Reimposta fotocamera", + "resetToIdle": "Ripristina all'immobilità", + "screenShot": "Screenshot" } } diff --git a/locales/it-IT/panel.json b/locales/it-IT/panel.json index de8cd578..123af01e 100644 --- a/locales/it-IT/panel.json +++ b/locales/it-IT/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "Elenco delle animazioni del personaggio", "noAnimations": "Nessuna animazione disponibile", + "postureList": "Elenco delle posture", "totalCount": "Totale {{total}} elementi" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "Aggiunto alla lista di riproduzione", "cancelAddPlay": "Sei sicuro di voler annullare l'iscrizione alla musica {{musicName}}?", "cancelSubscribed": "Annulla iscrizione", + "confirmClearPlayList": "", "findDance": "Trova la tua danza preferita", "musicAndDance": "Musica e danza", "noPlayList": "Nessuna playlist disponibile, puoi abbonarti ai tipi di danza che ti piacciono dal mercato.", diff --git a/locales/ja-JP/chat.json b/locales/ja-JP/chat.json index 9478c352..2f22ed83 100644 --- a/locales/ja-JP/chat.json +++ b/locales/ja-JP/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "こんにちは、チャットしましょう", "helloDance": "こんにちは、一緒にダンスしましょう", - "market": "マーケット" + "market": "マーケット", + "selectRole": "ロールを選択" } diff --git a/locales/ja-JP/common.json b/locales/ja-JP/common.json index 0ebb1721..cdcefa4a 100644 --- a/locales/ja-JP/common.json +++ b/locales/ja-JP/common.json @@ -12,6 +12,7 @@ "confirmDel": "削除してもよろしいですか?", "copy": "コピー", "copySuccess": "コピー成功", + "danceMarket": "ダンスマーケット", "del": "削除", "delAndRegenerate": "削除して再生成", "downloadAvatar": "アバターをダウンロード", @@ -22,7 +23,6 @@ "downloadSuccess": "ダウンロード成功", "edit": "編集", "goBottom": "一番下に移動", - "market": "発見", "pause": "一時停止", "play": "再生", "regenerate": "再生成", @@ -34,6 +34,7 @@ "resetTitle": "すべてのシステム設定をリセットしますか?", "save": "保存", "send": "送信", + "sessionCreate": "チャット作成", "share": "共有", "subscribe": "購読", "subscribeDance": "ダンスを購読", @@ -48,11 +49,13 @@ "cancel": "キャンセル", "commonSetting": "一般設定", "confirm": "確認", + "danceList": "ダンスリスト", "defaultAssistant": "デフォルトアシスタント", "delAlert": "役割および関連するセッションメッセージを削除しますか?削除後は復元できませんので、慎重に操作してください。", "delRole": "役割を削除", "delSession": "セッションを削除", "delSessionAlert": "対話を削除しますか?削除後は復元できませんので、慎重に操作してください。", + "history": "履歴", "inputStartChat": "チャットを開始するには内容を入力してください", "languageModel": "言語モデル", "loading": "読み込み中...", @@ -69,7 +72,6 @@ "roleModel": "Role GPTモデル", "useOwnKey": "独自のOpenAIキーを使用してください" }, - "playlist": "再生リスト", "search": "検索", "selectInDanceList": "ダンスリストから選択してください", "selectModel": "モデルを選択してください", diff --git a/locales/ja-JP/features.json b/locales/ja-JP/features.json index 42b21e62..b3a6d146 100644 --- a/locales/ja-JP/features.json +++ b/locales/ja-JP/features.json @@ -16,9 +16,9 @@ "startTitle": "APIキーをカスタマイズする" }, "info": { - "history": "チャット履歴", + "chat": "チャット", + "dance": "ダンス", "motions": "モーション", - "playlist": "プレイリスト", "posture": "ポーズ" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "モデルのダウンロード中、しばらくお待ちください...", "floor": "床を切り替える", "grid": "グリッド", - "resetCamera": "カメラをリセットする" + "resetCamera": "カメラをリセットする", + "resetToIdle": "停止舞踏動作", + "screenShot": "スクリーンショット" } } diff --git a/locales/ja-JP/panel.json b/locales/ja-JP/panel.json index 6d0a513f..d4d20c5c 100644 --- a/locales/ja-JP/panel.json +++ b/locales/ja-JP/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "キャラクターのアニメーションリスト", "noAnimations": "アニメーションがありません", + "postureList": "ポーズリスト", "totalCount": "合計 {{total}} 項目" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "再生リストに追加されました", "cancelAddPlay": "音楽{{musicName}}の購読をキャンセルしますか?", "cancelSubscribed": "購読をキャンセルする", + "confirmClearPlayList": "", "findDance": "お気に入りのダンスを見つける", "musicAndDance": "音楽とダンス", "noPlayList": "再生リストがありません。市場で好きなダンスをサブスクリプションできます。", diff --git a/locales/ko-KR/chat.json b/locales/ko-KR/chat.json index 39fcc901..1f10d43e 100644 --- a/locales/ko-KR/chat.json +++ b/locales/ko-KR/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "안녕하세요, 대화를 나눠보세요", "helloDance": "'안녕, 함께 춤을 추자'", - "market": "시장" + "market": "시장", + "selectRole": "역할 선택" } diff --git a/locales/ko-KR/common.json b/locales/ko-KR/common.json index f3517518..cf2adbf6 100644 --- a/locales/ko-KR/common.json +++ b/locales/ko-KR/common.json @@ -12,6 +12,7 @@ "confirmDel": "삭제하시겠습니까?", "copy": "복사", "copySuccess": "복사 성공", + "danceMarket": "댄스 시장", "del": "삭제", "delAndRegenerate": "삭제하고 다시 생성", "downloadAvatar": "아바타 다운로드", @@ -22,7 +23,6 @@ "downloadSuccess": "다운로드 성공", "edit": "편집", "goBottom": "맨 아래로 이동", - "market": "발견", "pause": "일시 정지", "play": "재생", "regenerate": "다시 생성", @@ -34,6 +34,7 @@ "resetTitle": "모든 시스템 설정을 재설정하시겠습니까?", "save": "저장", "send": "보내기", + "sessionCreate": "대화 생성", "share": "공유", "subscribe": "구독", "subscribeDance": "댄스 구독", @@ -48,11 +49,13 @@ "cancel": "취소", "commonSetting": "일반 설정", "confirm": "확인", + "danceList": "댄스 목록", "defaultAssistant": "기본 어시스턴트", "delAlert": "역할과 관련된 모든 대화 메시지를 삭제하시겠습니까? 삭제 후에는 복구할 수 없습니다. 신중하게 작업하세요!", "delRole": "역할 삭제", "delSession": "대화 삭제", "delSessionAlert": "대화를 삭제하시겠습니까? 삭제 후에는 복구할 수 없습니다. 신중하게 작업하세요!", + "history": "대화 기록", "inputStartChat": "채팅을 시작하려면 내용을 입력하세요", "languageModel": "언어 모델", "loading": "로딩 중...", @@ -69,7 +72,6 @@ "roleModel": "Role GPT 모델", "useOwnKey": "자체 OpenAI 키를 사용하세요." }, - "playlist": "재생 목록", "search": "검색", "selectInDanceList": "댄스 목록에서 선택하세요", "selectModel": "모델 선택", diff --git a/locales/ko-KR/features.json b/locales/ko-KR/features.json index 3b302706..24399033 100644 --- a/locales/ko-KR/features.json +++ b/locales/ko-KR/features.json @@ -16,9 +16,9 @@ "startTitle": "사용자 정의 API 키" }, "info": { - "history": "채팅 기록", + "chat": "채팅", + "dance": "댄스", "motions": "동작", - "playlist": "재생 목록", "posture": "자세" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "모델 다운로드 중입니다. 잠시만 기다려주세요...", "floor": "바닥 전환", "grid": "그리드", - "resetCamera": "카메라 재설정" + "resetCamera": "카메라 재설정", + "resetToIdle": "정지", + "screenShot": "스크린샷" } } diff --git a/locales/ko-KR/panel.json b/locales/ko-KR/panel.json index 511ee501..50b4eb2d 100644 --- a/locales/ko-KR/panel.json +++ b/locales/ko-KR/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "캐릭터 애니메이션 목록", "noAnimations": "애니메이션이 없습니다.", + "postureList": "자세 목록", "totalCount": "총 {{total}} 항목" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "재생 목록에 추가되었습니다", "cancelAddPlay": "{{musicName}} 음악 구독을 취소 하시겠습니까?", "cancelSubscribed": "구독 취소", + "confirmClearPlayList": "", "findDance": "좋아하는 춤을 찾아보세요", "musicAndDance": "음악과 춤", "noPlayList": "재생 목록이 없습니다. 시장에서 원하는 댄스를 구독할 수 있습니다.", diff --git a/locales/nl-NL/chat.json b/locales/nl-NL/chat.json index d607c2ea..259c52e9 100644 --- a/locales/nl-NL/chat.json +++ b/locales/nl-NL/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Hallo, laten we chatten", "helloDance": "Hoi, laten we dansen", - "market": "Ontdek" + "market": "Ontdek", + "selectRole": "Kies een rol" } diff --git a/locales/nl-NL/common.json b/locales/nl-NL/common.json index f9fbdd5d..dcd75286 100644 --- a/locales/nl-NL/common.json +++ b/locales/nl-NL/common.json @@ -12,6 +12,7 @@ "confirmDel": "Weet u zeker dat u wilt verwijderen?", "copy": "Kopiëren", "copySuccess": "Succesvol gekopieerd", + "danceMarket": "Dansmarkt", "del": "Verwijderen", "delAndRegenerate": "Verwijderen en opnieuw genereren", "downloadAvatar": "Avatar downloaden", @@ -22,7 +23,6 @@ "downloadSuccess": "Download succesvol", "edit": "Bewerken", "goBottom": "Naar onder gaan", - "market": "Ontdekken", "pause": "Pauze", "play": "Afspelen", "regenerate": "Opnieuw genereren", @@ -34,6 +34,7 @@ "resetTitle": "Weet u zeker dat u alle systeeminstellingen wilt resetten?", "save": "Opslaan", "send": "Verzenden", + "sessionCreate": "Chat creëren", "share": "Delen", "subscribe": "Abonneren", "subscribeDance": "Dans abonneren", @@ -48,11 +49,13 @@ "cancel": "Annuleren", "commonSetting": "Algemene instellingen", "confirm": "Bevestigen", + "danceList": "Danslijst", "defaultAssistant": "Standaard assistent", "delAlert": "Weet u zeker dat u de rol en de bijbehorende gespreksberichten wilt verwijderen? Na verwijdering kan dit niet hersteld worden, wees voorzichtig met het uitvoeren!", "delRole": "Rol verwijderen", "delSession": "Sessie verwijderen", "delSessionAlert": "Weet u zeker dat u het gesprek wilt verwijderen? Na verwijdering kan dit niet hersteld worden, wees voorzichtig met het uitvoeren!", + "history": "Geschiedenis", "inputStartChat": "Voer inhoud in om het chatten te starten", "languageModel": "Taalmodel", "loading": "Bezig met laden...", @@ -69,7 +72,6 @@ "roleModel": "Role GPT model", "useOwnKey": "Gebruik uw eigen OpenAI Key" }, - "playlist": "Afspeellijst", "search": "Zoeken", "selectInDanceList": "Selecteer alstublieft uit de danslijst", "selectModel": "Selecteer een model", diff --git a/locales/nl-NL/features.json b/locales/nl-NL/features.json index e03f81b8..85e3d369 100644 --- a/locales/nl-NL/features.json +++ b/locales/nl-NL/features.json @@ -16,9 +16,9 @@ "startTitle": "Aangepaste API Key" }, "info": { - "history": "chatgeschiedenis", + "chat": "Chat", + "dance": "Dans", "motions": "bewegingen", - "playlist": "afspeellijst", "posture": "houding" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "Model downloaden, even geduld aub...", "floor": "Verander vloer", "grid": "Raster", - "resetCamera": "Camera resetten" + "resetCamera": "Camera resetten", + "resetToIdle": "Stop dansbewegingen", + "screenShot": "Screenshot" } } diff --git a/locales/nl-NL/panel.json b/locales/nl-NL/panel.json index 53c1a660..e875bf6c 100644 --- a/locales/nl-NL/panel.json +++ b/locales/nl-NL/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "Lijst met personagebewegingen", "noAnimations": "Geen animaties beschikbaar", + "postureList": "Houdingenlijst", "totalCount": "Totaal {{total}} items" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "Is toegevoegd aan de afspeellijst", "cancelAddPlay": "Weet u zeker dat u wilt afmelden voor muziek {{musicName}}?", "cancelSubscribed": "Afmelden", + "confirmClearPlayList": "", "findDance": "Vind je favoriete dans", "musicAndDance": "Muziek en Dans", "noPlayList": "Geen afspeellijst beschikbaar, u kunt zich abonneren op dansen die u leuk vindt via de markt.", diff --git a/locales/pl-PL/chat.json b/locales/pl-PL/chat.json index 7385d83e..13e3a784 100644 --- a/locales/pl-PL/chat.json +++ b/locales/pl-PL/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Cześć, porozmawiajmy", "helloDance": "Cześć, zatańczmy razem", - "market": "Odkrywaj" + "market": "Odkrywaj", + "selectRole": "Wybierz rolę" } diff --git a/locales/pl-PL/common.json b/locales/pl-PL/common.json index 294f702f..753fc883 100644 --- a/locales/pl-PL/common.json +++ b/locales/pl-PL/common.json @@ -12,6 +12,7 @@ "confirmDel": "Czy na pewno chcesz usunąć?", "copy": "Kopiuj", "copySuccess": "Pomyślnie skopiowano", + "danceMarket": "Rynek tańca", "del": "Usuń", "delAndRegenerate": "Usuń i wygeneruj ponownie", "downloadAvatar": "Pobierz awatar", @@ -22,7 +23,6 @@ "downloadSuccess": "Pobieranie powiodło się", "edit": "Edytuj", "goBottom": "Powrót do dołu", - "market": "Odkryj", "pause": "Pauza", "play": "Odtwarzaj", "regenerate": "Wygeneruj ponownie", @@ -34,6 +34,7 @@ "resetTitle": "Czy na pewno chcesz zresetować wszystkie ustawienia systemowe?", "save": "Zapisz", "send": "Wyślij", + "sessionCreate": "Utwórz sesję", "share": "Udostępnij", "subscribe": "Subskrybuj", "subscribeDance": "Subskrybuj taniec", @@ -44,14 +45,17 @@ "warp": "Zmień linię" }, "aiAlert": "Pamiętaj: wszystko, co mówi inteligentny agent, jest generowane przez AI", + "animationLibrary": "Biblioteka animacji", "cancel": "Anuluj", "commonSetting": "Ustawienia ogólne", "confirm": "Potwierdź", + "danceList": "Lista tańców", "defaultAssistant": "Domyślny asystent", "delAlert": "Czy na pewno chcesz usunąć postać i powiązane z nią wiadomości? Po usunięciu nie będzie można odzyskać, proszę zachować ostrożność!", "delRole": "Usuń rolę", "delSession": "Usuń sesję", "delSessionAlert": "Czy na pewno chcesz usunąć rozmowę? Po usunięciu nie będzie można odzyskać, proszę zachować ostrożność!", + "history": "Historia", "inputStartChat": "Wprowadź treść, aby rozpocząć rozmowę", "languageModel": "Model językowy", "loading": "Ładowanie...", @@ -68,7 +72,6 @@ "roleModel": "Model Role GPT", "useOwnKey": "Proszę użyć własnego klucza OpenAI" }, - "playlist": "Playlista", "search": "Szukaj", "selectInDanceList": "Proszę wybrać z listy tańców", "selectModel": "Proszę wybrać model", diff --git a/locales/pl-PL/constants.json b/locales/pl-PL/constants.json index 1c3fb38b..faea425a 100644 --- a/locales/pl-PL/constants.json +++ b/locales/pl-PL/constants.json @@ -1,6 +1,7 @@ { "agent": { "gender": { + "all": "wszystkie", "female": "Kobieta", "male": "Mężczyzna" }, @@ -86,6 +87,21 @@ "neutralA": "Nie obawiaj się, moje potężne nogi nie biją głupców", "neutralB": "Pozwól mi dotknąć twoich nóg, czy nie czujesz, że twoje życie jest teraz pełne?" } + }, + "motion": { + "all": "wszystkie", + "dance": "taniec", + "normal": "normalny" + }, + "posture": { + "action": "akcja", + "all": "wszystkie", + "crouch": "kucanie", + "dance": "taniec", + "laying": "leżenie", + "locomotion": "ruch", + "sitting": "siedzenie", + "standing": "stanie" } } } diff --git a/locales/pl-PL/features.json b/locales/pl-PL/features.json index c1c4dfec..80a582cc 100644 --- a/locales/pl-PL/features.json +++ b/locales/pl-PL/features.json @@ -15,6 +15,12 @@ "startDesc": "Wprowadź swój klucz API OpenAI, aby rozpocząć rozmowę. Aplikacja nie będzie rejestrować Twojego klucza API", "startTitle": "Niestandardowy klucz API" }, + "info": { + "chat": "Czat", + "dance": "Taniec", + "motions": "Ruchy", + "posture": "Postawa" + }, "mode": { "chat": "Czat", "video": "Wideo" @@ -56,11 +62,14 @@ "used": "Tokenów użytych" }, "toolBar": { + "axes": "Osie", "cameraControl": "Kontrola kamery", "cameraHelper": "Asystent kamery", "downloadModel": "Pobieranie modelu, proszę czekać...", "floor": "Przełącz podłogę", "grid": "Siatka", - "resetCamera": "Zresetuj kamerę" + "resetCamera": "Zresetuj kamerę", + "resetToIdle": "Zatrzymaj ruch taneczny", + "screenShot": "Zrzut ekranu" } } diff --git a/locales/pl-PL/panel.json b/locales/pl-PL/panel.json index b549802b..560e125c 100644 --- a/locales/pl-PL/panel.json +++ b/locales/pl-PL/panel.json @@ -1,11 +1,19 @@ { + "animation": { + "animationList": "Lista ruchów", + "noAnimations": "Brak biblioteki animacji", + "postureList": "Lista postaw", + "totalCount": "Razem {{total}} pozycji" + }, "dance": { "addPlay": "Dodaj do listy", "addPlaySuccess": "Zostało dodane do listy odtwarzania", "cancelAddPlay": "Czy na pewno chcesz anulować subskrypcję muzyki {{musicName}}?", "cancelSubscribed": "Anuluj subskrypcję", + "confirmClearPlayList": "", "findDance": "Znajdź swój ulubiony taniec", "musicAndDance": "Muzyka i taniec", + "noPlayList": "Brak listy odtwarzania, możesz subskrybować ulubione tańce na rynku.", "play": "Odtwórz" }, "info": { @@ -25,8 +33,12 @@ "greetLabel": "Przywitanie", "modelDescription": "Podgląd modelu, możesz przeciągnąć plik modelu, aby zastąpić", "modelLabel": "Podgląd modelu", + "motionCategoryLabel": "Kategoria ruchu", + "motionDescription": "Wybierz ruch podczas reakcji, który wpłynie na zachowanie postaci.", + "motionLabel": "Ruch", "nameDescription": "Nazwa postaci, nazwa używana podczas rozmowy z postacią", "nameLabel": "Nazwa", + "postureCategoryLabel": "Kategoria postawy", "readmeDescription": "Plik z opisem postaci, używany do prezentacji szczegółowego opisu postaci na stronie odkrywania", "readmeLabel": "Opis postaci", "textDescription": "Niestandardowe tło odpowiedzi", @@ -69,6 +81,7 @@ "addAction": "Dodaj reakcję", "editAction": "Edytuj reakcję", "inputActionEmotion": "Proszę wprowadzić wyraz twarzy postaci podczas reakcji", + "inputActionMotion": "Wprowadź ruch postaci podczas reakcji.", "inputActionText": "Proszę wprowadzić treść odpowiedzi", "inputDIYText": "Wprowadź niestandardową treść", "noTouchActions": "Brak niestandardowych akcji dotyku, możesz dodać je, klikając przycisk '+'", diff --git a/locales/pt-BR/chat.json b/locales/pt-BR/chat.json index e5e80520..0a244cd1 100644 --- a/locales/pt-BR/chat.json +++ b/locales/pt-BR/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Hello, let's chat", "helloDance": "Hi, let's dance together", - "market": "Discover" + "market": "Discover", + "selectRole": "Escolha o papel" } diff --git a/locales/pt-BR/common.json b/locales/pt-BR/common.json index be17ec11..f6b42988 100644 --- a/locales/pt-BR/common.json +++ b/locales/pt-BR/common.json @@ -12,6 +12,7 @@ "confirmDel": "Tem certeza de que deseja excluir?", "copy": "Copiar", "copySuccess": "Cópia bem-sucedida", + "danceMarket": "Mercado de dança", "del": "Excluir", "delAndRegenerate": "Excluir e Regenerar", "downloadAvatar": "Baixar avatar", @@ -22,7 +23,6 @@ "downloadSuccess": "Download bem-sucedido", "edit": "Editar", "goBottom": "Ir para o final", - "market": "Descobrir", "pause": "Pausar", "play": "Reproduzir", "regenerate": "Regenerar", @@ -34,6 +34,7 @@ "resetTitle": "Confirmar redefinir todas as configurações do sistema?", "save": "Salvar", "send": "Enviar", + "sessionCreate": "Criar sessão de bate-papo", "share": "Compartilhar", "subscribe": "Inscrever-se", "subscribeDance": "Inscrever-se na dança", @@ -48,11 +49,13 @@ "cancel": "Cancelar", "commonSetting": "Configuração comum", "confirm": "Confirmar", + "danceList": "Lista de dança", "defaultAssistant": "Assistente padrão", "delAlert": "Tem certeza de que deseja excluir o papel e as mensagens da sessão relacionadas? Esta ação não pode ser desfeita. Por favor, proceda com cuidado!", "delRole": "Excluir papel", "delSession": "Excluir sessão", "delSessionAlert": "Tem certeza de que deseja excluir a conversa? Esta ação não pode ser desfeita. Por favor, proceda com cuidado!", + "history": "Histórico de bate-papo", "inputStartChat": "Digite algo para começar a conversar", "languageModel": "Modelo de idioma", "loading": "Carregando...", @@ -69,7 +72,6 @@ "roleModel": "Modelo GPT de papel", "useOwnKey": "Use sua própria chave OpenAI" }, - "playlist": "Lista de reprodução", "search": "Pesquisar", "selectInDanceList": "Por favor, selecione na lista de danças", "selectModel": "Selecione um modelo", diff --git a/locales/pt-BR/features.json b/locales/pt-BR/features.json index ab61ec2a..583d4007 100644 --- a/locales/pt-BR/features.json +++ b/locales/pt-BR/features.json @@ -16,9 +16,9 @@ "startTitle": "Chave de API personalizada" }, "info": { - "history": "Histórico de bate-papo", + "chat": "Chat", + "dance": "Dança", "motions": "Movimentos", - "playlist": "Lista de reprodução", "posture": "Postura" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "Modelo sendo baixado, por favor, aguarde...", "floor": "Alternar piso", "grid": "Grade", - "resetCamera": "Redefinir câmera" + "resetCamera": "Redefinir câmera", + "resetToIdle": "Parar a dança", + "screenShot": "Capturar tela" } } diff --git a/locales/pt-BR/panel.json b/locales/pt-BR/panel.json index 5fa7caa3..4c94f552 100644 --- a/locales/pt-BR/panel.json +++ b/locales/pt-BR/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "Lista de Movimentos do Personagem", "noAnimations": "Sem animações disponíveis", + "postureList": "Lista de posturas", "totalCount": "Total de {{total}} itens" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "Adicionado à lista de reprodução", "cancelAddPlay": "Tem certeza de que deseja cancelar a inscrição na música {{musicName}}?", "cancelSubscribed": "Cancelar inscrição", + "confirmClearPlayList": "", "findDance": "Encontre sua dança favorita", "musicAndDance": "Música e Dança", "noPlayList": "Sem lista de reprodução disponível, você pode assinar no mercado as danças que gosta", diff --git a/locales/ru-RU/chat.json b/locales/ru-RU/chat.json index 7e5cbe24..fe8165ae 100644 --- a/locales/ru-RU/chat.json +++ b/locales/ru-RU/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Привет, давай поболтаем", "helloDance": "Привет, давай потанцуем вместе", - "market": "рынок" + "market": "рынок", + "selectRole": "Выберите роль" } diff --git a/locales/ru-RU/common.json b/locales/ru-RU/common.json index 5f72ca43..7ac4e0ab 100644 --- a/locales/ru-RU/common.json +++ b/locales/ru-RU/common.json @@ -12,6 +12,7 @@ "confirmDel": "Вы уверены, что хотите удалить?", "copy": "Копировать", "copySuccess": "Успешно скопировано", + "danceMarket": "Танцевальный рынок", "del": "Удалить", "delAndRegenerate": "Удалить и сгенерировать заново", "downloadAvatar": "Загрузить аватар", @@ -22,7 +23,6 @@ "downloadSuccess": "Успешно загружено", "edit": "Редактировать", "goBottom": "Перейти вниз", - "market": "Маркет", "pause": "Пауза", "play": "Воспроизвести", "regenerate": "Сгенерировать заново", @@ -34,6 +34,7 @@ "resetTitle": "Вы уверены, что хотите сбросить все системные настройки?", "save": "Сохранить", "send": "Отправить", + "sessionCreate": "Создать чат", "share": "Поделиться", "subscribe": "Подписаться", "subscribeDance": "Подписаться на танец", @@ -48,11 +49,13 @@ "cancel": "Отмена", "commonSetting": "Общие настройки", "confirm": "Подтвердить", + "danceList": "Список танцев", "defaultAssistant": "По умолчанию", "delAlert": "Вы уверены, что хотите удалить роль и связанные с ней сообщения? После удаления восстановление будет невозможно. Пожалуйста, будьте осторожны!", "delRole": "Удалить роль", "delSession": "Удалить сессию", "delSessionAlert": "Вы уверены, что хотите удалить диалог? После удаления восстановление будет невозможно. Пожалуйста, будьте осторожны!", + "history": "История сообщений", "inputStartChat": "Введите текст для начала чата", "languageModel": "Языковая модель", "loading": "Загрузка...", @@ -69,7 +72,6 @@ "roleModel": "Модель Role GPT", "useOwnKey": "Используйте свой ключ OpenAI" }, - "playlist": "Плейлист", "search": "Поиск", "selectInDanceList": "Выберите из списка танцев", "selectModel": "Выберите модель", diff --git a/locales/ru-RU/features.json b/locales/ru-RU/features.json index f67f3ebe..3162650a 100644 --- a/locales/ru-RU/features.json +++ b/locales/ru-RU/features.json @@ -16,9 +16,9 @@ "startTitle": "Настроить ключ API" }, "info": { - "history": "История чата", + "chat": "Чат", + "dance": "Танец", "motions": "Движения", - "playlist": "Плейлист", "posture": "Поза" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "Загрузка модели, пожалуйста, подождите...", "floor": "Переключить пол", "grid": "Сетка", - "resetCamera": "Сбросить камеру" + "resetCamera": "Сбросить камеру", + "resetToIdle": "Остановить танцевальное движение", + "screenShot": "Скриншот" } } diff --git a/locales/ru-RU/panel.json b/locales/ru-RU/panel.json index a45212d8..f21da836 100644 --- a/locales/ru-RU/panel.json +++ b/locales/ru-RU/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "Список анимаций персонажа", "noAnimations": "Отсутствует библиотека анимаций", + "postureList": "Список поз", "totalCount": "Всего {{total}} позиций" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "добавлено в список воспроизведения", "cancelAddPlay": "Вы уверены, что хотите отменить подписку на музыку {{musicName}}?", "cancelSubscribed": "отменить подписку", + "confirmClearPlayList": "", "findDance": "найдите свой любимый танец", "musicAndDance": "музыка и танец", "noPlayList": "Отсутствует список воспроизведения, вы можете подписаться на рынке на танцы, которые вам нравятся", diff --git a/locales/tr-TR/chat.json b/locales/tr-TR/chat.json index 6b7d58ac..84d0c792 100644 --- a/locales/tr-TR/chat.json +++ b/locales/tr-TR/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "Merhaba, sohbet edelim", "helloDance": "Merhaba, birlikte dans edelim", - "market": "keşfet" + "market": "keşfet", + "selectRole": "Rol Seç" } diff --git a/locales/tr-TR/common.json b/locales/tr-TR/common.json index 7b60d4b4..a5b89173 100644 --- a/locales/tr-TR/common.json +++ b/locales/tr-TR/common.json @@ -12,6 +12,7 @@ "confirmDel": "Silmek istediğinize emin misiniz?", "copy": "Kopyala", "copySuccess": "Kopyalama başarılı", + "danceMarket": "Dans Pazarı", "del": "Sil", "delAndRegenerate": "Sil ve Yeniden Oluştur", "downloadAvatar": "Avatar İndir", @@ -22,7 +23,6 @@ "downloadSuccess": "İndirme başarılı", "edit": "Düzenle", "goBottom": "Alt kısma git", - "market": "Keşfet", "pause": "Duraklat", "play": "Oynat", "regenerate": "Yeniden Oluştur", @@ -34,6 +34,7 @@ "resetTitle": "Tüm sistem ayarlarını sıfırlamak istediğinize emin misiniz?", "save": "Kaydet", "send": "Gönder", + "sessionCreate": "Sohbet Oluştur", "share": "Paylaş", "subscribe": "Abone Ol", "subscribeDance": "Dansı Abone Ol", @@ -48,11 +49,13 @@ "cancel": "İptal", "commonSetting": "Genel Ayarlar", "confirm": "Onayla", + "danceList": "Dans Listesi", "defaultAssistant": "Varsayılan Asistan", "delAlert": "Rolü ve ilgili oturum mesajlarını silmeyi onaylıyor musunuz? Silindikten sonra geri alınamaz, lütfen dikkatli olun!", "delRole": "Rolü Sil", "delSession": "Oturumu Sil", "delSessionAlert": "Sohbeti silmeyi onaylıyor musunuz? Silindikten sonra geri alınamaz, lütfen dikkatli olun!", + "history": "Geçmiş", "inputStartChat": "Sohbete başlamak için içerik girin", "languageModel": "Dil Modeli", "loading": "Yükleniyor...", @@ -69,7 +72,6 @@ "roleModel": "Rol GPT Modeli", "useOwnKey": "Kendi OpenAI Anahtarınızı kullanın" }, - "playlist": "Oynatma Listesi", "search": "Ara", "selectInDanceList": "Dans listesinden seçiniz", "selectModel": "Model seçin", diff --git a/locales/tr-TR/features.json b/locales/tr-TR/features.json index ced88666..0e362049 100644 --- a/locales/tr-TR/features.json +++ b/locales/tr-TR/features.json @@ -16,9 +16,9 @@ "startTitle": "Özel API Anahtarı" }, "info": { - "history": "Geçmiş", + "chat": "Sohbet", + "dance": "Dans", "motions": "Hareketler", - "playlist": "Oynatma Listesi", "posture": "Duruş" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "Model İndiriliyor, Lütfen Bekleyin...", "floor": "Zemin Değiştir", "grid": "Izgara", - "resetCamera": "Kamerayı Sıfırla" + "resetCamera": "Kamerayı Sıfırla", + "resetToIdle": "Dansı Durdur", + "screenShot": "Ekran Görüntüsü Al" } } diff --git a/locales/tr-TR/panel.json b/locales/tr-TR/panel.json index cf30219f..cbeb8a5e 100644 --- a/locales/tr-TR/panel.json +++ b/locales/tr-TR/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "Karakter hareket listesi", "noAnimations": "Hareket kütüphanesi bulunamadı", + "postureList": "Poz Listesi", "totalCount": "Toplam {{total}} öğe" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "Oynatma listesine eklendi", "cancelAddPlay": "{{musicName}} müziğini abonelikten çıkarmak istediğinize emin misiniz?", "cancelSubscribed": "Aboneliği iptal et", + "confirmClearPlayList": "", "findDance": "Favori dansını bul", "musicAndDance": "Müzik ve Dans", "noPlayList": "Oynatma listesi bulunamadı, beğendiğiniz dansları pazar üzerinden abone olabilirsiniz", diff --git a/locales/vi-VN/chat.json b/locales/vi-VN/chat.json index f37db67e..418bfde2 100644 --- a/locales/vi-VN/chat.json +++ b/locales/vi-VN/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "你好,让我们来聊天吧", "helloDance": "嗨,让我们一起跳舞吧", - "market": "发现" + "market": "发现", + "selectRole": "Chọn vai trò" } diff --git a/locales/vi-VN/common.json b/locales/vi-VN/common.json index 3477c866..d3c051f0 100644 --- a/locales/vi-VN/common.json +++ b/locales/vi-VN/common.json @@ -12,6 +12,7 @@ "confirmDel": "Xác nhận xóa?", "copy": "Sao chép", "copySuccess": "Sao chép thành công", + "danceMarket": "Thị trường nhảy", "del": "Xóa", "delAndRegenerate": "Xóa và tạo lại", "downloadAvatar": "Tải xuống hình đại diện", @@ -22,7 +23,6 @@ "downloadSuccess": "Tải xuống thành công", "edit": "Chỉnh sửa", "goBottom": "Quay về dưới cùng", - "market": "Khám phá", "pause": "Tạm dừng", "play": "Phát", "regenerate": "Tạo lại", @@ -34,6 +34,7 @@ "resetTitle": "Xác nhận đặt lại tất cả cài đặt hệ thống?", "save": "Lưu", "send": "Gửi", + "sessionCreate": "Tạo phiên trò chuyện", "share": "Chia sẻ", "subscribe": "Đăng ký", "subscribeDance": "Đăng ký nhảy múa", @@ -44,14 +45,17 @@ "warp": "Xuống dòng" }, "aiAlert": "Vui lòng nhớ: Tất cả những gì trí tuệ nhân tạo nói đều được tạo ra bởi AI", + "animationLibrary": "Thư viện hoạt hình", "cancel": "Hủy", "commonSetting": "Cài đặt chung", "confirm": "Xác nhận", + "danceList": "Danh sách nhảy", "defaultAssistant": "Trợ lý mặc định", "delAlert": "Xác nhận xóa vai trò và tin nhắn liên quan? Hành động này không thể hoàn tác, vui lòng cân nhắc!", "delRole": "Xóa vai trò", "delSession": "Xóa phiên", "delSessionAlert": "Xác nhận xóa cuộc trò chuyện? Hành động này không thể hoàn tác, vui lòng cân nhắc!", + "history": "Lịch sử", "inputStartChat": "Nhập nội dung để bắt đầu trò chuyện", "languageModel": "Mô hình ngôn ngữ", "loading": "Đang tải...", @@ -68,7 +72,6 @@ "roleModel": "Mô hình Role GPT", "useOwnKey": "Vui lòng sử dụng API Key của riêng bạn" }, - "playlist": "Danh sách phát", "search": "Tìm kiếm", "selectInDanceList": "Vui lòng chọn từ danh sách nhảy múa", "selectModel": "Chọn mô hình", diff --git a/locales/vi-VN/constants.json b/locales/vi-VN/constants.json index 3fc44d47..f247cd8c 100644 --- a/locales/vi-VN/constants.json +++ b/locales/vi-VN/constants.json @@ -1,6 +1,7 @@ { "agent": { "gender": { + "all": "Tất cả", "female": "Nữ", "male": "Nam" }, @@ -86,6 +87,21 @@ "neutralA": "Đừng sợ, chân sắt đá của tôi không đá người ngốc", "neutralB": "Khiến bạn chạm vào chân tôi, có phải bạn cảm thấy cuộc sống của bạn trọn vẹn hơn không?" } + }, + "motion": { + "all": "Tất cả", + "dance": "Nhảy múa", + "normal": "Hằng ngày" + }, + "posture": { + "action": "Hành động", + "all": "Tất cả", + "crouch": "Ngồi xổm", + "dance": "Nhảy múa", + "laying": "Nằm", + "locomotion": "Di chuyển", + "sitting": "Ngồi", + "standing": "Đứng" } } } diff --git a/locales/vi-VN/features.json b/locales/vi-VN/features.json index 7438a335..9798e49e 100644 --- a/locales/vi-VN/features.json +++ b/locales/vi-VN/features.json @@ -15,6 +15,12 @@ "startDesc": "Nhập OpenAI API Key của bạn để bắt đầu cuộc trò chuyện. Ứng dụng sẽ không ghi lại API Key của bạn", "startTitle": "Tùy chỉnh API Key" }, + "info": { + "chat": "Trò chuyện", + "dance": "Nhảy múa", + "motions": "Chuyển động", + "posture": "Tư thế" + }, "mode": { "chat": "Trò chuyện", "video": "Video" @@ -56,11 +62,14 @@ "used": "Token đã sử dụng" }, "toolBar": { + "axes": "Trục", "cameraControl": "Điều khiển camera", "cameraHelper": "Trợ lý camera", "downloadModel": "Đang tải xuống mô hình, vui lòng đợi...", "floor": "Chuyển đổi sàn", "grid": "Lưới", - "resetCamera": "Đặt lại camera" + "resetCamera": "Đặt lại camera", + "resetToIdle": "Dừng hoạt động nhảy múa", + "screenShot": "Chụp ảnh" } } diff --git a/locales/vi-VN/panel.json b/locales/vi-VN/panel.json index 870c8ded..f39a42cd 100644 --- a/locales/vi-VN/panel.json +++ b/locales/vi-VN/panel.json @@ -1,11 +1,19 @@ { + "animation": { + "animationList": "Danh sách hành động", + "noAnimations": "Chưa có thư viện hoạt ảnh", + "postureList": "Danh sách tư thế", + "totalCount": "Tổng cộng {{total}} mục" + }, "dance": { "addPlay": "Thêm vào danh sách", "addPlaySuccess": "Đã thêm vào danh sách phát", "cancelAddPlay": "Bạn có chắc muốn hủy đăng ký âm nhạc {{musicName}} không?", "cancelSubscribed": "Hủy đăng ký", + "confirmClearPlayList": "", "findDance": "Tìm kiếm những bước nhảy bạn yêu thích", "musicAndDance": "Âm nhạc và nhảy múa", + "noPlayList": "Chưa có danh sách phát nào, bạn có thể đăng ký các bản nhảy yêu thích của mình thông qua thị trường", "play": "Phát" }, "info": { @@ -25,8 +33,12 @@ "greetLabel": "Chào hỏi", "modelDescription": "Xem trước mô hình, kéo thả tệp mô hình để thay thế", "modelLabel": "Xem trước mô hình", + "motionCategoryLabel": "Danh mục hành động", + "motionDescription": "Chọn hành động phản ứng, sẽ ảnh hưởng đến hành vi hành động của nhân vật", + "motionLabel": "Hành động", "nameDescription": "Tên nhân vật, được gọi khi trò chuyện với nhân vật", "nameLabel": "Tên", + "postureCategoryLabel": "Danh mục tư thế", "readmeDescription": "Tài liệu hướng dẫn về nhân vật, dùng để hiển thị thông tin chi tiết về nhân vật trên trang khám phá", "readmeLabel": "Hướng dẫn nhân vật", "textDescription": "Tùy chỉnh văn bản phản hồi", @@ -69,6 +81,7 @@ "addAction": "Thêm hành động phản ứng", "editAction": "Chỉnh sửa hành động phản ứng", "inputActionEmotion": "Nhập tâm trạng của nhân vật khi phản ứng", + "inputActionMotion": "Vui lòng nhập hành động khi nhân vật phản ứng", "inputActionText": "Nhập văn bản phản ứng", "inputDIYText": "Nhập văn bản tùy chỉnh", "noTouchActions": "Không có hành động tương tác được xác định, bạn có thể thêm bằng cách nhấn vào nút '+'", diff --git a/locales/zh-CN/chat.json b/locales/zh-CN/chat.json index a85eab08..33816ef2 100644 --- a/locales/zh-CN/chat.json +++ b/locales/zh-CN/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "你好,让我们来聊天吧", "helloDance": "嗨,让我们一起跳舞吧", - "market": "发现" + "market": "发现", + "selectRole": "选择角色" } diff --git a/locales/zh-CN/common.json b/locales/zh-CN/common.json index c8dd6d00..bccde1b9 100644 --- a/locales/zh-CN/common.json +++ b/locales/zh-CN/common.json @@ -26,7 +26,8 @@ "unsubscribe": "取消订阅", "unsubscribeSuccess": "已取消订阅", "downloadSubscribe": "下载订阅", - "market": "发现", + "sessionCreate": "创建聊天", + "danceMarket": "舞蹈市场", "clearAll": "清空", "clearNow": "立即清除", "clearContext": "清除上下文", @@ -48,11 +49,13 @@ "cancel": "取消", "commonSetting": "通用设置", "confirm": "确定", + "danceList": "舞蹈列表", "defaultAssistant": "默认助手", "delAlert": "确认删除角色以及相关联的会话消息吗?删除后无法恢复, 请谨慎操作!", "delRole": "删除角色", "delSession": "删除会话", "delSessionAlert": "确认删除对话吗?删除后无法恢复, 请谨慎操作!", + "history": "聊天记录", "inputStartChat": "请输入内容开始聊天", "languageModel": "语言模型", "loading": "加载中...", @@ -69,7 +72,6 @@ "checkConnect": "连通性检查", "check": "检查" }, - "playlist": "播放列表", "search": "搜索", "selectInDanceList": "请从舞蹈列表中选取", "selectModel": "请选择模型", diff --git a/locales/zh-CN/features.json b/locales/zh-CN/features.json index b6ecfced..f7d44351 100644 --- a/locales/zh-CN/features.json +++ b/locales/zh-CN/features.json @@ -16,8 +16,8 @@ "closeTip": "关闭提示" }, "info": { - "history": "聊天记录", - "playlist": "播放列表", + "chat": "聊天", + "dance": "舞蹈", "motions": "动作", "posture": "姿势" }, @@ -66,6 +66,8 @@ "cameraControl": "镜头控制", "floor": "切换地板", "resetCamera": "重置镜头", + "resetToIdle": "停止舞蹈动作", + "screenShot": "拍照", "grid": "网格", "axes": "坐标轴", "downloadModel": "模型下载中,请稍后..." diff --git a/locales/zh-CN/panel.json b/locales/zh-CN/panel.json index 4083e4dc..567d75f1 100644 --- a/locales/zh-CN/panel.json +++ b/locales/zh-CN/panel.json @@ -1,7 +1,8 @@ { "animation": { "noAnimations": "暂无动作库", - "animationList": "角色动作列表", + "animationList": "动作列表", + "postureList": "姿势列表", "totalCount": "共 {{total}} 项" }, "dance": { @@ -9,9 +10,10 @@ "addPlay": "添加到列表", "addPlaySuccess": "已添加到播放列表", "cancelAddPlay": "确定取消订阅音乐{{musicName}}吗?", + "confirmClearPlayList": "", "cancelSubscribed": "取消订阅", "findDance": "找到你最喜欢的舞蹈", - "musicAndDance": "音乐与舞蹈", + "musicAndDance": "舞蹈市场", "noPlayList": "暂无播放列表,您可以通过市场订阅你喜欢的舞蹈" }, "info": { diff --git a/locales/zh-TW/chat.json b/locales/zh-TW/chat.json index ee9013ee..34b1135e 100644 --- a/locales/zh-TW/chat.json +++ b/locales/zh-TW/chat.json @@ -10,5 +10,6 @@ }, "helloChat": "妳好,讓我們來聊天吧", "helloDance": "哈囉,讓我們一起跳舞吧", - "market": "發現" + "market": "發現", + "selectRole": "選擇角色" } diff --git a/locales/zh-TW/common.json b/locales/zh-TW/common.json index 4fcd7987..f3572922 100644 --- a/locales/zh-TW/common.json +++ b/locales/zh-TW/common.json @@ -12,6 +12,7 @@ "confirmDel": "確定刪除嗎?", "copy": "複製", "copySuccess": "複製成功", + "danceMarket": "舞蹈市場", "del": "刪除", "delAndRegenerate": "刪除並重新生成", "downloadAvatar": "下載頭像", @@ -22,7 +23,6 @@ "downloadSuccess": "下載成功", "edit": "編輯", "goBottom": "返回底部", - "market": "發現", "pause": "暫停", "play": "播放", "regenerate": "重新生成", @@ -34,6 +34,7 @@ "resetTitle": "確認重置所有系統設置?", "save": "保存", "send": "發送", + "sessionCreate": "建立對話", "share": "分享", "subscribe": "訂閱", "subscribeDance": "訂閱舞蹈", @@ -48,11 +49,13 @@ "cancel": "取消", "commonSetting": "通用設置", "confirm": "確定", + "danceList": "舞蹈清單", "defaultAssistant": "默認助手", "delAlert": "確認刪除角色以及相關聯的會話消息嗎?刪除後無法恢復,請謹慎操作!", "delRole": "刪除角色", "delSession": "刪除會話", "delSessionAlert": "確認刪除對話嗎?刪除後無法恢復,請謹慎操作!", + "history": "歷史記錄", "inputStartChat": "請輸入內容開始聊天", "languageModel": "語言模型", "loading": "加載中...", @@ -69,7 +72,6 @@ "roleModel": "Role GPT 模型", "useOwnKey": "請使用自己的 OpenAI Key" }, - "playlist": "播放列表", "search": "搜索", "selectInDanceList": "請從舞蹈列表中選取", "selectModel": "請選擇模型", diff --git a/locales/zh-TW/features.json b/locales/zh-TW/features.json index 03c270d6..9d34c8f1 100644 --- a/locales/zh-TW/features.json +++ b/locales/zh-TW/features.json @@ -16,9 +16,9 @@ "startTitle": "自定義 API Key" }, "info": { - "history": "聊天記錄", + "chat": "聊天", + "dance": "舞蹈", "motions": "動作", - "playlist": "播放清單", "posture": "姿勢" }, "mode": { @@ -68,6 +68,8 @@ "downloadModel": "模型下載中,請稍後...", "floor": "切換地板", "grid": "網格", - "resetCamera": "重設鏡頭" + "resetCamera": "重設鏡頭", + "resetToIdle": "停止舞蹈動作", + "screenShot": "截圖" } } diff --git a/locales/zh-TW/panel.json b/locales/zh-TW/panel.json index bd1cb501..0dee466d 100644 --- a/locales/zh-TW/panel.json +++ b/locales/zh-TW/panel.json @@ -2,6 +2,7 @@ "animation": { "animationList": "角色動作列表", "noAnimations": "暫無動作庫", + "postureList": "姿勢清單", "totalCount": "共 {{total}} 項" }, "dance": { @@ -9,6 +10,7 @@ "addPlaySuccess": "已新增至播放清單", "cancelAddPlay": "確定要取消訂閱音樂{{musicName}}嗎?", "cancelSubscribed": "取消訂閱", + "confirmClearPlayList": "", "findDance": "尋找您最喜愛的舞蹈", "musicAndDance": "音樂與舞蹈", "noPlayList": "暫無播放清單,您可以透過市場訂閱您喜歡的舞蹈", diff --git a/src/features/AgentViewer/ToolBar/index.tsx b/src/features/AgentViewer/ToolBar/index.tsx index 000ab881..14994193 100644 --- a/src/features/AgentViewer/ToolBar/index.tsx +++ b/src/features/AgentViewer/ToolBar/index.tsx @@ -4,7 +4,7 @@ import { Aperture, Axis3D, Grid3x3, Orbit, Power, SwitchCamera } from 'lucide-re import React from 'react'; import { useTranslation } from 'react-i18next'; -import { Viewer } from '@/features/vrmViewer/viewer'; +import { Viewer } from '@/libs/vrmViewer/viewer'; interface ToolBarProps { className?: string; diff --git a/src/features/AgentViewer/index.tsx b/src/features/AgentViewer/index.tsx index a1a493df..f9f3661e 100644 --- a/src/features/AgentViewer/index.tsx +++ b/src/features/AgentViewer/index.tsx @@ -7,8 +7,6 @@ import PageLoading from '@/components/PageLoading'; import { useLoadModel } from '@/hooks/useLoadModel'; import { useGlobalStore } from '@/store/global'; import { Agent } from '@/types/agent'; -import { getModelPathByAgentId } from '@/utils/file'; -import storage from '@/utils/storage'; import ToolBar from './ToolBar'; import { useStyles } from './style'; @@ -28,24 +26,14 @@ function AgentViewer(props: Props) { const viewer = useGlobalStore((s) => s.viewer); const { t } = useTranslation('features'); - const { downloading, percent, fetchModelBlob } = useLoadModel(); + const { downloading, percent, fetchModelUrl } = useLoadModel(); const canvasRef = useCallback( (canvas: HTMLCanvasElement) => { if (canvas) { viewer.setup(canvas); - const modelPath = getModelPathByAgentId(agent.agentId); - storage.getItem(modelPath).then((blob) => { - if (!blob) { - viewer.unloadVRM(); - fetchModelBlob(agent.agentId, agent.meta.model!).then((res) => { - if (res) { - const modelUrl = URL.createObjectURL(res); - viewer.loadVrm(modelUrl); - } - }); - } else { - const modelUrl = URL.createObjectURL(blob as Blob); + fetchModelUrl(agent.agentId, agent.meta.model!).then((modelUrl) => { + if (modelUrl) { viewer.loadVrm(modelUrl); } }); @@ -85,10 +73,9 @@ function AgentViewer(props: Props) { break; } case 'vmd': { - file.arrayBuffer().then((data) => { - viewer.model?.dance(data); - }); - + const blob = new Blob([file], { type: 'application/octet-stream' }); + const url = window.URL.createObjectURL(blob); + viewer.model?.loadVMD(url); break; } // No default diff --git a/src/features/DanceList/Item/index.tsx b/src/features/DanceList/Item/index.tsx index e703e533..579c9651 100644 --- a/src/features/DanceList/Item/index.tsx +++ b/src/features/DanceList/Item/index.tsx @@ -1,7 +1,9 @@ -import { Avatar } from '@lobehub/ui'; +import { Avatar, Icon } from '@lobehub/ui'; import { useHover } from 'ahooks'; import { Progress, Typography } from 'antd'; +import { Pause, Play } from 'lucide-react'; import React, { memo, useRef, useState } from 'react'; +import { useTranslation } from 'react-i18next'; import ListItem from '@/components/ListItem'; import Actions from '@/features/DanceList/Item/Actions'; @@ -24,28 +26,40 @@ const DanceItem = (props: DanceItemProps) => { const [open, setOpen] = useState(false); const { styles } = useStyles(); - const [currentPlayId, setCurrentPlayId] = useDanceStore((s) => [ + const [currentPlayId, currentIdentifier, activateDance, setCurrentPlayId] = useDanceStore((s) => [ s.currentPlayId, + s.currentIdentifier, + s.activateDance, s.setCurrentPlayId, ]); + const [isPlaying, setIsPlaying] = useGlobalStore((s) => [s.isPlaying, s.setIsPlaying]); + const isCurrentPlay = currentPlayId ? currentPlayId === danceItem.danceId : false; + const isSelected = currentIdentifier === danceItem.danceId; const hoverRef = useRef(null); const isHovered = useHover(hoverRef); + const { t } = useTranslation('common'); - const { downloading: audioDownloading, percent: audioPercent, fetchAudioBuffer } = useLoadAudio(); - const { downloading: danceDownloading, percent: dancePercent, fetchDanceBuffer } = useLoadDance(); + const { downloading: audioDownloading, percent: audioPercent, fetchAudioUrl } = useLoadAudio(); + const { downloading: danceDownloading, percent: dancePercent, fetchDanceUrl } = useLoadDance(); const viewer = useGlobalStore((s) => s.viewer); const handlePlayPause = () => { - const audioPromise = fetchAudioBuffer(danceItem.danceId, danceItem.audio); - const dancePromise = fetchDanceBuffer(danceItem.danceId, danceItem.src); - Promise.all([dancePromise, audioPromise]).then((res) => { - if (!res) return; - const [danceBuffer, audioBuffer] = res; - viewer.model?.dance(danceBuffer, audioBuffer); - }); - setCurrentPlayId(danceItem.danceId); + viewer.model?.disposeAll(); + if (isPlaying && isCurrentPlay) { + setIsPlaying(false); + } else { + setCurrentPlayId(danceItem.danceId); + setIsPlaying(true); + const audioPromise = fetchAudioUrl(danceItem.danceId, danceItem.audio); + const dancePromise = fetchDanceUrl(danceItem.danceId, danceItem.src); + Promise.all([dancePromise, audioPromise]).then((res) => { + if (!res) return; + const [danceUrl, audioUrl] = res; + if (danceUrl && audioUrl) viewer.model?.dance(danceUrl, audioUrl); + }); + } }; return ( @@ -64,11 +78,23 @@ const DanceItem = (props: DanceItemProps) => { ) : null, , ]} - onClick={handlePlayPause} + onClick={() => { + activateDance(danceItem.danceId); + }} + onDoubleClick={handlePlayPause} className={styles.listItem} avatar={
+ {isHovered || isCurrentPlay ? ( +
+ +
+ ) : null}
} title={danceItem?.name} @@ -77,7 +103,7 @@ const DanceItem = (props: DanceItemProps) => { {danceItem?.author} } - active={isCurrentPlay || isHovered} + active={isSelected || isHovered} /> ); }; diff --git a/src/features/MotionList/ActionList/ListItem.tsx b/src/features/MotionList/ActionList/ListItem.tsx index 07b3dd3f..f402376b 100644 --- a/src/features/MotionList/ActionList/ListItem.tsx +++ b/src/features/MotionList/ActionList/ListItem.tsx @@ -72,8 +72,8 @@ const TouchActionListItem = memo(({ item }) => { showAction={true} onClick={async () => { if (item.url) { - const url = await fetchMotionUrl(item.id, item.url); - viewer.model?.loadFBX(url); + const motionUrl = await fetchMotionUrl(item.id, item.url); + if (motionUrl) viewer.model?.loadFBX(motionUrl); } }} title={item.name} diff --git a/src/features/PostureList/ActionList/ListItem.tsx b/src/features/PostureList/ActionList/ListItem.tsx index 07b3dd3f..f402376b 100644 --- a/src/features/PostureList/ActionList/ListItem.tsx +++ b/src/features/PostureList/ActionList/ListItem.tsx @@ -72,8 +72,8 @@ const TouchActionListItem = memo(({ item }) => { showAction={true} onClick={async () => { if (item.url) { - const url = await fetchMotionUrl(item.id, item.url); - viewer.model?.loadFBX(url); + const motionUrl = await fetchMotionUrl(item.id, item.url); + if (motionUrl) viewer.model?.loadFBX(motionUrl); } }} title={item.name} diff --git a/src/features/audioPlayer/audioPlayer.ts b/src/features/audioPlayer/audioPlayer.ts index 7311c0d7..28e99624 100644 --- a/src/features/audioPlayer/audioPlayer.ts +++ b/src/features/audioPlayer/audioPlayer.ts @@ -7,7 +7,11 @@ export class AudioPlayer { this.bufferSource = undefined; } - public async playFromArrayBuffer(buffer: ArrayBuffer, onEnded?: () => void) { + public async playFromArrayBuffer( + buffer: ArrayBuffer, + onEnded?: () => void, + onProgress?: () => void, + ) { const audioBuffer = await this.audio.decodeAudioData(buffer); this.bufferSource = this.audio.createBufferSource(); @@ -18,10 +22,16 @@ export class AudioPlayer { if (onEnded) { this.bufferSource.addEventListener('ended', onEnded); } + if (onProgress) { + this.bufferSource.addEventListener('time', onProgress); + } } public stopPlay() { - if (this.bufferSource) this.bufferSource.stop(); + if (this.bufferSource) { + this.bufferSource.stop(); + this.bufferSource = undefined; + } } public async playFromURL(url: string, onEnded?: () => void) { diff --git a/src/features/messages/speakCharacter.ts b/src/features/messages/speakCharacter.ts index 62bd9cc4..829fc315 100644 --- a/src/features/messages/speakCharacter.ts +++ b/src/features/messages/speakCharacter.ts @@ -1,9 +1,8 @@ +import { Viewer } from '@/libs/vrmViewer/viewer'; import { speechApi } from '@/services/tts'; import { Screenplay } from '@/types/touch'; import { wait } from '@/utils/wait'; -import { Viewer } from '../vrmViewer/viewer'; - const createSpeakCharacter = () => { let lastTime = 0; let prevFetchPromise: Promise = Promise.resolve(); diff --git a/src/hooks/useDownloadDance.tsx b/src/hooks/useDownloadDance.tsx index c4866136..f87d1be4 100644 --- a/src/hooks/useDownloadDance.tsx +++ b/src/hooks/useDownloadDance.tsx @@ -33,25 +33,25 @@ export const useDownloadDance = () => { onProgress: (loaded, total) => { setAudioProgress((loaded / total) * 100); }, - }).then((res) => res.arrayBuffer()); + }); const dancePromise = fetchWithProgress(dance.src, { onProgress: (loaded, total) => { setDanceProgress(Math.ceil((loaded / total) * 100)); }, - }).then((res) => res.arrayBuffer()); + }); try { - const [audioArrayBuffer, coverBase64, danceArrayBuffer] = await Promise.all([ + const [audioBlob, coverBase64, danceBlob] = await Promise.all([ audioPromise, coverPromise, dancePromise, ]); const danceKey = getDancePathByDanceId(dance.danceId); - await setItem(danceKey, danceArrayBuffer); + await setItem(danceKey, danceBlob); const audioKey = getAudioPathByDanceId(dance.danceId); - await setItem(audioKey, audioArrayBuffer); + await setItem(audioKey, audioBlob); addDanceItem({ ...dance, cover: coverBase64 }); message.success(dance.name + t('actions.downloadSuccess')); diff --git a/src/hooks/useLoadAudio.tsx b/src/hooks/useLoadAudio.tsx index 61f3996e..266c7446 100644 --- a/src/hooks/useLoadAudio.tsx +++ b/src/hooks/useLoadAudio.tsx @@ -9,34 +9,38 @@ export const useLoadAudio = () => { const [downloading, setDownloading] = useState(false); const [percent, setPercent] = useState(0); - const fetchAudioBuffer = async (danceId: string, audioUrl: string) => { + const fetchAudioUrl = async (danceId: string, audioUrl: string) => { const localAudioPath = getAudioPathByDanceId(danceId); - let audioBuffer = (await storage.getItem(localAudioPath)) as ArrayBuffer; + let audioBlob = await storage.getItem(localAudioPath); // 存量转换 - if (audioBuffer && !isArrayBuffer(audioBuffer)) { - audioBuffer = await (audioBuffer as Blob).arrayBuffer(); + if (audioBlob && isArrayBuffer(audioBlob)) { + // 如果存的是 ArrayBuffer,设置为空重新下载; + audioBlob = null; } + try { - if (!audioBuffer) { + if (!audioBlob) { setDownloading(true); setPercent(0); - audioBuffer = await fetchWithProgress(audioUrl, { + audioBlob = await fetchWithProgress(audioUrl, { onProgress: (loaded, total) => { setPercent((loaded / total) * 100); }, - }).then((res) => res.arrayBuffer()); - await storage.setItem(localAudioPath, audioBuffer); + }); + await storage.setItem(localAudioPath, audioBlob); } } finally { setDownloading(false); } - return audioBuffer; + if (!audioBlob) return null; + + return URL.createObjectURL(audioBlob); }; return { downloading, percent, - fetchAudioBuffer, + fetchAudioUrl, }; }; diff --git a/src/hooks/useLoadDance.tsx b/src/hooks/useLoadDance.tsx index 6771e1fc..53e8d159 100644 --- a/src/hooks/useLoadDance.tsx +++ b/src/hooks/useLoadDance.tsx @@ -1,3 +1,4 @@ +import { isArrayBuffer } from 'lodash-es'; import { useState } from 'react'; import { fetchWithProgress } from '@/utils/fetch'; @@ -8,31 +9,40 @@ export const useLoadDance = () => { const [downloading, setDownloading] = useState(false); const [percent, setPercent] = useState(0); - const fetchDanceBuffer = async (danceId: string, src: string) => { + const fetchDanceUrl = async (danceId: string, src: string) => { const localDancePath = getDancePathByDanceId(danceId); - let danceBuffer = (await storage.getItem(localDancePath)) as ArrayBuffer; + let danceBlob = await storage.getItem(localDancePath); + + // 存量转换 + if (danceBlob && isArrayBuffer(danceBlob)) { + // 如果存的是 ArrayBuffer,设置为空重新下载; + danceBlob = null; + } try { - if (!danceBuffer) { + if (!danceBlob) { setDownloading(true); setPercent(0); - danceBuffer = await fetchWithProgress(src, { + danceBlob = await fetchWithProgress(src, { onProgress: (loaded, total) => { setPercent((loaded / total) * 100); }, - }).then((res) => res.arrayBuffer()); - await storage.setItem(localDancePath, danceBuffer); + }); + await storage.setItem(localDancePath, danceBlob); } } finally { setDownloading(false); } - return danceBuffer; + + if (!danceBlob) return null; + + return URL.createObjectURL(danceBlob); }; return { downloading, percent, - fetchDanceBuffer, + fetchDanceUrl, }; }; diff --git a/src/hooks/useLoadModel.tsx b/src/hooks/useLoadModel.tsx index 445d025d..1d1cd191 100644 --- a/src/hooks/useLoadModel.tsx +++ b/src/hooks/useLoadModel.tsx @@ -8,30 +8,34 @@ export const useLoadModel = () => { const [downloading, setDownloading] = useState(false); const [percent, setPercent] = useState(0); - const fetchModelBlob = async (agentId: string, modelUrl: string) => { - setDownloading(true); - setPercent(0); - try { - const blob = await fetchWithProgress(modelUrl, { - onProgress: (loaded, total) => { - setPercent(Math.ceil((loaded / total) * 100)); - }, - }); - const modelPath = getModelPathByAgentId(agentId); - await storage.setItem(modelPath, blob); + const fetchModelUrl = async (agentId: string, remoteModelUrl: string) => { + const localModelPath = getModelPathByAgentId(agentId); + let modelBlob = await storage.getItem(localModelPath); - return blob; - } catch (e) { - console.error(e); - return null; + try { + if (!modelBlob) { + setDownloading(true); + setPercent(0); + modelBlob = await fetchWithProgress(remoteModelUrl, { + onProgress: (loaded, total) => { + setPercent(Math.ceil((loaded / total) * 100)); + }, + }); + const modelPath = getModelPathByAgentId(agentId); + await storage.setItem(modelPath, modelBlob); + } } finally { setDownloading(false); } + + if (!modelBlob) return null; + + return URL.createObjectURL(modelBlob); }; return { downloading, percent, - fetchModelBlob, + fetchModelUrl, }; }; diff --git a/src/hooks/useLoadMotion.tsx b/src/hooks/useLoadMotion.tsx index bc7414b5..e7eafea7 100644 --- a/src/hooks/useLoadMotion.tsx +++ b/src/hooks/useLoadMotion.tsx @@ -10,7 +10,8 @@ export const useLoadMotion = () => { const fetchMotionUrl = async (motionId: string, motionUrl: string) => { const localMotionPath = getMotionPathByMotionId(motionId); - let motionBlob = (await storage.getItem(localMotionPath)) as Blob; + let motionBlob = await storage.getItem(localMotionPath); + try { if (!motionBlob) { setDownloading(true); @@ -26,6 +27,9 @@ export const useLoadMotion = () => { } finally { setDownloading(false); } + + if (!motionBlob) return null; + return URL.createObjectURL(motionBlob); }; diff --git a/src/libs/VRMAnimation/loadMixamoAnimation.ts b/src/libs/FBXAnimation/loadMixamoAnimation.ts similarity index 100% rename from src/libs/VRMAnimation/loadMixamoAnimation.ts rename to src/libs/FBXAnimation/loadMixamoAnimation.ts diff --git a/src/libs/VRMAnimation/mixamoVRMRigMap.ts b/src/libs/FBXAnimation/mixamoVRMRigMap.ts similarity index 100% rename from src/libs/VRMAnimation/mixamoVRMRigMap.ts rename to src/libs/FBXAnimation/mixamoVRMRigMap.ts diff --git a/src/libs/VMDAnimation/loadVMDAnimation.ts b/src/libs/VMDAnimation/loadVMDAnimation.ts index 0fc0d1d9..e72f7cb9 100644 --- a/src/libs/VMDAnimation/loadVMDAnimation.ts +++ b/src/libs/VMDAnimation/loadVMDAnimation.ts @@ -1,8 +1,14 @@ -// export async function loadVMDAnimation(url: string): Promise { -// const gltf = await loader.loadAsync(url); +import { VRM } from '@pixiv/three-vrm'; -// const vrmAnimations: VRMAnimation[] = gltf.userData.vrmAnimations; -// const vrmAnimation: VRMAnimation | undefined = vrmAnimations[0]; +import { convert } from '@/libs/VMDAnimation/vmd2vrmanim'; +import { bindToVRM, toOffset } from '@/libs/VMDAnimation/vmd2vrmanim.binding'; -// return vrmAnimation ?? null; -// } +export async function loadVMDAnimation(url: string, vrm: VRM) { + const res = await fetch(url); + const buffer = await res.arrayBuffer(); + + const animation = convert(buffer, toOffset(vrm)); + const clip = bindToVRM(animation, vrm); + + return clip ?? null; +} diff --git a/src/libs/VMDAnimation/vrm-ik-handler.ts b/src/libs/VMDAnimation/vrm-ik-handler.ts index 6d089c35..bab2f824 100644 --- a/src/libs/VMDAnimation/vrm-ik-handler.ts +++ b/src/libs/VMDAnimation/vrm-ik-handler.ts @@ -100,6 +100,7 @@ export default class VRMIKHandler { private targets = new Map(); private iks = new Map(); + // private vector = new Vector3(); private bones: Bone[]; private root: Object3D; @@ -151,7 +152,7 @@ export default class VRMIKHandler { effector: leftToeId, target: leftToeId, iteration: 3, - maxAngle: 1, + maxAngle: 4, links: [ { enabled: false, @@ -164,7 +165,7 @@ export default class VRMIKHandler { effector: rightToeId, target: rightToeId, iteration: 3, - maxAngle: 1, + maxAngle: 4, links: [ { enabled: false, @@ -223,7 +224,17 @@ export default class VRMIKHandler { if (ik.maxAngle != null && angle > ik.maxAngle) angle = ik.maxAngle; axis.crossVectors(effectorVec, targetVec).normalize(); link.quaternion.multiply(quaternion.setFromAxisAngle(axis, angle)); + clampVector3ByRadian(link.rotation, rotationMin, rotationMax); + + // if (rotationMin) { + // link.rotation.setFromVector3(this.vector.setFromEuler(link.rotation).max(rotationMin)); + // } + // + // if (rotationMax) { + // link.rotation.setFromVector3(this.vector.setFromEuler(link.rotation).min(rotationMax)); + // } + link.updateMatrixWorld(true); rotated = true; } diff --git a/src/features/emoteController/autoBlink.ts b/src/libs/emoteController/autoBlink.ts similarity index 100% rename from src/features/emoteController/autoBlink.ts rename to src/libs/emoteController/autoBlink.ts diff --git a/src/features/emoteController/autoLookAt.ts b/src/libs/emoteController/autoLookAt.ts similarity index 100% rename from src/features/emoteController/autoLookAt.ts rename to src/libs/emoteController/autoLookAt.ts diff --git a/src/features/emoteController/emoteConstants.ts b/src/libs/emoteController/emoteConstants.ts similarity index 100% rename from src/features/emoteController/emoteConstants.ts rename to src/libs/emoteController/emoteConstants.ts diff --git a/src/features/emoteController/emoteController.ts b/src/libs/emoteController/emoteController.ts similarity index 100% rename from src/features/emoteController/emoteController.ts rename to src/libs/emoteController/emoteController.ts diff --git a/src/features/emoteController/expressionController.ts b/src/libs/emoteController/expressionController.ts similarity index 100% rename from src/features/emoteController/expressionController.ts rename to src/libs/emoteController/expressionController.ts diff --git a/src/features/lipSync/lipSync.ts b/src/libs/lipSync/lipSync.ts similarity index 93% rename from src/features/lipSync/lipSync.ts rename to src/libs/lipSync/lipSync.ts index 1933bbe2..678aefbf 100644 --- a/src/features/lipSync/lipSync.ts +++ b/src/libs/lipSync/lipSync.ts @@ -48,7 +48,10 @@ export class LipSync { } public stopPlay() { - if (this.bufferSource) this.bufferSource.stop(); + if (this.bufferSource) { + this.bufferSource.stop(); + this.bufferSource = undefined; + } } public async playFromURL(url: string, onEnded?: () => void) { diff --git a/src/features/lipSync/lipSyncAnalyzeResult.ts b/src/libs/lipSync/lipSyncAnalyzeResult.ts similarity index 100% rename from src/features/lipSync/lipSyncAnalyzeResult.ts rename to src/libs/lipSync/lipSyncAnalyzeResult.ts diff --git a/src/features/vrmViewer/model.ts b/src/libs/vrmViewer/model.ts similarity index 78% rename from src/features/vrmViewer/model.ts rename to src/libs/vrmViewer/model.ts index 70417ec0..6a77137d 100644 --- a/src/features/vrmViewer/model.ts +++ b/src/libs/vrmViewer/model.ts @@ -2,20 +2,21 @@ import { VRM, VRMLoaderPlugin, VRMUtils } from '@pixiv/three-vrm'; import * as THREE from 'three'; import { AnimationAction, AnimationClip } from 'three'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'; +import { LoopOnce } from 'three/src/constants'; import { AudioPlayer } from '@/features/audioPlayer/audioPlayer'; +import { loadMixamoAnimation } from '@/libs/FBXAnimation/loadMixamoAnimation'; +import { loadVMDAnimation } from '@/libs/VMDAnimation/loadVMDAnimation'; import { convert } from '@/libs/VMDAnimation/vmd2vrmanim'; import { bindToVRM, toOffset } from '@/libs/VMDAnimation/vmd2vrmanim.binding'; import IKHandler from '@/libs/VMDAnimation/vrm-ik-handler'; import { VRMAnimation } from '@/libs/VRMAnimation/VRMAnimation'; -import { loadMixamoAnimation } from '@/libs/VRMAnimation/loadMixamoAnimation'; import { loadVRMAnimation } from '@/libs/VRMAnimation/loadVRMAnimation'; import { VRMLookAtSmootherLoaderPlugin } from '@/libs/VRMLookAtSmootherLoaderPlugin/VRMLookAtSmootherLoaderPlugin'; +import { EmoteController } from '@/libs/emoteController/emoteController'; +import { LipSync } from '@/libs/lipSync/lipSync'; import { Screenplay } from '@/types/touch'; -import { EmoteController } from '../emoteController/emoteController'; -import { LipSync } from '../lipSync/lipSync'; - /** * 3Dキャラクターを管理するクラス */ @@ -30,7 +31,7 @@ export class Model { private _audioPlayer?: AudioPlayer; private _action: AnimationAction | undefined; private _clip: AnimationClip | undefined; - private _audio: ArrayBuffer | undefined; + private _audio: string | undefined; constructor(lookAtTargetParent: THREE.Object3D) { this._lookAtTargetParent = lookAtTargetParent; @@ -78,14 +79,17 @@ export class Model { } public disposeAll() { - const { vrm, mixer } = this; - - if (!vrm || !mixer) { - console.error('You have to load VRM first'); - return; + const { mixer } = this; + + if (mixer) { + mixer.stopAllAction(); + if (this._clip) { + mixer.uncacheAction(this._clip); + mixer.uncacheClip(this._clip); + this._clip = undefined; + } } - mixer.stopAllAction(); this.ikHandler?.disableAll(); if (this._action) { this._action.stop(); @@ -96,12 +100,6 @@ export class Model { this._audioPlayer?.stopPlay(); this._audio = undefined; } - - if (this._clip) { - mixer.uncacheAction(this._clip); - mixer.uncacheClip(this._clip); - this._clip = undefined; - } } /** @@ -124,7 +122,7 @@ export class Model { public async loadIdleAnimation() { const vrma = await loadVRMAnimation('/idle_loop.vrma'); - if (vrma) this.loadAnimation(vrma); + if (vrma) await this.loadAnimation(vrma); } public async loadFBX(animationUrl: string) { @@ -142,22 +140,34 @@ export class Model { } } + public async loadVMD(animationUrl: string) { + const { vrm, mixer } = this; + + if (vrm && mixer) { + this.disposeAll(); + const clip = await loadVMDAnimation(animationUrl, vrm); + const action = mixer.clipAction(clip); + action.play(); + this._action = action; + this._clip = clip; + } + } + /** - * 播放舞蹈 - * @param audio ArrayBuffer - * @param dance ArrayBuffer + * 播放舞蹈,以音乐文件的播放作为结束标志。 */ - public async dance(dance: ArrayBuffer, audio?: ArrayBuffer) { + public async dance(danceUrl: string, audioUrl: string, onEnd?: () => void) { const { vrm, mixer } = this; if (vrm && mixer) { this.disposeAll(); - const animation = convert(dance, toOffset(vrm)); - const clip = bindToVRM(animation, vrm); + const clip = await loadVMDAnimation(danceUrl, vrm); const action = mixer.clipAction(clip); - action.play(); // play animation - if (audio) { - this._audioPlayer?.playFromArrayBuffer(audio); - this._audio = audio; + action.setLoop(LoopOnce, 1).play(); // play animation + if (audioUrl) { + this._audioPlayer?.playFromURL(audioUrl, () => { + onEnd?.(); + }); + this._audio = audioUrl; } this._action = action; @@ -166,12 +176,9 @@ export class Model { } public async resetToIdle() { - const { vrm, mixer } = this; - if (vrm && mixer) { - this.disposeAll(); + this.disposeAll(); - await this.loadIdleAnimation(); - } + await this.loadIdleAnimation(); } /** * 语音播放,配合人物表情动作 diff --git a/src/features/vrmViewer/viewer.ts b/src/libs/vrmViewer/viewer.ts similarity index 97% rename from src/features/vrmViewer/viewer.ts rename to src/libs/vrmViewer/viewer.ts index d8bc219b..312d2b88 100644 --- a/src/features/vrmViewer/viewer.ts +++ b/src/libs/vrmViewer/viewer.ts @@ -27,7 +27,7 @@ export class Viewer { this._scene = scene; // 方向光 - const directionalLight = new THREE.DirectionalLight(0xFF_FF_FF, Math.PI); + const directionalLight = new THREE.DirectionalLight(0xff_ff_ff, Math.PI); directionalLight.position.set(1, 1, 1).normalize(); scene.add(directionalLight); @@ -142,7 +142,7 @@ export class Viewer { this._scene.remove(this._gridHelper); this._gridHelper = undefined; } else { - this._gridHelper = new GridHelper(50, 100, 0xAA_AA_AA, 0xAA_AA_AA); + this._gridHelper = new GridHelper(50, 100, 0xaa_aa_aa, 0xaa_aa_aa); this._scene.add(this._gridHelper); } } diff --git a/src/store/global/index.ts b/src/store/global/index.ts index 1942d6ea..e0b568f7 100644 --- a/src/store/global/index.ts +++ b/src/store/global/index.ts @@ -5,7 +5,7 @@ import { shallow } from 'zustand/shallow'; import { createWithEqualityFn } from 'zustand/traditional'; import { INITIAL_COORDINATES } from '@/constants/token'; -import { Viewer } from '@/features/vrmViewer/viewer'; +import { Viewer } from '@/libs/vrmViewer/viewer'; import { Panel, PanelConfig, PanelKey } from '@/types/config'; export * from './selectors/panel'; @@ -23,6 +23,7 @@ export interface GlobalStore { * @param key */ focusPanel: (key: PanelKey) => void; + isPlaying: boolean; /** * Open panel * @param key @@ -31,6 +32,7 @@ export interface GlobalStore { panel: PanelConfig; setChatDialog: (show: boolean) => void; setChatSidebar: (show: boolean) => void; + setIsPlaying: (isPlaying: boolean) => void; /** * Set panel config * @param panel @@ -43,7 +45,6 @@ export interface GlobalStore { showChatDialog: boolean; showChatSidebar: boolean; showRoleList: boolean; - showSessionList: boolean; /** * 主题模式 @@ -62,6 +63,7 @@ const initialState = { * 主题模式 */ themeMode: 'auto' as ThemeMode, + isPlaying: false, showChatSidebar: false, showSessionList: true, showChatDialog: true, @@ -90,7 +92,9 @@ const initialState = { export const useGlobalStore = createWithEqualityFn()( (set, get) => ({ ...initialState, - + setIsPlaying: (isPlaying: boolean) => { + set({ isPlaying: isPlaying }); + }, closePanel: (key: PanelKey) => { const { setPanel, focusList } = get(); setPanel(key, { open: false });