Browse Source

Faster time formatting

master
Eduard Kuzmenko 3 years ago
parent
commit
68fbe05f36
  1. 64
      src/lib/langPack.ts

64
src/lib/langPack.ts

@ -109,10 +109,32 @@ namespace I18n {
}); });
} }
export function setTimeFormat(format: State['settings']['timeFormat']) { function updateAmPm() {
const haveToUpdate = !!timeFormat && timeFormat !== format; if(timeFormat === 'h12') {
try {
const dateTimeFormat = getDateTimeFormat({hour: 'numeric', minute: 'numeric', hour12: true});
const date = new Date();
date.setHours(0);
const amText = dateTimeFormat.format(date);
amPmCache.am = amText.split(' ')[1];
date.setHours(12);
const pmText = dateTimeFormat.format(date);
amPmCache.pm = pmText.split(' ')[1];
} catch(err) {
console.error('cannot get am/pm', err);
amPmCache = {am: 'AM', pm: 'PM'};
}
}
}
export function setTimeFormat(
format: State['settings']['timeFormat'],
haveToUpdate = !!timeFormat && timeFormat !== format
) {
timeFormat = format; timeFormat = format;
updateAmPm();
if(haveToUpdate) { if(haveToUpdate) {
cachedDateTimeFormats.clear(); cachedDateTimeFormats.clear();
const elements = Array.from(document.querySelectorAll(`.i18n`)) as HTMLElement[]; const elements = Array.from(document.querySelectorAll(`.i18n`)) as HTMLElement[];
@ -280,6 +302,7 @@ namespace I18n {
rootScope.dispatchEvent('language_change', langPack.lang_code); rootScope.dispatchEvent('language_change', langPack.lang_code);
lastAppliedLangCode = langPack.lang_code; lastAppliedLangCode = langPack.lang_code;
cachedDateTimeFormats.clear(); cachedDateTimeFormats.clear();
updateAmPm();
} }
const elements = Array.from(document.querySelectorAll(`.i18n`)) as HTMLElement[]; const elements = Array.from(document.querySelectorAll(`.i18n`)) as HTMLElement[];
@ -414,17 +437,18 @@ namespace I18n {
export type IntlElementBaseOptions = { export type IntlElementBaseOptions = {
element?: HTMLElement, element?: HTMLElement,
property?: /* 'innerText' | */'innerHTML' | 'placeholder', property?: 'innerText' | 'innerHTML' | 'placeholder' | 'textContent',
}; };
abstract class IntlElementBase<Options extends IntlElementBaseOptions> { abstract class IntlElementBase<Options extends IntlElementBaseOptions> {
public element: IntlElementBaseOptions['element']; public element: IntlElementBaseOptions['element'];
public property: IntlElementBaseOptions['property'] = 'innerHTML'; public property: IntlElementBaseOptions['property'];
constructor(options?: Options) { constructor(options?: Options) {
this.element = options?.element || document.createElement('span'); this.element = options?.element || document.createElement('span');
this.element.classList.add('i18n'); this.element.classList.add('i18n');
this.property = options?.property;
if(options && ((options as any as IntlElementOptions).key || (options as any as IntlDateElementOptions).date)) { if(options && ((options as any as IntlElementOptions).key || (options as any as IntlDateElementOptions).date)) {
this.update(options); this.update(options);
} }
@ -443,6 +467,10 @@ namespace I18n {
public key: IntlElementOptions['key']; public key: IntlElementOptions['key'];
public args: IntlElementOptions['args']; public args: IntlElementOptions['args'];
constructor(options: IntlElementOptions = {}) {
super({...options, property: options.property ?? 'innerHTML'});
}
public update(options?: IntlElementOptions) { public update(options?: IntlElementOptions) {
safeAssign(this, options); safeAssign(this, options);
@ -480,6 +508,7 @@ namespace I18n {
return dateTimeFormat; return dateTimeFormat;
} }
export let amPmCache = {am: 'AM', pm: 'PM'};
export type IntlDateElementOptions = IntlElementBaseOptions & { export type IntlDateElementOptions = IntlElementBaseOptions & {
date?: Date, date?: Date,
options: Intl.DateTimeFormatOptions options: Intl.DateTimeFormatOptions
@ -488,15 +517,30 @@ namespace I18n {
public date: IntlDateElementOptions['date']; public date: IntlDateElementOptions['date'];
public options: IntlDateElementOptions['options']; public options: IntlDateElementOptions['options'];
constructor(options: IntlDateElementOptions) {
super({...options, property: options.property ?? 'textContent'});
}
public update(options?: IntlDateElementOptions) { public update(options?: IntlDateElementOptions) {
safeAssign(this, options); safeAssign(this, options);
//var options = { month: 'long', day: 'numeric' }; let text: string;
if(this.options.hour && this.options.minute && Object.keys(this.options).length === 2/* && false */) {
// * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/hourCycle#adding_an_hour_cycle_via_the_locale_string text = ('0' + this.date.getHours()).slice(-2) + ':' + ('0' + this.date.getMinutes()).slice(-2);
const dateTimeFormat = getDateTimeFormat(this.options); // if(this.options.second) {
// text += ':' + ('0' + this.date.getSeconds()).slice(-2);
(this.element as any)[this.property] = capitalizeFirstLetter(dateTimeFormat.format(this.date)); // }
if(timeFormat === 'h12') {
text += ' ' + (this.date.getHours() < 12 ? amPmCache.am : amPmCache.pm);
}
} else {
// * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Locale/hourCycle#adding_an_hour_cycle_via_the_locale_string
const dateTimeFormat = getDateTimeFormat(this.options);
text = capitalizeFirstLetter(dateTimeFormat.format(this.date));
}
(this.element as any)[this.property] = text;
} }
} }

Loading…
Cancel
Save