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 && (
<>