import type { SessionMetadata } from "@jaeswift/jae-web-ui"; import { html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators.js"; @customElement("jae-session-sidebar") export class JaeSessionSidebar extends LitElement { @property({ type: Boolean }) collapsed = false; @property({ type: String }) currentSessionId: string | undefined = undefined; @property({ attribute: false }) onLoadSession?: (id: string) => void; @property({ attribute: false }) onNewSession?: () => void; @state() private _sessions: SessionMetadata[] = []; @state() private _pinnedIds: Set = new Set(); @state() private _confirmDelete: string | null = null; protected override createRenderRoot() { return this; } override connectedCallback() { super.connectedCallback(); const raw = localStorage.getItem("jae-pinned-sessions"); if (raw) { try { this._pinnedIds = new Set(JSON.parse(raw)); } catch {} } } setSessions(sessions: SessionMetadata[]) { this._sessions = [...sessions]; this.requestUpdate(); } private _togglePin(e: Event, id: string) { e.stopPropagation(); const s = new Set(this._pinnedIds); s.has(id) ? s.delete(id) : s.add(id); this._pinnedIds = s; localStorage.setItem("jae-pinned-sessions", JSON.stringify([...s])); this.requestUpdate(); } private _deleteSession(e: Event, id: string) { e.stopPropagation(); if (this._confirmDelete === id) { this._confirmDelete = null; this.dispatchEvent(new CustomEvent("delete-session", { detail: id, bubbles: true, composed: true })); } else { this._confirmDelete = id; this.requestUpdate(); setTimeout(() => { this._confirmDelete = null; this.requestUpdate(); }, 3000); } } private _fmt(iso: string) { const ms = Date.now() - new Date(iso).getTime(); if (ms < 60000) return "just now"; if (ms < 3600000) return Math.floor(ms / 60000) + "m ago"; if (ms < 86400000) return Math.floor(ms / 3600000) + "h ago"; if (ms < 604800000) return Math.floor(ms / 86400000) + "d ago"; return new Date(iso).toLocaleDateString(); } override render() { if (this.collapsed) return html``; const pinned = this._sessions .filter((s) => this._pinnedIds.has(s.id)) .sort((a, b) => b.lastModified.localeCompare(a.lastModified)); const rest = this._sessions .filter((s) => !this._pinnedIds.has(s.id)) .sort((a, b) => b.lastModified.localeCompare(a.lastModified)); const sorted = [...pinned, ...rest]; return html`
Chats
${ sorted.length === 0 ? html`
💬
No chats yet
` : sorted.map( (s) => html`
this.onLoadSession?.(s.id)}> ${ this._pinnedIds.has(s.id) ? html`
` : html`` }
${s.title || "Untitled"}
${this._fmt(s.lastModified)}
`, ) }
${sorted.length} chat${sorted.length !== 1 ? "s" : ""}
`; } }