UNPKG

create-fluxstack

Version:

⚡ Revolutionary full-stack TypeScript framework with Declarative Config System, Elysia + React + Bun

215 lines (177 loc) 6.03 kB
// 🔥 LiveClock - Real-time Clock Live Component // Automatically updates every second and broadcasts to all connected clients import { LiveComponent } from "@/core/types/types"; interface LiveClockState { currentTime: string; // Formatted time string timeZone: string; // IANA timezone (e.g., 'America/Sao_Paulo') format: '12h' | '24h'; // Time format preference showSeconds: boolean; // Toggle seconds display showDate: boolean; // Toggle date display lastSync: Date; // Last sync timestamp serverUptime: number; // Server uptime in seconds } export class LiveClockComponent extends LiveComponent<LiveClockState> { private clockInterval: NodeJS.Timeout | null = null; private startTime: Date; constructor(initialState: LiveClockState, ws: any, options?: { room?: string; userId?: string }) { const now = new Date(); super({ currentTime: now.toLocaleTimeString('pt-BR'), timeZone: 'America/Sao_Paulo', format: '24h', showSeconds: true, showDate: true, lastSync: now, serverUptime: 0, ...initialState }, ws, options); this.startTime = now; console.log(`🕐 ${this.constructor.name} created: ${this.id}`); // Start the real-time clock immediately this.startClock(); } private startClock() { // Clear any existing interval if (this.clockInterval) { clearInterval(this.clockInterval); } // Update clock every second this.clockInterval = setInterval(() => { this.updateClock(); }, 1000); // Initial update this.updateClock(); } private updateClock() { const now = new Date(); const uptimeMs = now.getTime() - this.startTime.getTime(); let timeString; if (this.state.format === '12h') { timeString = now.toLocaleTimeString('en-US', { hour12: true, hour: 'numeric', minute: '2-digit', second: this.state.showSeconds ? '2-digit' : undefined }); } else { timeString = now.toLocaleTimeString('pt-BR', { hour12: false, hour: '2-digit', minute: '2-digit', second: this.state.showSeconds ? '2-digit' : undefined }); } this.setState({ currentTime: timeString, lastSync: now, serverUptime: Math.floor(uptimeMs / 1000) }); // Broadcast time update to all connected clients if (this.room) { this.broadcast('CLOCK_TICK', { currentTime: timeString, timestamp: now.toISOString(), serverUptime: Math.floor(uptimeMs / 1000) }); } } async setTimeFormat(payload: { format: '12h' | '24h' }) { const { format } = payload; if (format !== '12h' && format !== '24h') { throw new Error('Invalid time format. Use "12h" or "24h"'); } this.setState({ format, lastSync: new Date() }); // Immediately update the clock display with new format this.updateClock(); console.log(`🕐 Time format changed to: ${format}`); return { success: true, format }; } async toggleSeconds(payload?: { showSeconds?: boolean }) { const showSeconds = payload?.showSeconds ?? !this.state.showSeconds; this.setState({ showSeconds, lastSync: new Date() }); // Update clock display immediately this.updateClock(); console.log(`🕐 Seconds display: ${showSeconds ? 'ON' : 'OFF'}`); return { success: true, showSeconds }; } async toggleDate(payload?: { showDate?: boolean }) { const showDate = payload?.showDate ?? !this.state.showDate; this.setState({ showDate, lastSync: new Date() }); console.log(`🕐 Date display: ${showDate ? 'ON' : 'OFF'}`); return { success: true, showDate }; } async setTimeZone(payload: { timeZone: string }) { const { timeZone } = payload; // Basic timezone validation try { new Date().toLocaleString('en-US', { timeZone }); } catch (error) { throw new Error(`Invalid timezone: ${timeZone}`); } this.setState({ timeZone, lastSync: new Date() }); console.log(`🕐 Timezone changed to: ${timeZone}`); return { success: true, timeZone }; } async getServerInfo() { console.log(`🕐 getServerInfo called for component: ${this.id}`); const now = new Date(); const uptimeMs = now.getTime() - this.startTime.getTime(); const result = { success: true, info: { serverTime: now.toISOString(), localTime: now.toLocaleString('pt-BR'), uptime: Math.floor(uptimeMs / 1000), uptimeFormatted: this.formatUptime(Math.floor(uptimeMs / 1000)), timezone: this.state.timeZone, componentId: this.id, startTime: this.startTime.toISOString() } }; console.log(`🕐 getServerInfo result:`, result); return result; } async syncTime() { // Force a manual time sync this.updateClock(); console.log(`🕐 Manual time sync performed`); return { success: true, syncTime: new Date().toISOString(), currentTime: this.state.currentTime }; } private formatUptime(seconds: number): string { const hours = Math.floor(seconds / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = seconds % 60; if (hours > 0) { return `${hours}h ${minutes}m ${secs}s`; } else if (minutes > 0) { return `${minutes}m ${secs}s`; } else { return `${secs}s`; } } public destroy() { // Clean up the interval when component is destroyed if (this.clockInterval) { clearInterval(this.clockInterval); this.clockInterval = null; console.log(`🕐 Clock interval cleared for component: ${this.id}`); } super.destroy(); } }