Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Full refactor for download language feature #1170

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
125 changes: 42 additions & 83 deletions src/components/Settings/Language/Language.container.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand All @@ -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) {
tomivm marked this conversation as resolved.
Show resolved Hide resolved
await this.lookDownloadingLang();
}
};

handleSubmit = async (optionalLang = null) => {
const { onLangChange } = this.props;
const selectedLang = optionalLang ? optionalLang : this.state.selectedLang;
Expand Down Expand Up @@ -195,6 +211,7 @@ export class LanguageContainer extends Component {
isDiferentTts: false,
engineName: ttsName,
marketId: marketId,
isUpdated: false,
selectedLang: lang
};
this.props.setDownloadingLang(downloadingLangState);
Expand Down Expand Up @@ -341,6 +358,7 @@ export class LanguageContainer extends Component {
engineName: ttsName,
marketId: marketId,
selectedLang: lang,
isUpdated: false,
martinbedouret marked this conversation as resolved.
Show resolved Hide resolved
continueOnline,
firstClick
};
Expand Down Expand Up @@ -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(
<FormattedMessage {...messages.instaledLangSuccesNotification} />
);
history.push('/settings');
return;
}
const ttsEnginesNames = ttsEngines.map(tts => tts.name);
if (!ttsEnginesNames.includes(engineName)) {
this.setState({
Expand All @@ -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 (
tomivm marked this conversation as resolved.
Show resolved Hide resolved
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(
<FormattedMessage {...messages.instaledLangSuccesNotification} />
);
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();
}
};

Expand Down Expand Up @@ -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 = {
Expand Down
4 changes: 1 addition & 3 deletions src/providers/LanguageProvider/LanguageProvider.reducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const initialState = {
dir: 'ltr',
langs: [],
localLangs: [],
langsFetched: false,
downloadingLang: { isdownloading: false }
};

Expand Down Expand Up @@ -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 };
Expand Down
21 changes: 8 additions & 13 deletions src/providers/SpeechProvider/SpeechProvider.actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -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));
martinbedouret marked this conversation as resolved.
Show resolved Hide resolved
if (!voices.length) {
throw new Error('TTS engine does not have a language.');
}
Expand All @@ -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);
Expand All @@ -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;
Expand Down
30 changes: 24 additions & 6 deletions src/providers/SpeechProvider/SpeechProvider.container.js
Original file line number Diff line number Diff line change
Expand Up @@ -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() {
Expand All @@ -26,28 +30,38 @@ 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()) {
getTtsEngines();
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);
tomivm marked this conversation as resolved.
Show resolved Hide resolved
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 });
}
}

Expand All @@ -59,15 +73,19 @@ export class SpeechProvider extends Component {
}

const mapStateToProps = state => ({
ttsEngine: state.speech.ttsEngine
ttsEngine: state.speech.ttsEngine,
//todo: downloadingVoices
downloadingLang: state.language.downloadingLang
});

const mapDispatchToProps = {
getVoices,
getTtsEngines,
getTtsDefaultEngine,
setTtsEngine,
updateLangSpeechStatus
updateLangSpeechStatus,
//todo: setDownloadingVoices
setDownloadingLang
};

export default connect(
Expand Down
13 changes: 3 additions & 10 deletions src/reducers.js
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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,
Expand Down