mirror of https://github.com/espruino/BangleApps
157 lines
6.9 KiB
HTML
157 lines
6.9 KiB
HTML
<html>
|
|
<head>
|
|
<link rel="stylesheet" href="../../css/spectre.min.css">
|
|
</head>
|
|
<body>
|
|
|
|
<p>Please choose a language from the following list:</p>
|
|
<div class="form-group">
|
|
<select id="languages" class="form-select">
|
|
</select>
|
|
</div>
|
|
<p>Then click <button id="upload" class="btn btn-primary">Upload</button></p>
|
|
|
|
<script src="../../lib/customize.js"></script>
|
|
<script src="locales.js"></script>
|
|
|
|
<script>
|
|
/*
|
|
eg. the built-in en_GB is:
|
|
|
|
exports = { name : "en_GB", currencySym:"£",
|
|
translate : str=>str, // as-is
|
|
date : (d,short) => short?("0"+d.getDate()).substr(-2)+"/"+("0"+(d.getMonth()+1)).substr(-2)+"/"+d.getFullYear():d.toString().substr(4,11), // Date to "Feb 28 2020" or "28/02/2020"(short)
|
|
time : (d,short) => { // Date to "4:15.28 pm" or "15:42"(short)
|
|
if (short)
|
|
return d.toString().substr(16,5);
|
|
else {
|
|
var h = d.getHours(), m = d.getMinutes(), r = "am";
|
|
if (h==0) { h=12; }
|
|
else if (h>=12) {
|
|
if (h>12) h-=12;
|
|
r = "pm";
|
|
}
|
|
return (" "+h).substr(-2)+":"+("0"+m).substr(-2)+"."+("0"+d.getSeconds()).substr(-2)+" "+r;
|
|
}
|
|
},
|
|
dow : (d,short) => short?d.toString().substr(0,3):"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(",")[d.getDay()], // Date to "Monday" or "Mon"(short)
|
|
month : (d,short) => short?d.toString().substr(4,3):"January,February,March,April,May,June,July,August,September,October,November,December".split(",")[d.getMonth()], // Date to "February" or "Feb"(short)
|
|
number : n => n.toString(), // more fancy?
|
|
currency : n => "£"+n.toFixed(2), // number to "£1.00"
|
|
distance : m => (m<1000)?Math.round(m)+"m":Math.round(m/160.934)/10+"mi", // meters to "123m" or "1.2mi" depending on size
|
|
speed : s => Math.round(s*0.621371)+"mph",// kph to "123mph"
|
|
temp : t => Math.round(t)+"'C" // degrees C to degrees C
|
|
meridian: d => (d.getHours() <= 12) ? "am":"pm",
|
|
};
|
|
|
|
*/
|
|
|
|
|
|
// do some sanity checks
|
|
Object.keys(locales).forEach(function(localeName) {
|
|
var locale = locales[localeName];
|
|
if (locale.trans && !locale.trans.on) console.error(localeName+": If translations are provided, 'on' *must* be included");
|
|
if (distanceUnits[locale.distance[0]]===undefined) console.error(localeName+": Unknown distance unit "+locale.distance[0]);
|
|
if (distanceUnits[locale.distance[1]]===undefined) console.error(localeName+": Unknown distance unit "+locale.distance[1]);
|
|
if (speedUnits[locale.speed]===undefined) console.error(localeName+": Unknown speed unit "+locale.speed);
|
|
});
|
|
|
|
var languageSelector = document.getElementById("languages");
|
|
languageSelector.innerHTML = Object.keys(locales).map(l=>{
|
|
var localeParts = l.split("_"); // en_GB -> ["en","GB"]
|
|
var icon = "";
|
|
// If we have a 2 char ISO country code, use it to get the unicode flag
|
|
if (localeParts[1] && localeParts[1].length==2)
|
|
icon = localeParts[1].toUpperCase().replace(/./g, char => String.fromCodePoint(char.charCodeAt(0)+127397) )+" ";
|
|
return `<option value="${l}">${icon}${l}</option>`
|
|
}).join("\n");
|
|
|
|
document.getElementById("upload").addEventListener("click", function() {
|
|
|
|
var lang = languageSelector.options[languageSelector.selectedIndex].value;
|
|
console.log(lang);
|
|
|
|
locale = locales[lang];
|
|
if (!locale) {
|
|
alert("Language not found!");
|
|
return;
|
|
}
|
|
|
|
|
|
function js(x) { return JSON.stringify(x); }
|
|
|
|
var replaceList = {
|
|
"%Y": "d.getFullYear()",
|
|
"%y": "(d.getFullYear().toString()).substr(-2)",
|
|
"%m": "('0'+(d.getMonth()+1).toString()).substr(-2)",
|
|
"%-m": "d.getMonth()+1",
|
|
"%d": "('0'+d.getDate()).substr(-2)",
|
|
"%-d": "d.getDate()",
|
|
"%HH": "('0'+d.getHours()).substr(-2)",
|
|
"%MM": "('0'+d.getMinutes()).substr(-2)",
|
|
"%SS": "('0'+d.getSeconds()).substr(-2)",
|
|
"%A": "l.day.split(',')[d.getDay()]",
|
|
"%a": "l.abday.split(',')[d.getDay()]",
|
|
"%B": "l.month.split(',')[d.getMonth()]",
|
|
"%b": "l.abmonth.split(',')[d.getMonth()]",
|
|
"%p": `(d.getHours()<12)?${js(locale.ampm[0].toUpperCase())}:${js(locale.ampm[1].toUpperCase())}`,
|
|
"%P": `(d.getHours()<12)?${js(locale.ampm[0].toLowerCase())}:${js(locale.ampm[1].toLowerCase())}`
|
|
};
|
|
|
|
var timeN = locales[lang].timePattern[0];
|
|
var timeS = locales[lang].timePattern[1];
|
|
var dateN = locales[lang].datePattern[0];
|
|
var dateS = locales[lang].datePattern[1];
|
|
Object.keys(replaceList).forEach(e => {
|
|
timeN = timeN.replace(e,"${"+replaceList[e]+"}");
|
|
timeS = timeS.replace(e,"${"+replaceList[e]+"}");
|
|
dateN = dateN.replace(e,"${"+replaceList[e]+"}");
|
|
dateS = dateS.replace(e,"${"+replaceList[e]+"}");
|
|
});
|
|
var currency = locale.currency_first ?
|
|
`${js(locale.currency_symbol)} + n.toFixed(2)`:
|
|
`n.toFixed(2) + ${js(locale.currency_symbol)}`;
|
|
var temperature;
|
|
if (locale.temperature=='°C') temperature="t";
|
|
else if (locale.temperature=='°F') temperature="(t*9/5)+32";
|
|
else throw new Error("Unknown temperature unit "+locale.temperature);
|
|
|
|
var localeModule = `var l = ${JSON.stringify({
|
|
abday : locale.abday,
|
|
day : locale.day,
|
|
abmonth : locale.abmonth,
|
|
month : locale.month,
|
|
})};
|
|
exports = {
|
|
name: ${js(locale.lang)},
|
|
currencySym: ${js(locale.currency_symbol)},
|
|
dow: (d,short) => {day = d.getDay();return (short) ? l.abday.split(",")[day] : l.day.split(",")[day];},
|
|
month: (d,short) => { month = d.getMonth(); return (short) ? l.abmonth.split(",")[month] : l.month.split(",")[month];},
|
|
number: n => n.toString(),
|
|
currency: n => ${currency},
|
|
distance: n => (n < ${distanceUnits[locale.distance[1]]}) ? Math.round(n/${distanceUnits[locale.distance[0]]}) + ${js(locale.distance[0])} : Math.round(n/${distanceUnits[locale.distance[1]]}) + ${js(locale.distance[1])},
|
|
speed: s => Math.round(s/${speedUnits[locale.speed]}) + ${js(locale.speed)},
|
|
temp: t => Math.round(${temperature}) + ${js(locale.temperature)},
|
|
translate: s => ${locale.trans?`{var t=${js(locale.trans)};s=""+s;return t[s]||t[s.toLowerCase()]||s;}`:`s`},
|
|
date: (d,short) => (short) ? \`${dateS}\`: \`${dateN}\`,
|
|
time: (d,short) => (short) ? \`${timeS}\`: \`${timeN}\`,
|
|
meridian: d => (d.getHours() <= 12) ? ${js(locale.ampm[0])}:${js(locale.ampm[1])},
|
|
};`;
|
|
console.log("Locale Module is:",localeModule);
|
|
/*
|
|
FIXME:
|
|
|
|
* Number/Currency need to add thousands separators: .replace(${js(locale.thousands_sep)}, ${js(locale.decimal_point)}) won't cut it as toString doesn't add separators itself
|
|
* distance (and speed) should probably use 1 decimal point for numbers less than 10
|
|
*/
|
|
|
|
sendCustomizedApp({
|
|
storage:[
|
|
{name:"locale", content:localeModule}
|
|
]
|
|
});
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|