From ba2dbc660c229d3e86662d35513dfa7c904d9870 Mon Sep 17 00:00:00 2001 From: polwex Date: Sun, 23 Nov 2025 13:29:28 +0700 Subject: wew --- packages/tweetdeck/src/App.tsx | 311 ++--------------------------------------- 1 file changed, 8 insertions(+), 303 deletions(-) (limited to 'packages/tweetdeck/src/App.tsx') diff --git a/packages/tweetdeck/src/App.tsx b/packages/tweetdeck/src/App.tsx index 924ff9a..44b6405 100644 --- a/packages/tweetdeck/src/App.tsx +++ b/packages/tweetdeck/src/App.tsx @@ -1,310 +1,15 @@ -import { useCallback, useEffect, useMemo, useState } from "react"; -import "./styles/normalize.css"; import "./styles/index.css"; -import { Sidebar, type NewAccountInput } from "./components/Sidebar"; -import { ColumnBoard } from "./components/ColumnBoard"; -import { AddColumnModal } from "./components/AddColumnModal"; -import { usePersistentState } from "./hooks/usePersistentState"; -import type { - ColumnSnapshot, - ColumnState, - DeckAccount, - DeckColumn, - DeckListsCache, - FullscreenState, -} from "./types/app"; -import type { Tweet } from "./lib/fetching/types"; -import { generateId } from "./lib/utils/id"; -import { twitterClient } from "./lib/client/twitterClient"; -import { FullscreenColumn } from "./components/FullscreenColumn"; - -const ACCOUNTS_KEY = "tweetdeck.accounts"; -const COLUMNS_KEY = "tweetdeck.columns"; +import "./styles/normalize.css"; +import { Toaster } from "react-hot-toast"; +import Deck from "./pages/Deck"; +import Test from "./Test"; export function App() { - const [accounts, setAccounts] = usePersistentState( - ACCOUNTS_KEY, - [], - ); - const [columns, setColumns] = usePersistentState( - COLUMNS_KEY, - [], - ); - const [listsCache, setListsCache] = useState({}); - const [activeAccountId, setActiveAccountId] = useState( - () => accounts[0]?.id, - ); - const [isModalOpen, setModalOpen] = useState(false); - const [toast, setToast] = useState(null); - const [fullscreen, setFullscreen] = useState(null); - const [columnSnapshots, setColumnSnapshots] = useState< - Record - >({}); - - useEffect(() => { - if (!activeAccountId) { - const firstAccount = accounts[0]; - if (firstAccount) { - setActiveAccountId(firstAccount.id); - } - } - }, [accounts, activeAccountId]); - - useEffect(() => { - const acs = accounts.filter((a) => !a.avatar || !a.username); - console.log({ acs }); - const nacs = acs.map(async (acc) => { - const our = await twitterClient.own({ cookie: acc.cookie }); - const nacc = { - ...acc, - handle: our.username, - label: our.name, - avatar: our.avatar, - }; - return nacc; - }); - Promise.all(nacs) - .then((acs) => setAccounts(acs)) - .catch((err) => console.error(err)); - }, []); - - const handleAddAccount = useCallback( - (payload: NewAccountInput) => { - const label = `Session ${accounts.length + 1}`; - const account: DeckAccount = { - id: generateId(), - label, - accent: randomAccent(), - cookie: payload.cookie.trim(), - createdAt: Date.now(), - }; - setAccounts((prev) => [...prev, account]); - setActiveAccountId(account.id); - setToast(`${account.label} is ready`); - }, - [accounts.length, setAccounts], - ); - - const handleRemoveAccount = useCallback( - (accountId: string) => { - setAccounts((prev) => prev.filter((account) => account.id !== accountId)); - setColumns((prev) => - prev.filter((column) => column.accountId !== accountId), - ); - setListsCache((prev) => { - const next = { ...prev }; - delete next[accountId]; - return next; - }); - if (activeAccountId === accountId) { - setActiveAccountId(undefined); - } - }, - [activeAccountId, setAccounts, setColumns], - ); - - const handleAddColumn = useCallback( - (column: Omit) => { - const nextColumn = { ...column, id: generateId() }; - setColumns((prev) => [...prev, nextColumn]); - setToast(`${nextColumn.title} added to deck`); - }, - [setColumns], - ); - - const handleRemoveColumn = useCallback( - (id: string) => { - setColumns((prev) => prev.filter((column) => column.id !== id)); - }, - [setColumns], - ); - - const fetchLists = useCallback( - async (accountId: string) => { - const account = accounts.find((acc) => acc.id === accountId); - if (!account) throw new Error("Account not found"); - if (listsCache[accountId]) return listsCache[accountId]; - console.log({ listsCache }); - const lists = await twitterClient.lists({ cookie: account.cookie }); - console.log({ lists }); - setListsCache((prev) => ({ ...prev, [accountId]: lists })); - return lists; - }, - [accounts, listsCache], - ); - - const handleColumnStateChange = useCallback( - (columnId: string, state: ColumnState) => { - setColumns((prev) => - prev.map((column) => - column.id === columnId ? { ...column, state } : column, - ), - ); - }, - [setColumns], - ); - - const handleColumnSnapshot = useCallback( - (columnId: string, snapshot: ColumnSnapshot) => { - setColumnSnapshots((prev) => { - const existing = prev[columnId]; - if ( - existing && - existing.tweets === snapshot.tweets && - existing.label === snapshot.label - ) { - return prev; - } - return { - ...prev, - [columnId]: { tweets: snapshot.tweets, label: snapshot.label }, - }; - }); - }, - [], - ); - - const openFullscreen = useCallback( - (payload: FullscreenState) => { - const snapshot = columnSnapshots[payload.column.id]; - setFullscreen({ - ...payload, - tweets: snapshot?.tweets ?? payload.tweets, - columnLabel: snapshot?.label ?? payload.columnLabel, - }); - }, - [columnSnapshots], - ); - - useEffect(() => { - if (!fullscreen) return; - const snapshot = columnSnapshots[fullscreen.column.id]; - if (!snapshot) return; - if ( - snapshot.tweets === fullscreen.tweets && - snapshot.label === fullscreen.columnLabel - ) { - return; - } - setFullscreen((prev) => { - if (!prev) return prev; - if (prev.column.id !== fullscreen.column.id) return prev; - const tweets = snapshot.tweets; - const index = Math.min(prev.index, Math.max(tweets.length - 1, 0)); - return { - ...prev, - tweets, - columnTitle: snapshot.label, - index, - }; - }); - }, [columnSnapshots, fullscreen]); - - const content = useMemo( - () => ( - - ), - [ - accounts, - columns, - handleRemoveColumn, - handleColumnStateChange, - handleColumnSnapshot, - openFullscreen, - ], - ); - return ( -
- setActiveAccountId(id)} - onAddAccount={handleAddAccount} - onRemoveAccount={handleRemoveAccount} - onAddColumn={() => setModalOpen(true)} - /> - -
{content}
- - setModalOpen(false)} - onAdd={handleAddColumn} - fetchLists={fetchLists} - listsCache={listsCache} - /> - - {toast && ( -
setToast(null)}> - {toast} -
- )} - - {fullscreen && ( - setFullscreen(null)} - onNavigate={(step) => { - setFullscreen((prev) => { - if (!prev) return prev; - if (!prev.tweets.length) return prev; - const nextIndex = Math.min( - prev.tweets.length - 1, - Math.max(0, prev.index + step), - ); - if (nextIndex === prev.index) return prev; - return { ...prev, index: nextIndex }; - }); - }} - hasPrevColumn={fullscreen.columnIndex > 0} - hasNextColumn={fullscreen.columnIndex < columns.length - 1} - onSwitchColumn={(direction) => { - setFullscreen((prev) => { - if (!prev) return prev; - const nextIndex = prev.columnIndex + direction; - if (nextIndex < 0) return prev; - if (nextIndex >= columns.length) { - setModalOpen(true); - return prev; - } - const nextColumn = columns[nextIndex]; - if (!nextColumn) return prev; - const snapshot = columnSnapshots[nextColumn.id]; - const account = accounts.find( - (acc) => acc.id === nextColumn.accountId, - ); - const tweets = snapshot?.tweets ?? []; - return { - column: nextColumn, - columnIndex: nextIndex, - columnLabel: snapshot?.label ?? nextColumn.title, - accent: account?.accent ?? prev.accent, - tweets, - index: 0, - }; - }); - }} - onAddColumn={() => setModalOpen(true)} - /> - )} -
+ <> + + + ); } - -function randomAccent(): string { - const palette = ["#7f5af0", "#2cb67d", "#f25f4c", "#f0a500", "#19a7ce"]; - const pick = palette[Math.floor(Math.random() * palette.length)]; - return pick ?? "#7f5af0"; -} - export default App; -- cgit v1.2.3