You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nostrweb/src/utils/time.ts

95 lines
2.3 KiB
TypeScript

/**
* throttle and debounce given function in regular time interval,
* but with the difference that the last call will be debounced and therefore never missed.
* @param {*} function to throttle and debounce
* @param {*} time desired interval to execute function
* @returns callback
*/
export const bounce = (
fn: () => void,
time: number,
) => {
let throttle: number | undefined;
let debounce: number | undefined;
return (/*...args*/) => {
if (throttle) {
clearTimeout(debounce);
debounce = setTimeout(() => fn(/*...args*/), time);
return;
}
fn(/*...args*/);
throttle = setTimeout(() => {
clearTimeout(throttle);
}, time);
};
};
/**
* Intl.DateTimeFormat object
*
* example:
*
* console.log(dateTime.format(new Date()));
*/
export const dateTime = new Intl.DateTimeFormat('de-ch' /* navigator.language */, {
dateStyle: 'medium',
timeStyle: 'short',
});
/**
* format time relative to now, such as 5min ago
*
* @param {Date} time
* @param {string} locale
* @returns string
*
* example:
*
* console.log(timeAgo(new Date(Date.now() - 10000)));
*
*/
const timeAgo = (
time: Date,
locale: string = 'en',
) => {
const relativeTime = new Intl.RelativeTimeFormat(locale, {
numeric: 'auto',
style: 'long',
});
const timeSince = (Date.now() - time.getTime()) * 0.001;
const minutes = Math.floor(timeSince / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const months = Math.floor(days / 30);
const years = Math.floor(months / 12);
if (years > 0) {
return relativeTime.format(0 - years, 'year');
} else if (months > 0) {
return relativeTime.format(0 - months, 'month');
} else if (days > 0) {
return relativeTime.format(0 - days, 'day');
} else if (hours > 0) {
return relativeTime.format(0 - hours, 'hour');
} else if (minutes > 0) {
return relativeTime.format(0 - minutes, 'minute');
} else {
return relativeTime.format(Math.round(0 - timeSince), 'second');
}
};
/**
* formatTime shows relative time if it is less than 24h else absolute datetime
*
* @param {time} date object to format
* @return string
*/
export const formatTime = (time: Date) => {
const yesterday = new Date(Date.now() - (24 * 60 * 60 * 1000));
if (time > yesterday) {
return timeAgo(time);
} else {
return dateTime.format(time);
};
};