cheogram-www
created pr with
cheogram-www/unread-filter.1
added cheogram-www/unread-filter.2
1: 9d343f3 = 1: efc44ba Allow filtering by unread
-: ------- > 2: 2da6059 Combine unread and tag into filter.
cmds
checkout latest patchset:
ssh pr.pico.sh pull cheogram-www:unread-filter | git am -3checkout specific patchset revision:
ssh pr.pico.sh pull cheogram-www:unread-filter [rev] | git am -3add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh cheogram-www:unread-filteradd comment to patch request:
ssh pr.pico.sh comment cheogram-www:unread-filter "lgtm!"
Patchset
cheogram-www/unread-filter.2
Allow filtering by unread
Stephen Paul Weber
2026-10-26T01:57:16ZIn the tags drop down for now
Semantic diff summary
0 added,
4 modified,
0 signature changed,
0 removed
across 1 analyzed file
+31
-18
src/components/Chats.tsx
#
| ... | ... | @@ -13,7 +13,7 @@ import { | |
| 13 | 13 | } from "@mui/material"; | |
| 14 | 14 | import { QRCanvas, frontalCamera } from "qr/dom.js"; | |
| 15 | 15 | import { Virtuoso, VirtuosoHandle } from "react-virtuoso"; | |
| 16 | - | import { useQueryState } from "nuqs"; | |
| 16 | + | import { parseAsBoolean, useQueryState } from "nuqs"; | |
| 17 | 17 | import { useState, useEffect, useRef, useCallback, useContext } from "react"; | |
| 18 | 18 | import { | |
| 19 | 19 | Outlet, |
| ... | ... | @@ -66,6 +66,10 @@ export const Chats = () => { | |
| 66 | 66 | const [searchParams] = useSearchParams(); | |
| 67 | 67 | const [searchQ, setSearchQ] = useQueryState("q"); | |
| 68 | 68 | const [searchTag, setSearchTag] = useQueryState("tag"); | |
| 69 | + | const [searchUnread, setSearchUnread] = useQueryState( | |
| 70 | + | "unread", | |
| 71 | + | parseAsBoolean.withDefault(false), | |
| 72 | + | ); | |
| 69 | 73 | const { persistence, client, status, setStatus, logout } = useOutletContext<{ | |
| 70 | 74 | persistence: borogove.Persistence & borogove.persistence.KeyValueStore; | |
| 71 | 75 | client: borogove.Client; |
| ... | ... | @@ -307,9 +311,9 @@ export const Chats = () => { | |
| 307 | 311 | } | |
| 308 | 312 | } | |
| 309 | 313 | } | |
| 310 | - | return searchTag | |
| 311 | - | ? results.filter((c) => c.getTags().includes(searchTag)) | |
| 312 | - | : results; | |
| 314 | + | return results | |
| 315 | + | .filter((c) => !searchTag || c.getTags().includes(searchTag)) | |
| 316 | + | .filter((c) => !searchUnread || c.unreadCount() > 0); | |
| 313 | 317 | }; | |
| 314 | 318 | ||
| 315 | 319 | const [searchResultLimit, setSearchResultLimit] = useState(5); |
| ... | ... | @@ -611,21 +615,30 @@ export const Chats = () => { | |
| 611 | 615 | /> | |
| 612 | 616 | )} | |
| 613 | 617 | </AwaitOnce> | |
| 614 | - | {tags.size > 0 && ( | |
| 615 | - | <select | |
| 616 | - | id="tag-nav" | |
| 617 | - | onChange={(e) => | |
| 618 | - | setSearchTag(e.target.value ? e.target.value : null) | |
| 618 | + | <select | |
| 619 | + | id="tag-nav" | |
| 620 | + | value={ | |
| 621 | + | searchUnread ? "unread" : searchTag ? `tag:${searchTag}` : "all" | |
| 622 | + | } | |
| 623 | + | onChange={(e) => { | |
| 624 | + | const value = e.target.value; | |
| 625 | + | if (value.startsWith("tag:")) { | |
| 626 | + | setSearchUnread(false); | |
| 627 | + | setSearchTag(value.slice("tag:".length)); | |
| 628 | + | } else { | |
| 629 | + | setSearchTag(null); | |
| 630 | + | setSearchUnread(value === "unread"); | |
| 619 | 631 | } | |
| 620 | - | > | |
| 621 | - | <option value="">All Chats</option> | |
| 622 | - | {tags.keys().map((t) => ( | |
| 623 | - | <option value={t} key={t} selected={searchTag === t}> | |
| 624 | - | {t} | |
| 625 | - | </option> | |
| 626 | - | ))} | |
| 627 | - | </select> | |
| 628 | - | )} | |
| 632 | + | }} | |
| 633 | + | > | |
| 634 | + | <option value="all">All Chats</option> | |
| 635 | + | <option value="unread">Unread</option> | |
| 636 | + | {tags.keys().map((t) => ( | |
| 637 | + | <option value={`tag:${t}`} key={t}> | |
| 638 | + | {t} | |
| 639 | + | </option> | |
| 640 | + | ))} | |
| 641 | + | </select> | |
| 629 | 642 | {subnav !== "apps" && subnav != "requests" && ( | |
| 630 | 643 | <nav aria-label="Chat List"> | |
| 631 | 644 | {searchQ && searchQ.length > 0 && ( |