From 24b6261f468d2716d9c0114c10e678b149d12a8a Mon Sep 17 00:00:00 2001 From: ouoertheo Date: Tue, 22 Aug 2023 08:30:17 -0500 Subject: [PATCH] add ready flag, add custom voice feature --- public/scripts/extensions/tts/novel.js | 74 +++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 6 deletions(-) diff --git a/public/scripts/extensions/tts/novel.js b/public/scripts/extensions/tts/novel.js index f3393c96a..05c6effa7 100644 --- a/public/scripts/extensions/tts/novel.js +++ b/public/scripts/extensions/tts/novel.js @@ -1,4 +1,4 @@ -import { getRequestHeaders } from "../../../script.js" +import { getRequestHeaders, callPopup } from "../../../script.js" import { getPreviewString } from "./index.js" export { NovelTtsProvider } @@ -9,22 +9,63 @@ class NovelTtsProvider { //########// settings + ready = false voices = [] separator = ' . ' audioElement = document.createElement('audio') defaultSettings = { - voiceMap: {} + voiceMap: {}, + customVoices: [] } get settingsHtml() { - let html = `Use NovelAI's TTS engine.
- The Voice IDs in the preview list are only examples, as it can be any string of text. Feel free to try different options!
- Hint: Save an API key in the NovelAI API settings to use it here.`; + let html = ` +
+ + Use NovelAI's TTS engine.
+ The default Voice IDs are only examples. Add custom voices and Novel will create a new random voice for it. Feel free to try different options!
+
+ Hint: Save an API key in the NovelAI API settings to use it here.
+ +
+ + + +
+ `; return html; } onSettingsChange() { + + } + + // Add a new Novel custom voice to provider + async addCustomVoice(){ + const voiceName = await callPopup('

Custom Voice name:

', 'input') + this.settings.customVoices.push(voiceName) + this.populateCustomVoices() + } + + // Delete selected custom voice from provider + deleteCustomVoice() { + const selected = $("#tts-novel-custom-voices-select").find(':selected').val(); + const voiceIndex = this.settings.customVoices.indexOf(selected); + + if (voiceIndex !== -1) { + this.settings.customVoices.splice(voiceIndex, 1); + } + this.populateCustomVoices() + } + + // Create the UI dropdown list of voices in provider + populateCustomVoices(){ + let voiceSelect = $("#tts-novel-custom-voices-select") + voiceSelect.empty() + this.settings.customVoices.forEach(voice => { + voiceSelect.append(``) + }) } loadSettings(settings) { @@ -32,6 +73,8 @@ class NovelTtsProvider { if (Object.keys(settings).length == 0) { console.info("Using default TTS Provider settings") } + $("#tts-novel-custom-voices-add").on('click', () => (this.addCustomVoice())) + $("#tts-novel-custom-voices-delete").on('click',() => (this.deleteCustomVoice())) // Only accept keys defined in defaultSettings this.settings = this.defaultSettings @@ -44,9 +87,22 @@ class NovelTtsProvider { } } + this.populateCustomVoices() + this.checkReady() console.info("Settings loaded") } + // Perform a simple readiness check by trying to fetch voiceIds + // Doesnt really do much for Novel, not seeing a good way to test this at the moment. + async checkReady(){ + try { + await this.fetchTtsVoiceIds() + this.ready = true + + } catch { + this.ready = false + } + } async onApplyClick() { return @@ -73,7 +129,7 @@ class NovelTtsProvider { // API CALLS // //###########// async fetchTtsVoiceIds() { - const voices = [ + let voices = [ { name: 'Ligeia', voice_id: 'Ligeia', lang: 'en-US', preview_url: false }, { name: 'Aini', voice_id: 'Aini', lang: 'en-US', preview_url: false }, { name: 'Orea', voice_id: 'Orea', lang: 'en-US', preview_url: false }, @@ -89,6 +145,12 @@ class NovelTtsProvider { { name: 'Lam', voice_id: 'Lam', lang: 'en-US', preview_url: false }, ]; + // Add in custom voices to the map + let addVoices = this.settings.customVoices.map(voice => + ({ name: voice, voice_id: voice, lang: 'en-US', preview_url: false }) + ) + voices = voices.concat(addVoices) + return voices; }