Mark all as read

This commit is contained in:
Jack Kingsman
2026-01-07 17:42:25 -08:00
parent 4df8b89fc4
commit 8ef617fe29
3 changed files with 40 additions and 4 deletions

View File

@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>RemoteTerm for MeshCore</title>
<script type="module" crossorigin src="/assets/index-Bjui8xah.js"></script>
<script type="module" crossorigin src="/assets/index-D9RuHvp1.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-RWG6EjFU.css">
</head>
<body>

View File

@@ -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}
/>
);

View File

@@ -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<SortOrder>(loadSortOrder);
const [searchQuery, setSearchQuery] = useState('');
@@ -247,6 +249,17 @@ export function Sidebar({
</div>
)}
{/* Mark All Read */}
{!query && Object.keys(unreadCounts).length > 0 && (
<div
className="px-3 py-2.5 cursor-pointer flex items-center gap-2 border-l-2 border-transparent hover:bg-accent"
onClick={onMarkAllRead}
>
<span className="text-muted-foreground text-xs"></span>
<span className="flex-1 truncate text-muted-foreground">Mark all as read</span>
</div>
)}
{/* Channels */}
{filteredChannels.length > 0 && (
<>