import { createEffect, createSignal } from "solid-js"; import { type Dayjs } from "dayjs"; import type { Handler } from "mdast-util-to-hast"; import { Plugin } from "unified"; import { visit } from "unist-util-visit"; import { dayjs, timeLocale } from "@revolt/i18n/dayjs"; import { time as Time } from "../elements"; export function RenderTimestamp(props: { format: string; date: Dayjs }) { /** * Format a time string */ function format() { switch (props.format) { case "t": return props.date.format("hh:mm"); case "T": return props.date.format("hh:mm:ss"); case "R": return props.date.fromNow(); case "D": return props.date.format("DD MMMM YYYY"); case "F": return props.date.format("dddd, DD MMMM YYYY hh:mm"); default: return props.date.format("DD MMMM YYYY hh:mm"); } } // Signal for current value const [value, setValue] = createSignal(format()); const update = () => setValue(format()); createEffect(() => { // Update every second if we are rendering relative time if (props.format === "R") { const interval = setInterval(update, 1000); return () => clearInterval(interval); } }); return ( ); } /** * Regex for matching timestamps */ export const RE_TIMESTAMP = //g; export const remarkTimestamps: Plugin = () => (tree) => { visit( tree, "text", ( node: { type: "text"; value: string }, idx, parent: { children: unknown[] }, ) => { const elements = node.value.split(RE_TIMESTAMP); if (elements.length === 1) return; // no matches // Generate initial node const newNodes: ( | { type: "text"; value: string } | { type: "timestamp"; format: string; date: Dayjs; } )[] = [ { type: "text", value: elements.shift()!, }, ]; // Process all timestamps for (let i = 0; i < elements.length / 3; i++) { // Process timestamp const date = dayjs .unix(parseInt(elements[i * 3])) .locale(timeLocale()[1]); // Insert components newNodes.push({ type: "timestamp", format: elements[i * 3 + 1], date, }); newNodes.push({ type: "text", value: elements[i * 3 + 2], }); } parent.children.splice(idx, 1, ...newNodes); return idx + newNodes.length; }, ); }; export const timestampHandler: Handler = (h, node) => { return { type: "element" as const, tagName: "timestamp", children: [], properties: { format: node.format, date: node.date, }, }; };