Image Generation Refactor: - MessageInput: add onImageGenerate callback, remove skill fetch dependency - ChatView: implement handleImageGenerate that creates image-gen-request message for ImageGenConfirmation UI, then user selects params and generates - New API route POST /api/chat/messages for DB-only message persistence - image-gen-completed event now only persists notice to DB, no longer triggers model - Reference images passed via module-level Map (imageGenRefStore) to avoid DB bloat from base64 data; user message DB content stores metadata only Bug Fixes: - Fix useCallback dependency missing imageGen causing stale closure reads - Fix React Hooks order violation in MessageItem (early return before hooks) - Fix localStorage cache collision across sessions (key now includes sessionId) - Fix empty src attribute in FileAttachmentDisplay for DB-restored messages - Add JSON parse fallback for malformed image-gen-request blocks Gallery Reference Images: - /api/media/generate saves reference images to disk, stores paths in metadata - /api/media/gallery extracts referenceImages from metadata in mapRow - GalleryDetail displays reference image thumbnails - ImageGenCard supports referenceImages prop for chat display UI Changes: - ImageGenToggle: replace paint brush icon with text label (en: Image, zh: 生图) - Model selector button: remove provider name display to save space - ImageGenConfirmation: support referenceImagesData prop for base64 preview i18n: - Add imageGen.toggleLabel key (en: Image, zh: 生图)
25 lines
869 B
TypeScript
25 lines
869 B
TypeScript
import { clsx, type ClassValue } from "clsx"
|
|
import { twMerge } from "tailwind-merge"
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs))
|
|
}
|
|
|
|
/**
|
|
* Parse a date string from the database as UTC.
|
|
*
|
|
* DB timestamps are stored as UTC but without timezone indicator
|
|
* (e.g. "2026-02-26 07:23:45"). `new Date()` would misinterpret
|
|
* these as local time. This helper normalises the string so the
|
|
* browser always treats it as UTC.
|
|
*/
|
|
export function parseDBDate(dateStr: string): Date {
|
|
if (!dateStr) return new Date(0);
|
|
// Already has timezone info (ISO with Z or offset) — parse as-is
|
|
if (dateStr.includes('Z') || dateStr.includes('+') || /T\d{2}:\d{2}:\d{2}[+-]/.test(dateStr)) {
|
|
return new Date(dateStr);
|
|
}
|
|
// DB format "YYYY-MM-DD HH:mm:ss" — append Z to mark as UTC
|
|
return new Date(dateStr.replace(' ', 'T') + 'Z');
|
|
}
|