diff --git a/src/components/Settings/Language/Language.container.js b/src/components/Settings/Language/Language.container.js index 245215978..7c06d376d 100644 --- a/src/components/Settings/Language/Language.container.js +++ b/src/components/Settings/Language/Language.container.js @@ -59,10 +59,6 @@ export class LanguageContainer extends Component { * TTS default engine */ ttsDefaultEngine: PropTypes.object, - /** - * list of available voices - */ - voices: PropTypes.array, /** * Callback fired when language changes */ @@ -87,10 +83,30 @@ export class LanguageContainer extends Component { avaliableAndDownloadablesLangs: [], downloadablesOnly: [] }, - downloadLangLoading: true, + downloadLangLoading: false, downloadingLangError: { ttsError: false, langError: false } }; + componentDidMount = async () => { + const { isdownloading } = this.props.downloadingLang; + this.setState({ + downloadablesLangs: isAndroid() + ? this.prepareDownloadablesLenguages() + : { + avaliableAndDownloadablesLangs: [], + downloadablesOnly: [] + } + }); + this.setState({ downloadLangLoading: !!isdownloading }); + }; + + componentDidUpdate = async () => { + const { isdownloading, isUpdated } = this.props.downloadingLang; + if (isdownloading && isUpdated) { + await this.lookDownloadingLang(); + } + }; + handleSubmit = async (optionalLang = null) => { const { onLangChange } = this.props; const selectedLang = optionalLang ? optionalLang : this.state.selectedLang; @@ -195,6 +211,7 @@ export class LanguageContainer extends Component { isDiferentTts: false, engineName: ttsName, marketId: marketId, + isUpdated: false, selectedLang: lang }; this.props.setDownloadingLang(downloadingLangState); @@ -341,6 +358,7 @@ export class LanguageContainer extends Component { engineName: ttsName, marketId: marketId, selectedLang: lang, + isUpdated: false, continueOnline, firstClick }; @@ -403,13 +421,26 @@ export class LanguageContainer extends Component { const { setDownloadingLang, - + localLangs, ttsEngines, ttsEngine, history, showNotification } = this.props; + this.setState({ downloadLangLoading: false }); + + if (engineName === ttsEngine.name && localLangs.includes(selectedLang)) { + setDownloadingLang({ isdownloading: false }); + this.setState({ selectedLang: selectedLang }); + if (isDiferentTts) return; + await this.handleSubmit(selectedLang); + showNotification( + + ); + history.push('/settings'); + return; + } const ttsEnginesNames = ttsEngines.map(tts => tts.name); if (!ttsEnginesNames.includes(engineName)) { this.setState({ @@ -418,86 +449,16 @@ export class LanguageContainer extends Component { ttsError: true } }); - return; - } - if (ttsEngine.name !== engineName) { - try { - await this.handleSetTtsEngine(engineName); - } catch { - this.setState({ - downloadingLangError: { - ttsError: false, - langError: true - } - }); - } - } - const localLangs = this.props.localLangs; - if (!localLangs.includes(selectedLang)) { + } else if ( + ttsEngine.name !== engineName || + !localLangs.includes(selectedLang) + ) { this.setState({ downloadingLangError: { ttsError: false, langError: true } }); - return; - } - const downloadingLangState = { - isdownloading: false - }; - setDownloadingLang(downloadingLangState); - this.setState({ - downloadingLangError: { - ttsError: false, - langError: false - }, - selectedLang: selectedLang - }); - this.refreshLanguageList(); - if (isDiferentTts) return; - await this.handleSubmit(selectedLang); - showNotification( - - ); - history.push('/settings'); - }; - - refreshLanguageList = () => { - this.setState({ - downloadablesLangs: isAndroid() - ? this.prepareDownloadablesLenguages() - : { - //downloadablesLangsList: [] - avaliableAndDownloadablesLangs: [], - downloadablesOnly: [] - } - }); - }; - - refreshDownloadLanguage = async () => { - const { isdownloading } = this.props.downloadingLang; - - this.refreshLanguageList(); - - if (isdownloading) await this.lookDownloadingLang(); - this.setState({ downloadLangLoading: false }); - }; - - componentDidMount = async () => { - if (this.props.langsFetched) this.refreshDownloadLanguage(); - }; - - componentDidUpdate = async prevProps => { - const isdownloading = this.props.downloadingLang?.isdownloading; - const langsFetched = this.props.langsFetched; - - if (!prevProps.langsFetched && langsFetched) { - this.setState({ downloadLangLoading: true }); - await this.refreshDownloadLanguage(); - } - if (!isdownloading) return; - if (prevProps.downloadingLang.isdownloading === false) { - await this.refreshDownloadLanguage(); } }; @@ -556,13 +517,11 @@ export class LanguageContainer extends Component { const mapStateToProps = state => ({ lang: state.language.lang, - langsFetched: state.language.langsFetched, langs: state.language.langs, localLangs: state.language.localLangs, ttsEngines: state.speech.ttsEngines, ttsEngine: state.speech.ttsEngine, - downloadingLang: state.language.downloadingLang, - voices: state.speech.voices + downloadingLang: state.language.downloadingLang }); const mapDispatchToProps = { diff --git a/src/providers/LanguageProvider/LanguageProvider.reducer.js b/src/providers/LanguageProvider/LanguageProvider.reducer.js index 68a17418d..3b22429ad 100644 --- a/src/providers/LanguageProvider/LanguageProvider.reducer.js +++ b/src/providers/LanguageProvider/LanguageProvider.reducer.js @@ -16,7 +16,6 @@ const initialState = { dir: 'ltr', langs: [], localLangs: [], - langsFetched: false, downloadingLang: { isdownloading: false } }; @@ -45,8 +44,7 @@ function languageProviderReducer(state = initialState, action) { return { ...state, langs: action.langs.sort(), - localLangs: action.localLangs || [], - langsFetched: true + localLangs: action.localLangs || [] }; case SET_DOWNLOADING_LANG: return { ...state, downloadingLang: action.downloadingLangData }; diff --git a/src/providers/SpeechProvider/SpeechProvider.actions.js b/src/providers/SpeechProvider/SpeechProvider.actions.js index 3c8666a52..bfee21d82 100644 --- a/src/providers/SpeechProvider/SpeechProvider.actions.js +++ b/src/providers/SpeechProvider/SpeechProvider.actions.js @@ -52,26 +52,19 @@ export function receiveTtsEngine(ttsEngineName) { } export function getTtsEngines() { - const ttsEngines = tts?.getTtsEngines(); + const ttsEngines = tts.getTtsEngines(); return { type: RECEIVE_TTS_ENGINES, ttsEngines }; } -export function setTtsEngine(selectedTtsEngineName) { +export function setTtsEngine(ttsEngineName) { return async dispatch => { dispatch(requestTtsEngine()); try { - const engineAvailable = tts - .getTtsEngines() - .map(tts => tts.name) - .includes(selectedTtsEngineName); - const engineName = engineAvailable - ? selectedTtsEngineName - : tts.getTtsDefaultEngine().name; - const voices = await tts.setTtsEngine(engineName); - dispatch(receiveTtsEngine(engineName)); + const voices = await tts.setTtsEngine(ttsEngineName); + dispatch(receiveTtsEngine(ttsEngineName)); if (!voices.length) { throw new Error('TTS engine does not have a language.'); } @@ -81,7 +74,7 @@ export function setTtsEngine(selectedTtsEngineName) { }; } -export function updateLangSpeechStatus(voices) { +export function updateLangSpeechStatus(voices, forceChangeVoice = false) { return async (dispatch, getState) => { try { const supportedLangs = getSupportedLangs(voices); @@ -102,7 +95,9 @@ export function updateLangSpeechStatus(voices) { // last step is to change voice in case it is available if ( - getState().speech.options.lang.substring(0, 2) !== lang.substring(0, 2) + getState().speech.options.lang.substring(0, 2) !== + lang.substring(0, 2) || + forceChangeVoice ) { const uris = voices.map(v => { return v.voiceURI; diff --git a/src/providers/SpeechProvider/SpeechProvider.container.js b/src/providers/SpeechProvider/SpeechProvider.container.js index 15778fa9c..380ff1b42 100644 --- a/src/providers/SpeechProvider/SpeechProvider.container.js +++ b/src/providers/SpeechProvider/SpeechProvider.container.js @@ -10,13 +10,17 @@ import { updateLangSpeechStatus, setTtsEngine } from './SpeechProvider.actions'; +import { setDownloadingLang } from '../LanguageProvider/LanguageProvider.actions'; + import { isAndroid } from '../../cordova-util'; export class SpeechProvider extends Component { static propTypes = { children: PropTypes.node.isRequired, ttsEngine: PropTypes.object, - setTtsEngine: PropTypes.func + setTtsEngine: PropTypes.func, + downloadingLang: PropTypes.object, + setDownloadingLang: PropTypes.func }; async componentDidMount() { @@ -26,9 +30,12 @@ export class SpeechProvider extends Component { getTtsEngines, getTtsDefaultEngine, ttsEngine, - setTtsEngine + setTtsEngine, + downloadingLang, + setDownloadingLang } = this.props; + let forceChangeVoice = false; if (tts.isSupported()) { //if android we have to set the tts engine first if (isAndroid()) { @@ -36,18 +43,25 @@ export class SpeechProvider extends Component { getTtsDefaultEngine(); } if (ttsEngine && ttsEngine.name) { + const ttsEnginesName = + downloadingLang?.isdownloading && + downloadingLang.engineName !== ttsEngine.name + ? downloadingLang.engineName + : ttsEngine.name; try { - await setTtsEngine(ttsEngine.name); + await setTtsEngine(ttsEnginesName); + forceChangeVoice = true; } catch (err) { console.error(err.message); } } try { const voices = await getVoices(); - await updateLangSpeechStatus(voices); + await updateLangSpeechStatus(voices, forceChangeVoice); } catch (err) { console.error(err.message); } + setDownloadingLang({ ...downloadingLang, isUpdated: true }); } } @@ -59,7 +73,9 @@ export class SpeechProvider extends Component { } const mapStateToProps = state => ({ - ttsEngine: state.speech.ttsEngine + ttsEngine: state.speech.ttsEngine, + //todo: downloadingVoices + downloadingLang: state.language.downloadingLang }); const mapDispatchToProps = { @@ -67,7 +83,9 @@ const mapDispatchToProps = { getTtsEngines, getTtsDefaultEngine, setTtsEngine, - updateLangSpeechStatus + updateLangSpeechStatus, + //todo: setDownloadingVoices + setDownloadingLang }; export default connect( diff --git a/src/reducers.js b/src/reducers.js index 47621ad32..c30c9acad 100644 --- a/src/reducers.js +++ b/src/reducers.js @@ -1,4 +1,4 @@ -import { persistCombineReducers, persistReducer } from 'redux-persist'; +import { persistCombineReducers } from 'redux-persist'; import appReducer from './components/App/App.reducer'; import languageProviderReducer from './providers/LanguageProvider/LanguageProvider.reducer'; @@ -11,20 +11,13 @@ import storage from 'redux-persist/lib/storage'; const config = { key: 'root', - storage, - blacklist: ['language'] -}; - -const languagePersistConfig = { - key: 'language', - storage: storage, - blacklist: ['langsFetched'] + storage }; export default function createReducer() { return persistCombineReducers(config, { app: appReducer, - language: persistReducer(languagePersistConfig, languageProviderReducer), + language: languageProviderReducer, speech: speechProviderReducer, board: boardReducer, communicator: communicatorReducer,