diff options
Diffstat (limited to 'packages/tweetdeck/src/components/FullscreenColumn.tsx')
| -rw-r--r-- | packages/tweetdeck/src/components/FullscreenColumn.tsx | 134 |
1 files changed, 134 insertions, 0 deletions
diff --git a/packages/tweetdeck/src/components/FullscreenColumn.tsx b/packages/tweetdeck/src/components/FullscreenColumn.tsx new file mode 100644 index 0000000..66959b8 --- /dev/null +++ b/packages/tweetdeck/src/components/FullscreenColumn.tsx @@ -0,0 +1,134 @@ +import { useEffect } from "react"; +import type { FullscreenState } from "../types/app"; +import { TweetCard } from "./TweetCard"; + +interface FullscreenColumnProps { + state: FullscreenState; + onExit: () => void; + onNavigate: (step: number) => void; + onSwitchColumn: (step: number) => void; + hasPrevColumn: boolean; + hasNextColumn: boolean; + onAddColumn: () => void; +} + +export function FullscreenColumn({ + state, + onExit, + onNavigate, + onSwitchColumn, + hasPrevColumn, + hasNextColumn, + onAddColumn, +}: FullscreenColumnProps) { + console.log({ state }); + const tweet = state.tweets[state.index]; + const hasTweets = state.tweets.length > 0; + + useEffect(() => { + const handler = (event: KeyboardEvent) => { + if (event.key === "Escape") { + onExit(); + return; + } + if (event.key === "ArrowDown") { + event.preventDefault(); + onNavigate(1); + } + if (event.key === "ArrowUp") { + event.preventDefault(); + onNavigate(-1); + } + if (event.key === "ArrowRight") { + event.preventDefault(); + if (hasNextColumn) { + onSwitchColumn(1); + } else { + onAddColumn(); + } + } + if (event.key === "ArrowLeft") { + event.preventDefault(); + if (hasPrevColumn) { + onSwitchColumn(-1); + } + } + }; + window.addEventListener("keydown", handler); + return () => window.removeEventListener("keydown", handler); + }, [ + onExit, + onNavigate, + onSwitchColumn, + hasPrevColumn, + hasNextColumn, + onAddColumn, + ]); + + return ( + <div className="fullscreen-overlay"> + <button + className="ghost fullscreen-close" + onClick={onExit} + aria-label="Close fullscreen view" + > + × + </button> + <div className="fullscreen-content"> + <header> + <p className="eyebrow"> + {state.columnLabel}@{state.column.account} + </p> + <p className="muted tiny"> + {hasTweets + ? `${state.index + 1} / ${state.tweets.length}` + : "0 / 0"} + </p> + </header> + <div className="fullscreen-card"> + {hasTweets && tweet ? ( + <TweetCard tweet={tweet} accent={state.accent} /> + ) : ( + <div className="fullscreen-empty"> + <p>No tweets loaded for this column yet.</p> + <p className="muted"> + Try refreshing the column or exit fullscreen. + </p> + </div> + )} + </div> + <div className="fullscreen-controls"> + <button + className="ghost" + onClick={() => onNavigate(-1)} + disabled={!hasTweets || state.index === 0} + > + ↑ Previous tweet + </button> + <button + className="ghost" + onClick={() => onNavigate(1)} + disabled={!hasTweets || state.index >= state.tweets.length - 1} + > + Next tweet ↓ + </button> + </div> + <div className="fullscreen-column-controls"> + <button + className="ghost" + onClick={() => onSwitchColumn(-1)} + disabled={!hasPrevColumn} + > + ← Previous column + </button> + <button + className="ghost" + onClick={() => (hasNextColumn ? onSwitchColumn(1) : onAddColumn())} + > + {hasNextColumn ? "Next column →" : "+ Add column →"} + </button> + </div> + </div> + </div> + ); +} |
