From cb1b56f5a0eddbf77446f415f2beda57c8305f85 Mon Sep 17 00:00:00 2001
From: polwex <polwex@sortug.com>
Date: Sun, 23 Nov 2025 01:12:53 +0700
Subject: wut

---
 packages/tweetdeck/src/components/ChatColumn.tsx | 62 ++++++++++++++++++++++++
 1 file changed, 62 insertions(+)
 create mode 100644 packages/tweetdeck/src/components/ChatColumn.tsx

(limited to 'packages/tweetdeck/src/components/ChatColumn.tsx')

diff --git a/packages/tweetdeck/src/components/ChatColumn.tsx b/packages/tweetdeck/src/components/ChatColumn.tsx
new file mode 100644
index 0000000..0c336e5
--- /dev/null
+++ b/packages/tweetdeck/src/components/ChatColumn.tsx
@@ -0,0 +1,62 @@
+import { useCallback, useEffect, useState } from "react";
+import type { DeckAccount, DeckColumn, ChatState } from "../types/app";
+import { twitterClient } from "../lib/client/twitterClient";
+import { ChatCard } from "./ChatCard";
+
+interface ChatColumnProps {
+  column: DeckColumn & { kind: "chat" };
+  account: DeckAccount;
+  onRemove: () => void;
+}
+
+export function ChatColumn({ column, account, onRemove }: ChatColumnProps) {
+  const [state, setState] = useState<ChatState>({ entries: [], isLoading: false });
+  const [error, setError] = useState<string | undefined>();
+
+  const refresh = useCallback(async () => {
+    setState(prev => ({ ...prev, isLoading: true }));
+    setError(undefined);
+    try {
+      const notifications = await twitterClient.notifications({ cookie: account.cookie });
+      setState({ entries: notifications, isLoading: false });
+    } catch (err) {
+      setError(err instanceof Error ? err.message : "Failed to refresh chat");
+      setState(prev => ({ ...prev, isLoading: false }));
+    }
+  }, [account.cookie]);
+
+  useEffect(() => {
+    refresh();
+  }, [refresh, account.id]);
+
+  return (
+    <article className="column">
+      <header>
+        <div>
+          <p className="eyebrow">Signal</p>
+          <h3>{column.title || "Chat"}</h3>
+          <p className="muted tiny">Mentions, follows and notifications for {account.label}</p>
+        </div>
+        <div className="column-actions">
+          <button className="ghost" onClick={refresh} aria-label="Refresh chat">
+            ↻
+          </button>
+          <button className="ghost" onClick={onRemove} aria-label="Remove column">
+            ×
+          </button>
+        </div>
+      </header>
+      {error && <p className="error">{error}</p>}
+      {state.isLoading && !state.entries.length ? (
+        <div className="column-loading">Loading…</div>
+      ) : (
+        <div className="chat-stack">
+          {state.entries.map(entry => (
+            <ChatCard key={entry.id} notification={entry} accent={account.accent} />
+          ))}
+          {!state.entries.length && <p className="muted">No recent notifications.</p>}
+        </div>
+      )}
+    </article>
+  );
+}
-- 
cgit v1.2.3

