From 8ef617fe2946ba23241deea1b0924ed5124fbcb3 Mon Sep 17 00:00:00 2001 From: Jack Kingsman Date: Wed, 7 Jan 2026 17:42:25 -0800 Subject: [PATCH] Mark all as read --- frontend/dist/index.html | 2 +- frontend/src/App.tsx | 23 +++++++++++++++++++++++ frontend/src/components/Sidebar.tsx | 19 ++++++++++++++++--- 3 files changed, 40 insertions(+), 4 deletions(-) diff --git a/frontend/dist/index.html b/frontend/dist/index.html index 417e663..abbb8ff 100644 --- a/frontend/dist/index.html +++ b/frontend/dist/index.html @@ -4,7 +4,7 @@ RemoteTerm for MeshCore - + diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 7b0324b..9819b30 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -515,6 +515,28 @@ export function App() { setSidebarOpen(false); }, []); + // Mark all conversations as read + const handleMarkAllRead = useCallback(() => { + const now = Math.floor(Date.now() / 1000); + + // Update localStorage for all channels + for (const channel of channels) { + const key = getStateKey('channel', channel.key); + setLastReadTime(key, now); + } + + // Update localStorage for all contacts + for (const contact of contacts) { + if (contact.public_key) { + const key = getStateKey('contact', contact.public_key); + setLastReadTime(key, now); + } + } + + // Clear all unread counts + setUnreadCounts({}); + }, [channels, contacts]); + // Delete channel handler const handleDeleteChannel = useCallback(async (key: string) => { if (!confirm('Delete this channel? Message history will be preserved.')) return; @@ -640,6 +662,7 @@ export function App() { showCracker={showCracker} crackerRunning={crackerRunning} onToggleCracker={() => setShowCracker((prev) => !prev)} + onMarkAllRead={handleMarkAllRead} /> ); diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx index 9bfaeb3..321cb55 100644 --- a/frontend/src/components/Sidebar.tsx +++ b/frontend/src/components/Sidebar.tsx @@ -21,15 +21,16 @@ interface SidebarProps { showCracker: boolean; crackerRunning: boolean; onToggleCracker: () => void; + onMarkAllRead: () => void; } -// Load sort preference from localStorage +// Load sort preference from localStorage (default to 'recent') function loadSortOrder(): SortOrder { try { const stored = localStorage.getItem('remoteterm-sortOrder'); - return stored === 'recent' ? 'recent' : 'alpha'; + return stored === 'alpha' ? 'alpha' : 'recent'; } catch { - return 'alpha'; + return 'recent'; } } @@ -53,6 +54,7 @@ export function Sidebar({ showCracker, crackerRunning, onToggleCracker, + onMarkAllRead, }: SidebarProps) { const [sortOrder, setSortOrder] = useState(loadSortOrder); const [searchQuery, setSearchQuery] = useState(''); @@ -247,6 +249,17 @@ export function Sidebar({ )} + {/* Mark All Read */} + {!query && Object.keys(unreadCounts).length > 0 && ( +
+ + Mark all as read +
+ )} + {/* Channels */} {filteredChannels.length > 0 && ( <>