1
0
mirror of https://github.com/LibreTranslate/LibreTranslate.git synced 2024-12-18 08:27:03 +02:00

fix: fix race condition in settings and langs

This commit is contained in:
Seth Falco 2022-06-21 19:33:34 +01:00
parent 3c1be4e731
commit 6e2df73a7f
No known key found for this signature in database
GPG Key ID: DE1C217EFF01FEC8

View File

@ -39,14 +39,17 @@ document.addEventListener('DOMContentLoaded', function(){
filesTranslation: true, filesTranslation: true,
frontendTimeout: 500 frontendTimeout: 500
}, },
mounted: function(){ mounted: function() {
var self = this; const self = this;
var requestSettings = new XMLHttpRequest();
requestSettings.open('GET', BaseUrl + '/frontend/settings', true);
requestSettings.onload = function() { const settingsRequest = new XMLHttpRequest();
settingsRequest.open("GET", BaseUrl + "/frontend/settings", true);
const langsRequest = new XMLHttpRequest();
langsRequest.open("GET", BaseUrl + "/languages", true);
settingsRequest.onload = function() {
if (this.status >= 200 && this.status < 400) { if (this.status >= 200 && this.status < 400) {
// Success!
self.settings = JSON.parse(this.response); self.settings = JSON.parse(this.response);
self.sourceLang = self.settings.language.source.code; self.sourceLang = self.settings.language.source.code;
self.targetLang = self.settings.language.target.code; self.targetLang = self.settings.language.target.code;
@ -55,74 +58,42 @@ document.addEventListener('DOMContentLoaded', function(){
self.supportedFilesFormat = self.settings.supportedFilesFormat; self.supportedFilesFormat = self.settings.supportedFilesFormat;
self.filesTranslation = self.settings.filesTranslation; self.filesTranslation = self.settings.filesTranslation;
self.frontendTimeout = self.settings.frontendTimeout; self.frontendTimeout = self.settings.frontendTimeout;
}else {
if (langsRequest.response) {
handleLangsResponse(self, langsRequest);
} else {
langsRequest.onload = function() {
handleLangsResponse(self, this);
}
}
} else {
self.error = "Cannot load /frontend/settings"; self.error = "Cannot load /frontend/settings";
self.loading = false; self.loading = false;
} }
}; };
requestSettings.onerror = function() { settingsRequest.onerror = function() {
self.error = "Error while calling /frontend/settings"; self.error = "Error while calling /frontend/settings";
self.loading = false; self.loading = false;
}; };
requestSettings.send(); langsRequest.onerror = function() {
var requestLanguages = new XMLHttpRequest();
requestLanguages.open('GET', BaseUrl + '/languages', true);
requestLanguages.onload = function() {
if (this.status >= 200 && this.status < 400) {
// Success!
self.langs = JSON.parse(this.response);
self.langs.push({ name: 'Auto Detect (Experimental)', code: 'auto' })
if (self.langs.length === 0){
self.loading = false;
self.error = "No languages available. Did you install the models correctly?"
return;
}
const sourceLanguage = self.langs.find(l => l.code === self.getQueryParam('source'))
const isSourceAuto = !sourceLanguage && self.getQueryParam('source') === "auto"
const targetLanguage = self.langs.find(l => l.code === self.getQueryParam('target'))
if (sourceLanguage || isSourceAuto) {
self.sourceLang = isSourceAuto ? "auto" : sourceLanguage.code
}
if (targetLanguage) {
self.targetLang = targetLanguage.code
}
const defaultText = self.getQueryParam('q')
if(defaultText) {
self.inputText = decodeURI(defaultText)
}
self.loading = false;
} else {
self.error = "Cannot load /languages";
self.loading = false;
}
};
requestLanguages.onerror = function() {
self.error = "Error while calling /languages"; self.error = "Error while calling /languages";
self.loading = false; self.loading = false;
}; };
requestLanguages.send(); settingsRequest.send();
langsRequest.send();
}, },
updated: function(){ updated: function(){
M.FormSelect.init(this.$refs.sourceLangDropdown); M.FormSelect.init(this.$refs.sourceLangDropdown);
M.FormSelect.init(this.$refs.targetLangDropdown); M.FormSelect.init(this.$refs.targetLangDropdown);
if (this.$refs.inputTextarea){ if (this.$refs.inputTextarea){
if (this.inputText === ""){ if (this.inputText === ""){
this.$refs.inputTextarea.style.height = this.inputTextareaHeight + "px"; this.$refs.inputTextarea.style.height = this.inputTextareaHeight + "px";
this.$refs.translatedTextarea.style.height = this.inputTextareaHeight + "px"; this.$refs.translatedTextarea.style.height = this.inputTextareaHeight + "px";
}else{ } else{
this.$refs.inputTextarea.style.height = this.$refs.translatedTextarea.style.height = "1px"; this.$refs.inputTextarea.style.height = this.$refs.translatedTextarea.style.height = "1px";
this.$refs.inputTextarea.style.height = Math.max(this.inputTextareaHeight, this.$refs.inputTextarea.scrollHeight + 32) + "px"; this.$refs.inputTextarea.style.height = Math.max(this.inputTextareaHeight, this.$refs.inputTextarea.scrollHeight + 32) + "px";
this.$refs.translatedTextarea.style.height = Math.max(this.inputTextareaHeight, this.$refs.translatedTextarea.scrollHeight + 32) + "px"; this.$refs.translatedTextarea.style.height = Math.max(this.inputTextareaHeight, this.$refs.translatedTextarea.scrollHeight + 32) + "px";
@ -136,28 +107,12 @@ document.addEventListener('DOMContentLoaded', function(){
// Update "selected" attribute (to overcome a vue.js limitation) // Update "selected" attribute (to overcome a vue.js limitation)
// but properly display checkmarks on supported browsers. // but properly display checkmarks on supported browsers.
// Also change the <select> width value depending on the <option> length // Also change the <select> width value depending on the <option> length
if (this.$refs.sourceLangDropdown){ if (this.$refs.sourceLangDropdown) {
for (var i = 0; i < this.$refs.sourceLangDropdown.children.length; i++){ updateSelectedAttribute(this.$refs.sourceLangDropdown, this.sourceLang);
var el = this.$refs.sourceLangDropdown.children[i];
if (el.value === this.sourceLang){
el.setAttribute('selected', '');
this.$refs.sourceLangDropdown.style.width = getTextWidth(el.text) + 24 + 'px';
}else{
el.removeAttribute('selected');
}
}
} }
if (this.$refs.targetLangDropdown){ if (this.$refs.targetLangDropdown) {
for (var i = 0; i < this.$refs.targetLangDropdown.children.length; i++){ updateSelectedAttribute(this.$refs.targetLangDropdown, this.targetLang);
var el = this.$refs.targetLangDropdown.children[i];
if (el.value === this.targetLang){
el.setAttribute('selected', '');
this.$refs.targetLangDropdown.style.width = getTextWidth(el.text) + 24 + 'px';
}else{
el.removeAttribute('selected');
}
}
} }
}, },
computed: { computed: {
@ -267,10 +222,10 @@ document.addEventListener('DOMContentLoaded', function(){
self.translatedText = res.translatedText; self.translatedText = res.translatedText;
self.loadingTranslation = false; self.loadingTranslation = false;
self.output = JSON.stringify(res, null, 4); self.output = JSON.stringify(res, null, 4);
}else{ } else{
throw new Error(res.error || "Unknown error"); throw new Error(res.error || "Unknown error");
} }
}catch(e){ } catch (e) {
self.error = e.message; self.error = e.message;
self.loadingTranslation = false; self.loadingTranslation = false;
} }
@ -422,9 +377,62 @@ document.addEventListener('DOMContentLoaded', function(){
} }
} }
}); });
}); });
/**
* @param {object} self
* @param {XMLHttpRequest} response
*/
function handleLangsResponse(self, response) {
if (response.status >= 200 && response.status < 400) {
self.langs = JSON.parse(response.response);
if (self.langs.length === 0){
self.loading = false;
self.error = "No languages available. Did you install the models correctly?"
return;
}
self.langs.push({ name: "Auto Detect (Experimental)", code: "auto" })
const sourceLanguage = self.langs.find(l => l.code === self.getQueryParam("source"))
const targetLanguage = self.langs.find(l => l.code === self.getQueryParam("target"))
if (sourceLanguage) {
self.sourceLang = sourceLanguage.code
}
if (targetLanguage) {
self.targetLang = targetLanguage.code
}
const defaultText = self.getQueryParam("q")
if (defaultText) {
self.inputText = decodeURI(defaultText)
}
} else {
self.error = "Cannot load /languages";
}
self.loading = false;
}
/**
* @param {object} langDropdown
* @param {string} lang
*/
function updateSelectedAttribute(langDropdown, lang) {
for (const child of langDropdown.children) {
if (child.value === lang){
child.setAttribute('selected', '');
langDropdown.style.width = getTextWidth(child.text) + 24 + 'px';
} else{
child.removeAttribute('selected');
}
}
}
function getTextWidth(text) { function getTextWidth(text) {
var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas")); var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
var ctx = canvas.getContext("2d"); var ctx = canvas.getContext("2d");