mirror of
https://github.com/badges/shields.git
synced 2025-04-18 19:44:04 +03:00
* add and consistently use parseDate and renderDateBadge helpers also move - age - formatDate - formatRelativeDate to date.js * fix bug in wordpress last update badge * validate in formatDate() and age() it is going to be unlikely we'll invoke either of these directly now, but lets calidate here too * remove unusued imports * reverse colours for galaxy toolshed
109 lines
3.5 KiB
JavaScript
109 lines
3.5 KiB
JavaScript
/**
|
|
* Commonly-used functions for rendering badges containing a date
|
|
*
|
|
* @module
|
|
*/
|
|
|
|
import dayjs from 'dayjs'
|
|
import calendar from 'dayjs/plugin/calendar.js'
|
|
import customParseFormat from 'dayjs/plugin/customParseFormat.js'
|
|
import { colorScale } from './color-formatters.js'
|
|
import { InvalidResponse } from './index.js'
|
|
|
|
dayjs.extend(calendar)
|
|
dayjs.extend(customParseFormat)
|
|
|
|
/**
|
|
* Parse and validate a string date into a dayjs object. Use this helper
|
|
* in preference to invoking dayjs directly when parsing a date from string.
|
|
*
|
|
* @param {...any} args - Variadic: Arguments to pass through to dayjs
|
|
* @returns {dayjs} - Parsed object
|
|
* @throws {InvalidResponse} - Error if validation fails
|
|
* @see https://day.js.org/docs/en/parse/string
|
|
* @see https://day.js.org/docs/en/parse/string-format
|
|
* @see https://day.js.org/docs/en/parse/is-valid
|
|
* @example
|
|
* parseDate('2024-01-01')
|
|
* parseDate('31/01/2024', 'DD/MM/YYYY')
|
|
* parseDate('2018 Enero 15', 'YYYY MMMM DD', 'es')
|
|
*/
|
|
function parseDate(...args) {
|
|
let date
|
|
if (args.length >= 2) {
|
|
// always use strict mode if format arg is supplied
|
|
date = dayjs(...args, true)
|
|
} else {
|
|
date = dayjs(...args)
|
|
}
|
|
if (!date.isValid()) {
|
|
throw new InvalidResponse({ prettyMessage: 'invalid date' })
|
|
}
|
|
return date
|
|
}
|
|
|
|
/**
|
|
* Returns a formatted date string without the year based on the value of input date param d.
|
|
*
|
|
* @param {Date | string | number | dayjs } d JS Date object, string, unix timestamp or dayjs object
|
|
* @returns {string} Formatted date string
|
|
*/
|
|
function formatDate(d) {
|
|
const date = parseDate(d)
|
|
const dateString = date.calendar(null, {
|
|
lastDay: '[yesterday]',
|
|
sameDay: '[today]',
|
|
lastWeek: '[last] dddd',
|
|
sameElse: 'MMMM YYYY',
|
|
})
|
|
// Trim current year from date string
|
|
return dateString.replace(` ${dayjs().year()}`, '').toLowerCase()
|
|
}
|
|
|
|
/**
|
|
* Determines the color used for a badge according to the age.
|
|
* Age is calculated as days elapsed till current date.
|
|
* The color varies from bright green to red as the age increases
|
|
* or the other way around if `reverse` is given `true`.
|
|
*
|
|
* @param {Date | string | number | dayjs } date JS Date object, string, unix timestamp or dayjs object
|
|
* @param {boolean} reversed Reverse the color scale (the older, the better)
|
|
* @returns {string} Badge color
|
|
*/
|
|
function age(date, reversed = false) {
|
|
const colorByAge = colorScale([7, 30, 180, 365, 730], undefined, !reversed)
|
|
const daysElapsed = dayjs().diff(parseDate(date), 'days')
|
|
return colorByAge(daysElapsed)
|
|
}
|
|
|
|
/**
|
|
* Creates a badge object that displays a date
|
|
*
|
|
* @param {Date | string | number | dayjs } date JS Date object, string, unix timestamp or dayjs object
|
|
* @param {boolean} reversed Reverse the color scale (the older, the better)
|
|
* @returns {object} A badge object that has two properties: message, and color
|
|
*/
|
|
function renderDateBadge(date, reversed = false) {
|
|
const d = parseDate(date)
|
|
const color = age(d, reversed)
|
|
const message = formatDate(d)
|
|
return { message, color }
|
|
}
|
|
|
|
/**
|
|
* Returns a relative date from the input timestamp.
|
|
* For example, day after tomorrow's timestamp will return 'in 2 days'.
|
|
*
|
|
* @param {number | string} timestamp - Unix timestamp
|
|
* @returns {string} Relative date from the unix timestamp
|
|
*/
|
|
function formatRelativeDate(timestamp) {
|
|
const parsedDate = dayjs.unix(parseInt(timestamp, 10))
|
|
if (!parsedDate.isValid()) {
|
|
return 'invalid date'
|
|
}
|
|
return dayjs().to(parsedDate).toLowerCase()
|
|
}
|
|
|
|
export { parseDate, renderDateBadge, formatDate, formatRelativeDate, age }
|