pluralisation and %s for numebr substitute, with simple conversion code for frontend

indiachan-spamvector
Thomas Lynch 1 year ago
parent 5db3bedb4d
commit 2d48f4110b
  1. 6
      gulp/res/js/forms.js
  2. 14
      gulp/res/js/i18n.js
  3. 1
      gulpfile.js
  4. 21
      locales/en.json
  5. 21
      locales/pt.json
  6. 4
      views/includes/postform.pug
  7. 2
      views/mixins/filelabel.pug

@ -1,4 +1,4 @@
/* globals modal Tegaki grecaptcha hcaptcha captchaController appendLocalStorageArray socket isThread setLocalStorage forceUpdate captchaController uploaditem */ /* globals __n modal Tegaki grecaptcha hcaptcha captchaController appendLocalStorageArray socket isThread setLocalStorage forceUpdate captchaController uploaditem */
async function videoThumbnail(file) { async function videoThumbnail(file) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const hiddenVideo = document.createElement('video'); const hiddenVideo = document.createElement('video');
@ -517,9 +517,9 @@ class postFormHandler {
if (this.files && this.files.length === 0) { if (this.files && this.files.length === 0) {
this.fileUploadList.textContent = ''; this.fileUploadList.textContent = '';
this.fileUploadList.style.display = 'none'; this.fileUploadList.style.display = 'none';
this.fileLabelText.nodeValue = `Select/Drop/Paste file${this.multipleFiles ? 's' : ''}`; this.fileLabelText.nodeValue = __n('Select/Drop/Paste files', this.multipleFiles ? 2 : 1);
} else { } else {
this.fileLabelText.nodeValue = `${this.files.length} file${this.files.length > 1 ? 's' : ''} selected`; this.fileLabelText.nodeValue = __n('%s files selected', this.files.length);
} }
this.fileInput.value = null; this.fileInput.value = null;
} }

@ -1,6 +1,18 @@
/* eslint-disable no-unused-vars */ /* eslint-disable no-unused-vars */
/* globals LANG */ /* globals LANG */
const pluralMap = {
1: 'one',
// two, three, few, many, ...
};
//simple translation
const __ = (key) => { const __ = (key) => {
//TODO: we'll see if this needs to be more advanced in future
return LANG[key]; return LANG[key];
}; };
//plurals+replace %s with count
const __n = (key, count) => {
const pluralKey = pluralMap[count] || 'other';
return LANG[key][pluralKey].replace('%s', count);
};

@ -466,6 +466,7 @@ const extraLocals = ${JSON.stringify({ meta: config.get.meta, reverseImageLinksU
`; `;
fs.writeFileSync('gulp/res/js/locals.js', locals); fs.writeFileSync('gulp/res/js/locals.js', locals);
del([ 'static/js/lang/' ]),
fs.mkdirSync(`${paths.scripts.dest}lang/`); fs.mkdirSync(`${paths.scripts.dest}lang/`);
Object.entries(i18n.getCatalog()) Object.entries(i18n.getCatalog())
.forEach(entry => { .forEach(entry => {

@ -21,13 +21,24 @@
"Email": "Email", "Email": "Email",
"Subject": "Subject", "Subject": "Subject",
"Message": "Message", "Message": "Message",
"Files": "Files", "Files": {
"File": "File", "one": "File",
"Max": "Max", "other": "Files"
},
"Max %s files": {
"one": "Max %s file",
"other": "Max %s files"
},
"total": "total", "total": "total",
"Password": "Password", "Password": "Password",
"Select/Drop/Paste file": "Select/Drop/Paste file", "Select/Drop/Paste files": {
"Select/Drop/Paste files": "Select/Drop/Paste files", "one": "Select/Drop/Paste file",
"other": "Select/Drop/Paste files"
},
"%s files selected": {
"one": "%s file selected",
"other": "%s files selected"
},
"Tegaki": "Tegaki", "Tegaki": "Tegaki",
"Replayable?": "Replayable?", "Replayable?": "Replayable?",
"Draw": "Draw", "Draw": "Draw",

@ -21,13 +21,24 @@
"Email": "Opção", "Email": "Opção",
"Subject": "Assunto", "Subject": "Assunto",
"Message": "Mensagem", "Message": "Mensagem",
"Files": "Ficheiros", "Files": {
"Files": "Ficheiro", "one": "Ficheiro",
"Max": "Máx", "other": "Ficheiros"
},
"Max %s files": {
"one": "Máx %s",
"other": "Máx %s"
},
"total": "total", "total": "total",
"Password": "Password", "Password": "Password",
"Select/Drop/Paste file": "Seleciona/Arrasta/Cola ficheiro", "Select/Drop/Paste files": {
"Select/Drop/Paste files": "Seleciona/Arrasta/Cola ficheiros", "one": "Seleciona/Arrasta/Cola ficheiro",
"other": "Seleciona/Arrasta/Cola ficheiros"
},
"%s files selected": {
"one": "%s ficheiro selecionado",
"other": "%s ficheiros selecionados"
},
"Tegaki": "Tegaki", "Tegaki": "Tegaki",
"Replayable?": "Replay?", "Replayable?": "Replay?",
"Draw": "Desenhar", "Draw": "Desenhar",

@ -44,13 +44,13 @@ section.form-wrapper.flex-center
- const maxFiles = board.settings.maxFiles; - const maxFiles = board.settings.maxFiles;
section.row section.row
.label .label
span #{__(`File${maxFiles > 1 ? 's' : ''}`)} span #{__n('Files', maxFiles)}
if fileRequired if fileRequired
span.required * span.required *
| |
| |
if maxFiles > 1 if maxFiles > 1
small #{__('Max')} #{maxFiles} small #{__n('Max %s files', maxFiles)}
small #{postFilesSize} #{__('total')} small #{postFilesSize} #{__('total')}
span.col span.col
+filelabel('file', maxFiles) +filelabel('file', maxFiles)

@ -1,3 +1,3 @@
mixin filelabel(id, max) mixin filelabel(id, max)
label.jsonly.postform-style.filelabel(for=id) label.jsonly.postform-style.filelabel(for=id)
| #{__(`Select/Drop/Paste file${max > 1 ? 's' : ''}`)} | #{__n(`Select/Drop/Paste files`, max)}

Loading…
Cancel
Save