From a99594b31878361c60bb5a81e3125a419b134f8a Mon Sep 17 00:00:00 2001 From: Supertiger Date: Sat, 2 Aug 2025 10:05:25 +0100 Subject: [PATCH] Add date-fns dependency and enhance Label and Clock modules for date formatting --- package.json | 1 + pnpm-lock.yaml | 8 ++++++ src/routes/waybar/Label.ts | 44 ++++++++++++++++++++++++++++-- src/routes/waybar/modules/clock.ts | 17 ++++++++---- src/routes/waybar/waybar.css | 1 + src/routes/waybar/waybar.ts | 37 ++++++++++++++----------- 6 files changed, 84 insertions(+), 24 deletions(-) diff --git a/package.json b/package.json index 719cfd3..929c9f8 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "dependencies": { "@adobe/css-tools": "^4.4.3", "@tbela99/css-parser": "^1.1.1", + "date-fns": "^4.1.0", "jsonc-parser": "^3.3.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a99234a..6296844 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@tbela99/css-parser': specifier: ^1.1.1 version: 1.1.1 + date-fns: + specifier: ^4.1.0 + version: 4.1.0 jsonc-parser: specifier: ^3.3.1 version: 3.3.1 @@ -292,6 +295,9 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + detect-libc@2.0.4: resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} engines: {node: '>=8'} @@ -601,6 +607,8 @@ snapshots: '@types/estree@1.0.8': {} + date-fns@4.1.0: {} + detect-libc@2.0.4: optional: true diff --git a/src/routes/waybar/Label.ts b/src/routes/waybar/Label.ts index d85691f..d9d6842 100644 --- a/src/routes/waybar/Label.ts +++ b/src/routes/waybar/Label.ts @@ -1,5 +1,6 @@ import type { Module } from "./createModule"; import { clamp, replaceTextWithUnicode } from "./utils"; +import { format as formatDate } from "date-fns"; interface LabelOpts { config?: { @@ -8,12 +9,15 @@ interface LabelOpts { states?: Record; "format-icons"?: string[]; }; + clickable?: boolean; + defaultFormat?: string; module: Module; interval?: number; update: () => void; } export const createLabel = (opts: LabelOpts) => { - let format = ""; + let alt = false; + let format = opts.defaultFormat || ""; const getFormat = () => { if (!opts.config) return undefined; @@ -36,8 +40,28 @@ export const createLabel = (opts: LabelOpts) => { console.error("No format found"); return "N/A"; } - const result = format.replace(/\{(\w+)\}/g, (match, key) => { - return data[key] !== undefined ? data[key] : match; + + const regex = /\{(\w+)\}|{:(.*?)}/g; + const result = format.replace(regex, (match, key, dateFmt) => { + if (key !== undefined) { + return data[key] !== undefined ? data[key] : match; + } + + if (dateFmt !== undefined) { + const now = new Date(); + + const convertedFormat = dateFmt + .replace(/%Y/g, "yyyy") + .replace(/%m/g, "MM") + .replace(/%d/g, "dd") + .replace(/%H/g, "HH") + .replace(/%M/g, "mm") + .replace(/%S/g, "ss"); + + return formatDate(now, convertedFormat); + } + + return match; }); element.innerHTML = replaceTextWithUnicode(result); @@ -83,6 +107,20 @@ export const createLabel = (opts: LabelOpts) => { return valid_state; }; + if (opts.clickable) { + element.style.cursor = "pointer"; + + element.onclick = () => { + alt = !alt; + if (alt && opts.config?.["format-alt"]) { + setFormat(opts.config?.["format-alt"]); + } else { + setFormat(opts.config?.format || opts.defaultFormat || ""); + } + opts.update(); + }; + } + return { element, set, diff --git a/src/routes/waybar/modules/clock.ts b/src/routes/waybar/modules/clock.ts index c3dc08f..a7a2b85 100644 --- a/src/routes/waybar/modules/clock.ts +++ b/src/routes/waybar/modules/clock.ts @@ -1,16 +1,23 @@ import type { WaybarConfig } from "../configParser"; import type { Module } from "../createModule"; +import { createLabel } from "../Label"; export const createClockModule = ( module: Module, config: WaybarConfig["clock"] ) => { - const update = () => { - const date = new Date(); + const label = createLabel({ + config, + module, + clickable: true, + update: () => update(), + defaultFormat: "{:%H:%M}", + interval: 1000, + }); - const hours = date.getHours().toString().padStart(2, "0"); - const minutes = date.getMinutes().toString().padStart(2, "0"); - module.element.innerHTML = `${hours}:${minutes}`; + module.element.appendChild(label.element); + const update = () => { + label.set({}); }; update(); diff --git a/src/routes/waybar/waybar.css b/src/routes/waybar/waybar.css index 7bcbad5..097670f 100644 --- a/src/routes/waybar/waybar.css +++ b/src/routes/waybar/waybar.css @@ -1,5 +1,6 @@ #waybar { display: flex; + user-select: none; } .modules { diff --git a/src/routes/waybar/waybar.ts b/src/routes/waybar/waybar.ts index dcc43ee..b53cc62 100644 --- a/src/routes/waybar/waybar.ts +++ b/src/routes/waybar/waybar.ts @@ -1,5 +1,5 @@ -import { parseConfig } from "./configParser"; -import { createModule } from "./createModule"; +import { parseConfig, type WaybarConfig } from "./configParser"; +import { createModule, type Module } from "./createModule"; import { modules, type ModuleArray, type Modules } from "./modules"; import "./waybar.css"; @@ -29,25 +29,30 @@ export const createWaybarPage = async () => { const moduleCenter = (config["modules-center"] as ModuleArray) || []; const moduleRight = (config["modules-right"] as ModuleArray) || []; + const loadModule = async ( + name: string, + createModuleBase: (name: string) => any, + loadIntoElement: HTMLElement, + config: WaybarConfig + ) => { + if (!modules[name as Modules]) { + console.error(`Module ${name} not found`); + return; + } + const module = createModuleBase(name); + loadIntoElement.appendChild(module.element); + const createModule = await modules[name as Modules]?.(); + + createModule(module, (config as any)[name]); + console.log(`Loaded module ${name}`); + }; + const loadModules = async ( enabledModules: ModuleArray, modulesElement: HTMLElement ) => { enabledModules.forEach(async (moduleName) => { - if (moduleName === "battery") { - console.log(moduleName); - const module = createModule("battery"); - modulesElement.appendChild(module.element); - const createBatteryModule = await modules.battery(); - createBatteryModule(module, config.battery); - } - if (moduleName === "clock") { - console.log(moduleName); - const module = createModule("clock"); - modulesElement.appendChild(module.element); - const createClockModule = await modules.clock(); - createClockModule(module, config.clock); - } + loadModule(moduleName, createModule, modulesElement, config); }); }; loadModules(moduleLeft, modulesLeftElement);