From 9ab1964cac0e6b292ff9b7bf86eec75f879091ec Mon Sep 17 00:00:00 2001 From: Todd Riley Date: Wed, 24 Sep 2025 13:22:52 -0400 Subject: [PATCH 1/2] A bit easier to read. --- tests/playground/playground.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/playground/playground.tsx b/tests/playground/playground.tsx index fc32087..ea2b8b0 100644 --- a/tests/playground/playground.tsx +++ b/tests/playground/playground.tsx @@ -14,6 +14,7 @@ type Mode = keyof typeof MODES const App = () => { const [activeComponent, setActiveComponent] = useState('claude') + const ModeComponent = MODES[activeComponent].component return (
@@ -43,10 +44,7 @@ const App = () => {
- {(() => { - const Component = MODES[activeComponent].component - return - })()} +
From 8208c415b975ed1ac1f87d5292ced73a5a45b6cd Mon Sep 17 00:00:00 2001 From: Todd Riley Date: Wed, 24 Sep 2025 14:01:24 -0400 Subject: [PATCH 2/2] Separate components into new files. --- src/components/BulkActionsBar.tsx | 22 +++++ src/components/CommentRow.tsx | 67 ++++++++++++++++ src/components/EmptyState.tsx | 20 +++++ src/components/NoMatchesState.tsx | 13 +++ src/components/PopupRoot.tsx | 128 ++++-------------------------- 5 files changed, 139 insertions(+), 111 deletions(-) create mode 100644 src/components/BulkActionsBar.tsx create mode 100644 src/components/CommentRow.tsx create mode 100644 src/components/EmptyState.tsx create mode 100644 src/components/NoMatchesState.tsx diff --git a/src/components/BulkActionsBar.tsx b/src/components/BulkActionsBar.tsx new file mode 100644 index 0000000..abe9416 --- /dev/null +++ b/src/components/BulkActionsBar.tsx @@ -0,0 +1,22 @@ +type BulkActionsBarProps = { + selectedIds: Set +} +export function BulkActionsBar({ selectedIds }: BulkActionsBarProps) { + return ( +
+ {selectedIds.size} selected + + + + +
+ ) +} diff --git a/src/components/CommentRow.tsx b/src/components/CommentRow.tsx new file mode 100644 index 0000000..d35fb1f --- /dev/null +++ b/src/components/CommentRow.tsx @@ -0,0 +1,67 @@ +import Badge from '@/components/Badge' +import { timeAgo } from '@/components/misc' +import type { CommentTableRow } from '@/entrypoints/background' +import { EnhancerRegistry } from '@/lib/registries' + +const enhancers = new EnhancerRegistry() + +type CommentRowProps = { + row: CommentTableRow + selectedIds: Set + toggleSelection: (id: string) => void + handleOpen: (url: string) => void + handleTrash: (row: CommentTableRow) => void +} + +export function CommentRow({ row, selectedIds, toggleSelection }: CommentRowProps) { + const enhancer = enhancers.enhancerFor(row.spot) + return ( + + + toggleSelection(row.spot.unique_key)} + className='rounded' + /> + + +
+ {/* Context line */} +
+
+ {enhancer.tableUpperDecoration(row.spot)} +
+
+ {row.latestDraft.stats.links.length > 0 && ( + + )} + {row.latestDraft.stats.images.length > 0 && ( + + )} + {row.latestDraft.stats.codeBlocks.length > 0 && ( + + )} + + + {row.isOpenTab && } +
+
+ + {/* Title */} +
+ + {enhancer.tableTitle(row.spot)} + + + {row.isTrashed && } +
+ {/* Draft */} +
+ {row.latestDraft.content.substring(0, 100)}… +
+
+ + + ) +} diff --git a/src/components/EmptyState.tsx b/src/components/EmptyState.tsx new file mode 100644 index 0000000..65814ef --- /dev/null +++ b/src/components/EmptyState.tsx @@ -0,0 +1,20 @@ +export function EmptyState() { + return ( +
+

No comments open

+

+ Your drafts will appear here when you start typing in comment boxes across GitHub and + Reddit. +

+
+ + · + +
+
+ ) +} diff --git a/src/components/NoMatchesState.tsx b/src/components/NoMatchesState.tsx new file mode 100644 index 0000000..0052595 --- /dev/null +++ b/src/components/NoMatchesState.tsx @@ -0,0 +1,13 @@ +type NoMatchesStateProps = { + onClearFilters: () => void +} +export function NoMatchesState({ onClearFilters }: NoMatchesStateProps) { + return ( +
+

No matches found

+ +
+ ) +} diff --git a/src/components/PopupRoot.tsx b/src/components/PopupRoot.tsx index ec32e04..de75534 100644 --- a/src/components/PopupRoot.tsx +++ b/src/components/PopupRoot.tsx @@ -1,13 +1,15 @@ import { Eye, EyeOff, Search, Settings, Trash2 } from 'lucide-react' import { useMemo, useState } from 'react' import { twMerge } from 'tailwind-merge' -import Badge from '@/components/Badge' import { badgeCVA } from '@/components/design' import MultiSegment from '@/components/MultiSegment' -import { allLeafValues, timeAgo } from '@/components/misc' +import { allLeafValues } from '@/components/misc' import type { CommentTableRow } from '@/entrypoints/background' import type { FilterState } from '@/entrypoints/popup/popup' -import { EnhancerRegistry } from '@/lib/registries' +import { BulkActionsBar } from './BulkActionsBar' +import { CommentRow } from './CommentRow' +import { EmptyState } from './EmptyState' +import { NoMatchesState } from './NoMatchesState' const initialFilter: FilterState = { searchQuery: '', @@ -20,7 +22,7 @@ interface PopupRootProps { } export function PopupRoot({ drafts }: PopupRootProps) { - const [selectedIds, setSelectedIds] = useState(new Set()) + const [selectedIds, setSelectedIds] = useState>(new Set()) const [filters, setFilters] = useState(initialFilter) const updateFilter = (key: K, value: FilterState[K]) => { @@ -100,31 +102,22 @@ export function PopupRoot({ drafts }: PopupRootProps) { return } - return filteredDrafts.map((row) => - commentRow(row, selectedIds, toggleSelection, handleOpen, handleTrash), - ) + return filteredDrafts.map((row) => ( + + )) } return (
{/* Bulk actions bar - floating popup */} - {selectedIds.size > 0 && ( -
- {selectedIds.size} selected - - - - -
- )} + {selectedIds.size > 0 && } {/* Table */}
@@ -221,90 +214,3 @@ export function PopupRoot({ drafts }: PopupRootProps) {
) } - -const enhancers = new EnhancerRegistry() -function commentRow( - row: CommentTableRow, - selectedIds: Set, - toggleSelection: (id: string) => void, - _handleOpen: (url: string) => void, - _handleTrash: (row: CommentTableRow) => void, -) { - const enhancer = enhancers.enhancerFor(row.spot) - return ( - - - toggleSelection(row.spot.unique_key)} - className='rounded' - /> - - -
- {/* Context line */} -
-
- {enhancer.tableUpperDecoration(row.spot)} -
-
- {row.latestDraft.stats.links.length > 0 && ( - - )} - {row.latestDraft.stats.images.length > 0 && ( - - )} - {row.latestDraft.stats.codeBlocks.length > 0 && ( - - )} - - - {row.isOpenTab && } -
-
- - {/* Title */} -
- - {enhancer.tableTitle(row.spot)} - - - {row.isTrashed && } -
- {/* Draft */} -
- {row.latestDraft.content.substring(0, 100)}… -
-
- - - ) -} - -const EmptyState = () => ( -
-

No comments open

-

- Your drafts will appear here when you start typing in comment boxes across GitHub and Reddit. -

-
- - · - -
-
-) - -const NoMatchesState = ({ onClearFilters }: { onClearFilters: () => void }) => ( -
-

No matches found

- -
-)