Added flags to translations

canary
WolverinDEV 2019-03-28 17:29:42 +01:00
parent 55463a7811
commit 5cb1b8b4da
3 changed files with 82 additions and 111 deletions

View File

@ -39,21 +39,20 @@ namespace i18n {
email: string; email: string;
} }
export interface FileInfo {
name: string;
contributors: Contributor[];
}
export interface TranslationFile { export interface TranslationFile {
url: string; path: string;
full_url: string;
info: FileInfo;
translations: Translation[]; translations: Translation[];
} }
export interface RepositoryTranslation { export interface RepositoryTranslation {
key: string; key: string;
path: string; path: string;
country_code: string;
name: string;
contributors: Contributor[];
} }
export interface TranslationRepository { export interface TranslationRepository {
@ -85,7 +84,7 @@ namespace i18n {
return translated; return translated;
} }
async function load_translation_file(url: string) : Promise<TranslationFile> { async function load_translation_file(url: string, path: string) : Promise<TranslationFile> {
return new Promise<TranslationFile>((resolve, reject) => { return new Promise<TranslationFile>((resolve, reject) => {
$.ajax({ $.ajax({
url: url, url: url,
@ -98,7 +97,8 @@ namespace i18n {
return; return;
} }
file.url = url; file.full_url = url;
file.path = path;
//TODO validate file //TODO validate file
resolve(file); resolve(file);
} catch(error) { } catch(error) {
@ -113,8 +113,8 @@ namespace i18n {
}); });
} }
export function load_file(url: string) : Promise<void> { export function load_file(url: string, path: string) : Promise<void> {
return load_translation_file(url).then(result => { return load_translation_file(url, path).then(result => {
log.info(LogCategory.I18N, tr("Successfully initialized up translation file from %s"), url); log.info(LogCategory.I18N, tr("Successfully initialized up translation file from %s"), url);
translations = result.translations; translations = result.translations;
return Promise.resolve(); return Promise.resolve();
@ -169,6 +169,7 @@ namespace i18n {
current_language?: string; current_language?: string;
current_translation_url: string; current_translation_url: string;
current_translation_path: string;
} }
export interface RepositoryConfig { export interface RepositoryConfig {
@ -248,65 +249,31 @@ namespace i18n {
config.save_repository_config(); config.save_repository_config();
} }
export function iterate_translations(callback_entry: (repository: TranslationRepository, entry: TranslationFile) => any, callback_finish: () => any) { export async function iterate_repositories(callback_entry: (repository: TranslationRepository) => any) {
let count = 0; const promises = [];
const update_finish = () => {
if(count == 0 && callback_finish)
callback_finish();
};
for(const repo of registered_repositories()) { for(const repository of registered_repositories()) {
count++; promises.push(load_repository0(repository, false).then(() => callback_entry(repository)).catch(error => {
load_repository0(repo, false).then(() => { log.warn(LogCategory.I18N, "Failed to fetch repository %s. error: %o", repository.url, error);
for(const translation of repo.translations || []) { }));
const translation_path = repo.url + "/" + translation.path;
count++;
load_translation_file(translation_path).then(file => {
if(callback_entry) {
try {
callback_entry(repo, file);
} catch (error) {
console.error(error);
//TODO more error handling?
}
}
count--;
update_finish();
}).catch(error => {
log.warn(LogCategory.I18N, tr("Failed to load translation file for repository %s. Translation: %s (%s) Error: %o"), repo.name, translation.key, translation_path, error);
count--;
update_finish();
});
}
count--;
update_finish();
}).catch(error => {
log.warn(LogCategory.I18N, tr("Failed to load repository while iteration: %s (%s). Error: %o"), (repo || {name: "unknown"}).name, (repo || {url: "unknown"}).url, error);
count--;
update_finish();
});
} }
await Promise.all(promises);
update_finish();
} }
export function select_translation(repository: TranslationRepository, entry: TranslationFile) { export function select_translation(repository: TranslationRepository, entry: RepositoryTranslation) {
const cfg = config.translation_config(); const cfg = config.translation_config();
if(entry && repository) { if(entry && repository) {
cfg.current_language = entry.info.name; cfg.current_language = entry.name;
cfg.current_repository_url = repository.url; cfg.current_repository_url = repository.url;
cfg.current_translation_url = entry.url; cfg.current_translation_url = repository.url + entry.path;
cfg.current_translation_path = entry.path;
} else { } else {
cfg.current_language = undefined; cfg.current_language = undefined;
cfg.current_repository_url = undefined; cfg.current_repository_url = undefined;
cfg.current_translation_url = undefined; cfg.current_translation_url = undefined;
cfg.current_translation_path = undefined;
} }
config.save_translation_config(); config.save_translation_config();
@ -318,7 +285,7 @@ namespace i18n {
if(cfg.current_translation_url) { if(cfg.current_translation_url) {
try { try {
await load_file(cfg.current_translation_url); await load_file(cfg.current_translation_url, cfg.current_translation_path);
} catch (error) { } catch (error) {
createErrorModal(tr("Translation System"), tr("Failed to load current selected translation file.") + "<br>File: " + cfg.current_translation_url + "<br>Error: " + error + "<br>" + tr("Using default fallback translations.")).open(); createErrorModal(tr("Translation System"), tr("Failed to load current selected translation file.") + "<br>File: " + cfg.current_translation_url + "<br>Error: " + error + "<br>" + tr("Using default fallback translations.")).open();
} }

View File

@ -157,7 +157,7 @@ namespace Modals {
let Regex = { let Regex = {
//DOMAIN<:port> //DOMAIN<:port>
DOMAIN: /^(localhost|((([a-zA-Z0-9_-]{0,63}\.){0,253})?[a-zA-Z0-9_-]{0,63}\.[a-zA-Z]{2,5}))(|:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[0-5]?[0-9]{1,4}))$/, DOMAIN: /^(localhost|((([a-zA-Z0-9_-]{0,63}\.){0,253})?[a-zA-Z0-9_-]{0,63}\.[a-zA-Z]{2,64}))(|:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[0-5]?[0-9]{1,46}))$/,
//IP<:port> //IP<:port>
IP_V4: /(^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(|:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[0-5]?[0-9]{1,4}))$/, IP_V4: /(^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))(|:(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[0-5]?[0-9]{1,4}))$/,
IP_V6: /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/, IP_V6: /(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/,

View File

@ -611,7 +611,7 @@ namespace Modals {
}; };
tag_loading.show(); tag_loading.show();
i18n.iterate_translations((repo, entry) => { i18n.iterate_repositories(repo => {
let repo_tag = tag_list.find("[repository=\"" + repo.unique_id + "\"]"); let repo_tag = tag_list.find("[repository=\"" + repo.unique_id + "\"]");
if (repo_tag.length == 0) { if (repo_tag.length == 0) {
repo_tag = template.renderTag({ repo_tag = template.renderTag({
@ -639,59 +639,63 @@ namespace Modals {
tag_list.append(repo_tag); tag_list.append(repo_tag);
} }
const tag = template.renderTag({ for(const translation of repo.translations) {
type: "translation", const tag = template.renderTag({
name: entry.info.name || entry.url, type: "translation",
id: repo.unique_id, name: translation.name || translation.path,
selected: i18n.config.translation_config().current_translation_url == entry.url id: repo.unique_id,
}); country_code: translation.country_code,
tag.find(".button-info").on('click', e => { selected: i18n.config.translation_config().current_translation_path == translation.path
e.preventDefault();
const info_modal = createModal({
header: tr("Translation info"),
body: () => {
const tag = $("#settings-translations-list-entry-info").renderTag({
type: "translation",
name: entry.info.name,
url: entry.url,
repository_name: repo.name,
contributors: entry.info.contributors || []
});
tag.find(".button-info").on('click', () => display_repository_info(repo));
return tag;
},
footer: () => {
let footer = $.spawn("div");
footer.addClass("modal-button-group");
footer.css("margin-top", "5px");
footer.css("margin-bottom", "5px");
footer.css("text-align", "right");
let buttonOk = $.spawn("button");
buttonOk.text(tr("Close"));
buttonOk.click(() => info_modal.close());
footer.append(buttonOk);
return footer;
}
}); });
info_modal.open() tag.find(".button-info").on('click', e => {
}); e.preventDefault();
tag.on('click', e => {
if (e.isDefaultPrevented()) return;
i18n.select_translation(repo, entry);
tag_list.find(".selected").removeClass("selected");
tag.addClass("selected");
restart_hint.show(); const info_modal = createModal({
}); header: tr("Translation info"),
tag.insertAfter(repo_tag) body: () => {
}, () => { const tag = $("#settings-translations-list-entry-info").renderTag({
tag_loading.hide(); type: "translation",
}); name: translation.name,
url: translation.path,
repository_name: repo.name,
contributors: translation.contributors || []
});
tag.find(".button-info").on('click', () => display_repository_info(repo));
return tag;
},
footer: () => {
let footer = $.spawn("div");
footer.addClass("modal-button-group");
footer.css("margin-top", "5px");
footer.css("margin-bottom", "5px");
footer.css("text-align", "right");
let buttonOk = $.spawn("button");
buttonOk.text(tr("Close"));
buttonOk.click(() => info_modal.close());
footer.append(buttonOk);
return footer;
}
});
info_modal.open()
});
tag.on('click', e => {
if (e.isDefaultPrevented()) return;
i18n.select_translation(repo, translation);
tag_list.find(".selected").removeClass("selected");
tag.addClass("selected");
restart_hint.show();
});
tag.insertAfter(repo_tag);
}
}).then(() => tag_loading.hide()).catch(error => {
console.error(error);
/* this should NEVER happen */
})
} }
}; };