diff --git a/src/main/factories/ipcs/pipeline.ts b/src/main/factories/ipcs/pipeline.ts index e39811e..bfe64fe 100644 --- a/src/main/factories/ipcs/pipeline.ts +++ b/src/main/factories/ipcs/pipeline.ts @@ -1,5 +1,5 @@ import { app, ipcMain, dialog } from 'electron' -import { resolve, delimiter, relative } from 'path' +import path, { resolve, delimiter, relative } from 'path' import { Webservice, PipelineStatus, @@ -26,6 +26,7 @@ import { setStatus, useWebservice, } from 'shared/data/slices/pipeline' +import fs from 'fs-extra' /** * Local DAISY Pipeline 2 management class @@ -365,7 +366,6 @@ Then close the program using the port and restart this application.`, '-Dorg.daisy.pipeline.ws.port=' + this.props.webservice.port ) } - if ( !existsSync(this.props.appDataFolder) && mkdirSync(this.props.appDataFolder, { recursive: true }) @@ -387,6 +387,33 @@ Then close the program using the port and restart this application.`, `Using existing ${this.props.logsFolder} for pipeline logs` ) } + // this file would contain TTS settings to pass to the pipeline on startup + // e.g. it could contain credentials for cloud-based TTS engines, without which the voices + // for that engine wouldn't be listed as available to the user + // additional TTS settings are passed in with jobs (e.g. voice selection but currently not engine properties) + let ttsEnginePropertiesFilepath = path.join( + this.props.appDataFolder, + 'tts-engine-properties.json' + ) + // if this TTS config file exists, then add its properties to SystemProps + if (existsSync(ttsEnginePropertiesFilepath)) { + try { + let f = fs.readFileSync(ttsEnginePropertiesFilepath) + let ttsEngineProperties = JSON.parse(f.toString()) + // @ts-ignore + ttsEngineProperties.map((property) => + SystemProps.push(`-D${property.key}=${property.value}`) + ) + } catch (err) { + this.pushMessage( + `Could not set TTS engine properties on startup from file ${ttsEnginePropertiesFilepath}` + ) + } + } else { + this.pushMessage( + `File not found for additional TTS engine properties (checking default location: ${ttsEnginePropertiesFilepath})` + ) + } // avoid using bat to control the runner ? // Spawn pipeline process let command = resolve(this.props.jrePath, 'bin', 'java') diff --git a/src/renderer/components/JobDetailsPane/Results.tsx b/src/renderer/components/JobDetailsPane/Results.tsx index dc6e715..2ba2a95 100644 --- a/src/renderer/components/JobDetailsPane/Results.tsx +++ b/src/renderer/components/JobDetailsPane/Results.tsx @@ -1,5 +1,8 @@ import { Job } from 'shared/types' import { FileLink } from '../FileLink' +import remarkGfm from 'remark-gfm' +import { externalLinkClick } from 'renderer/utils' +import Markdown from 'react-markdown' export function Results({ job }: { job: Job }) { return ( @@ -9,7 +12,28 @@ export function Results({ job }: { job: Job }) { {item.nicename} - {item.desc} +
+ { + return ( + + externalLinkClick(e, App) + } + > + {props.children} + + ) + }, + }} + > + {item.desc} + +
))} diff --git a/src/renderer/components/TtsConfig/index.tsx b/src/renderer/components/TtsConfig/index.tsx index d147ed3..7f2d3d0 100644 --- a/src/renderer/components/TtsConfig/index.tsx +++ b/src/renderer/components/TtsConfig/index.tsx @@ -18,6 +18,9 @@ export function TtsConfigPane({ const [preferredVoices, setPreferredVoices] = useState([ ...userPreferredVoices, ]) + const [engines, setEngines] = useState([]) + const [langs, setLangs] = useState([]) + const [enginesChecked, setEnginesChecked] = useState([]) // table filter search const [searchString, setSearchString] = useState('') @@ -83,12 +86,28 @@ export function TtsConfigPane({ }, [searchString]) useEffect(() => { + let tmpVoices = [...voiceList] + for (let v of tmpVoices) { + v.show = enginesChecked.includes(v.engine) + } + setVoiceList(tmpVoices) + }, [enginesChecked]) + + useEffect(() => { + let langs_ = Array.from(new Set(voiceList.map((v) => v.lang))) + let engines_ = Array.from(new Set(voiceList.map((v) => v.engine))) // sort on startup sortVoices(sortSettings.selected) + // see what engines and languages are included in this voices array + setLangs(langs_) + setEngines(engines_) + // start with all engines selected + setEnginesChecked(engines_) }, []) let clearSearch = () => { setSearchString('') + setEnginesChecked([...engines]) } // let moveVoice = (currPos, newPos) => { // console.log('Move', currPos, newPos) @@ -98,6 +117,18 @@ export function TtsConfigPane({ // setVoiceList(tmpVoices) // } + let changeEngineFilter = (e, engine) => { + let tmpEngines + if (e.target.checked) { + tmpEngines = [...enginesChecked, engine] + setEnginesChecked(tmpEngines) + } else { + tmpEngines = [...enginesChecked] + let idx = tmpEngines.findIndex((eng) => eng == engine) + tmpEngines.splice(idx, 1) + setEnginesChecked(tmpEngines) + } + } let getAriaSortValue = (colName) => { return sortSettings.selected == colName ? sortSettings[colName] == 1 @@ -115,18 +146,43 @@ export function TtsConfigPane({ configuration.

- - { - setSearchString(e.target.value) - }} - onKeyDown={(e) => { - e.key === 'Enter' && e.preventDefault() - }} - /> +
+ + { + setSearchString(e.target.value) + }} + onKeyDown={(e) => { + e.key === 'Enter' && e.preventDefault() + }} + /> +
+
+ Show engines: + +
{voiceList.filter((v) => v.show).length > 0 ? (
- +

No voices found{' '} - {searchString != '' ? ( + {searchString != '' || enginesChecked.length == 0 ? (