2026-06-01 16:42:36 +07:00
|
|
|
import { type ClassValue, clsx } from "clsx";
|
2026-05-16 19:17:34 +07:00
|
|
|
import { twMerge } from "tailwind-merge";
|
|
|
|
|
|
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
|
|
|
return twMerge(clsx(inputs));
|
|
|
|
|
}
|
2026-06-02 21:06:42 +07:00
|
|
|
|
|
|
|
|
export function formatBytes(bytes: number): string {
|
|
|
|
|
if (bytes === 0) return "0 Bytes";
|
|
|
|
|
const k = 1024;
|
|
|
|
|
const sizes = ["Bytes", "KB", "MB", "GB"];
|
|
|
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
|
|
|
return `${Math.round((bytes / Math.pow(k, i)) * 100) / 100} ${sizes[i]}`;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function formatDate(value: number): string {
|
|
|
|
|
return new Date(value).toLocaleString();
|
|
|
|
|
}
|
2026-06-16 22:44:28 +07:00
|
|
|
|
|
|
|
|
export interface MessageMetadata {
|
|
|
|
|
stickers?: Array<{ name?: string; url?: string }>;
|
|
|
|
|
attachments?: Array<{ name: string; url: string; contentType?: string }>;
|
|
|
|
|
embeds?: Array<{ title?: string; image?: string; thumbnail?: string }>;
|
|
|
|
|
channel?: {
|
|
|
|
|
channelId: string;
|
|
|
|
|
channelName?: string;
|
|
|
|
|
threadId?: string;
|
|
|
|
|
threadName?: string;
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function parseMetadata(value: string | null): MessageMetadata {
|
|
|
|
|
if (!value) return {};
|
|
|
|
|
try {
|
|
|
|
|
const parsed = JSON.parse(value) as MessageMetadata;
|
|
|
|
|
return parsed;
|
|
|
|
|
} catch {
|
|
|
|
|
return {};
|
|
|
|
|
}
|
|
|
|
|
}
|