forked from BasedHardware/omi
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.ts
More file actions
125 lines (106 loc) · 2.95 KB
/
Copy pathutils.ts
File metadata and controls
125 lines (106 loc) · 2.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
import { type ClassValue, clsx } from 'clsx';
import { twMerge } from 'tailwind-merge';
/**
* Merge Tailwind CSS classes with clsx
*/
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs));
}
/**
* Format duration in seconds to a human-readable string
* e.g., 323 -> "5m 23s"
*/
export function formatDuration(seconds: number): string {
if (seconds < 60) {
return `${seconds}s`;
}
const minutes = Math.floor(seconds / 60);
const remainingSeconds = seconds % 60;
if (minutes < 60) {
return remainingSeconds > 0 ? `${minutes}m ${remainingSeconds}s` : `${minutes}m`;
}
const hours = Math.floor(minutes / 60);
const remainingMinutes = minutes % 60;
if (remainingMinutes > 0) {
return `${hours}h ${remainingMinutes}m`;
}
return `${hours}h`;
}
/**
* Format a date to relative time (Today, Yesterday, or date string)
*/
export function formatRelativeDate(date: Date): string {
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
const inputDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
if (inputDate.getTime() === today.getTime()) {
return 'Today';
}
if (inputDate.getTime() === yesterday.getTime()) {
return 'Yesterday';
}
// Format as "Mon, Jan 15"
return date.toLocaleDateString('en-US', {
weekday: 'short',
month: 'short',
day: 'numeric',
});
}
/**
* Format time to 12-hour format (e.g., "2:30 PM")
*/
export function formatTime(date: Date): string {
return date.toLocaleTimeString('en-US', {
hour: 'numeric',
minute: '2-digit',
hour12: true,
});
}
/**
* Format notification timestamp with time (e.g., "2:30 PM" for today, "Yesterday 2:30 PM", or "Jan 15, 2:30 PM")
*/
export function formatNotificationTimestamp(date: Date): string {
const now = new Date();
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const yesterday = new Date(today);
yesterday.setDate(yesterday.getDate() - 1);
const inputDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
const timeStr = date.toLocaleTimeString('en-US', {
hour: 'numeric',
minute: '2-digit',
hour12: true,
});
if (inputDate.getTime() === today.getTime()) {
return timeStr;
}
if (inputDate.getTime() === yesterday.getTime()) {
return `Yesterday ${timeStr}`;
}
// Format as "Jan 15, 2:30 PM"
const dateStr = date.toLocaleDateString('en-US', {
month: 'short',
day: 'numeric',
});
return `${dateStr}, ${timeStr}`;
}
/**
* Group items by a key function
*/
export function groupBy<T, K extends string>(
items: T[],
getKey: (item: T) => K
): Record<K, T[]> {
return items.reduce(
(result, item) => {
const key = getKey(item);
if (!result[key]) {
result[key] = [];
}
result[key].push(item);
return result;
},
{} as Record<K, T[]>
);
}