wrolpi/app/src/components
lrnselfreliance 9caa140fb6
app: search Other tab distinguishes pending channels from none (#728)
* app: search Other tab distinguishes pending channels from none

useSearchChannels initialised channels to [] and loading to false, and
only set loading inside its mount effect, so the Other tab's first
render painted "No Channels" with a count of 0 before the search had
run.  A failed search was rendered the same way, since the hook had no
catch and the API helper returns undefined on a non-OK response.

Invariants now enforced and tested:
* null = pending, undefined = fetch failed, [] = no channels; loading
  is true from the first render because the search starts on mount.
* Changing tags resets to pending, and only the newest request may
  write state, so a slow response for previous tags is dropped.
* The tab shows a loader while pending, an error on failure, and
  "No Channels" only once the server confirmed there are none.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* app: useSearchChannels follows its caller's tags

The hook read its tag argument only as the initial state, so the
Other tab never refetched when the filter modal changed the URL's tags
while the tab stayed mounted; the list, including a stale "No
Channels", was whatever the mount fetched.

The internal tag state now follows the argument's contents, keyed on
the serialized list because the caller builds a new array every
render.  Tests change the hook argument after a loaded result and
expect a second search and a reset to pending, check that a new array
with the same tags does not refetch, and keep the slow-response drop.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-26 12:01:37 -06:00
..
admin Hotspot captive portal: welcome page with the WROLPi's address (#709) 2026-09-13 20:10:02 -06:00
calculators Speed Test calculator: ping, download, and upload against the API (#708) 2026-09-13 18:47:18 -06:00
collections ui: the last of Semantic UI, in name and in dead CSS 2026-08-08 18:05:54 -06:00
inventory test: the component suite's twelve failures, none of them about the component 2026-08-08 18:05:54 -06:00
ui Speed Test calculator: ping, download, and upload against the API (#708) 2026-09-13 18:47:18 -06:00
AddToPlaylist.js ui: Common.js and thirteen more files off Semantic 2026-08-08 18:04:00 -06:00
Apps.js fix: break the import cycle that put useCalculators in the TDZ 2026-08-08 18:05:47 -06:00
Archive.js ui: the last of Semantic UI, in name and in dead CSS 2026-08-08 18:05:54 -06:00
ArchivePreview.js ui: Common.js and thirteen more files off Semantic 2026-08-08 18:04:00 -06:00
BulkTagModal.js ui: only the top modal answers Escape, and the audited widths 2026-08-08 18:05:49 -06:00
BulkTagModal.test.js ui: migrate Downloads, Upload, and BulkTagModal off Semantic 2026-08-08 18:04:02 -06:00
Calculators.js Speed Test calculator: ping, download, and upload against the API (#708) 2026-09-13 18:47:18 -06:00
CbzViewer.js ui: Common.js and thirteen more files off Semantic 2026-08-08 18:04:00 -06:00
Channels.cy.js test: the component suite's twelve failures, none of them about the component 2026-08-08 18:05:54 -06:00
Channels.js ui: a Back button is a row of one, not a stretched flex child 2026-08-08 18:05:52 -06:00
CodecSettings.test.js videos: codec download preferences with transcode and strict-fail options (#701) 2026-09-07 09:12:00 -06:00
Common.js ui: the last of Semantic UI, in name and in dead CSS 2026-08-08 18:05:54 -06:00
Common.test.js ui: sample data names Blender and WROLPi, not real channels (#647) 2026-08-08 18:05:55 -06:00
DatesSelector.js ui: thirty-five files off Semantic, leaving fifteen 2026-08-08 18:04:01 -06:00
DesktopToggle.test.js ui: Common.js and thirteen more files off Semantic 2026-08-08 18:04:00 -06:00
Docs.js ui: a PDF asks before it lights up a night-adapted eye (#654) 2026-08-11 18:57:15 -06:00
Docs.test.js ui: a PDF asks before it lights up a night-adapted eye (#654) 2026-08-11 18:57:15 -06:00
DomainEditPage.test.js ui: the last of Semantic UI, in name and in dead CSS 2026-08-08 18:05:54 -06:00
DomainsPage.test.js Reformatting code. 2025-12-06 15:11:37 -07:00
DomainTagging.test.js test: one place for fixtures, real providers instead of mocked context modules 2026-08-08 18:04:04 -06:00
DonatePage.js ui: only the top modal answers Escape, and the audited widths 2026-08-08 18:05:49 -06:00
Download.cy.js videos: codec download preferences with transcode and strict-fail options (#701) 2026-09-07 09:12:00 -06:00
Download.js videos: codec download preferences with transcode and strict-fail options (#701) 2026-09-07 09:12:00 -06:00
Download.test.js Reformatting code. 2025-12-06 15:11:37 -07:00
ErrorBoundary.js ui: nine leaf files off Semantic, and the components they needed 2026-08-08 18:04:00 -06:00
FileBrowser.js ui: two upload dialogs that had drifted apart (#664) 2026-08-13 15:15:04 -06:00
FileBrowser.test.js ui: the Files filter's clear button rejoins its input (#650) 2026-08-08 18:05:55 -06:00
FilePreview.js files: left-align the preview toolbar (#698) 2026-09-03 16:03:17 -06:00
FilePreview.test.js files: readable text previews in dark themes (#697) 2026-09-03 15:47:44 -06:00
Files.js ui: the last of Semantic UI, in name and in dead CSS 2026-08-08 18:05:54 -06:00
Flasher.js ui: scale the whole interface by 10%, off the root font-size 2026-08-08 18:05:51 -06:00
Flasher.test.js ui: migrate Flasher.js off Semantic UI React 2026-08-08 18:04:02 -06:00
Headline.js ui: nine leaf files off Semantic, and the components they needed 2026-08-08 18:04:00 -06:00
HelpModal.js ui: thirty-five files off Semantic, leaving fifteen 2026-08-08 18:04:01 -06:00
KeyboardShortcutsProvider.js ui: the last of Semantic UI, in name and in dead CSS 2026-08-08 18:05:54 -06:00
Map.js Map previews that never drew, and a Docker map with no world under it (#658) 2026-08-11 20:37:23 -06:00
Map.test.js review: name the icon-only controls, and make two guards mean what they say 2026-08-08 18:05:50 -06:00
MapPreview.test.js Map previews that never drew, and a Docker map with no world under it (#658) 2026-08-11 20:37:23 -06:00
MapSearchView.js ui: widen a card's track by 25% 2026-08-08 18:05:51 -06:00
MapViewer.js review: close the mixed-unit gaps the scale left behind 2026-08-08 18:05:51 -06:00
Nav.js files: left-align the preview toolbar (#698) 2026-09-03 16:03:17 -06:00
Nav.test.js ui: the navbar shows which section you are in (#649) 2026-08-08 18:05:55 -06:00
OtherSearchView.test.js app: search Other tab distinguishes pending channels from none (#728) 2026-09-26 12:01:37 -06:00
otp.js Move One-Time Pad encryption to the browser (#479) 2026-06-13 13:52:34 -06:00
otp.test.js Move One-Time Pad encryption to the browser (#479) 2026-06-13 13:52:34 -06:00
Placeholder.js ui: Common.js and thirteen more files off Semantic 2026-08-08 18:04:00 -06:00
Playlists.js review: the scan the first two commits needed 2026-08-08 18:05:53 -06:00
Playlists.test.js Add ordered collections (playlists): polymorphic items + item API (#475) 2026-06-11 19:46:34 -06:00
Search.js app: search Other tab distinguishes pending channels from none (#728) 2026-09-26 12:01:37 -06:00
SearchFilterModal.test.js ui: thirty-five files off Semantic, leaving fifteen 2026-08-08 18:04:01 -06:00
Share.js files: left-align the preview toolbar (#698) 2026-09-03 16:03:17 -06:00
ShortcutHint.js Displaying cmd+k/ctrl+k global search keyboard shortcut suggestion. 2026-02-23 16:07:22 -07:00
SortableTable.js review: the 375px phone this fix had not been measured on (#662) 2026-08-13 11:38:49 -06:00
Tables.js ui: nine leaf files off Semantic, and the components they needed 2026-08-08 18:04:00 -06:00
TaggedDeleteConfirmModal.js ui: let a confirmation choose its width 2026-08-08 18:05:51 -06:00
TaggedDeleteConfirmModal.test.js ui: let a confirmation choose its width 2026-08-08 18:05:51 -06:00
Theme.tsx ui: the last of Semantic UI, in name and in dead CSS 2026-08-08 18:05:54 -06:00
ThemeProvider.test.js test: act on review — observe the wiring, and stop the soft assertions 2026-08-08 18:05:45 -06:00
ThemeSamplePage.js Jobs queue, video Edit dropdown: transcode/remux, edit title & description (#711) 2026-09-16 19:25:23 -06:00
Upload.js ui: two upload dialogs that had drifted apart (#664) 2026-08-13 15:15:04 -06:00
Upload.test.js ui: two upload dialogs that had drifted apart (#664) 2026-08-13 15:15:04 -06:00
Vars.js Jobs queue, video Edit dropdown: transcode/remux, edit title & description (#711) 2026-09-16 19:25:23 -06:00
VideoEditMenu.js app: video comments and description distinguish pending from empty (#727) 2026-09-26 11:22:37 -06:00
VideoEditMenu.test.js app: video comments and description distinguish pending from empty (#727) 2026-09-26 11:22:37 -06:00
VideoExtras.test.js app: video comments and description distinguish pending from empty (#727) 2026-09-26 11:22:37 -06:00
VideoPlayer.js app: video comments and description distinguish pending from empty (#727) 2026-09-26 11:22:37 -06:00
VideoPlayer.test.js videos: address review — tighten auto-caption detection 2026-07-16 18:29:18 -06:00
Videos.js videos: codec download preferences with transcode and strict-fail options (#701) 2026-09-07 09:12:00 -06:00
VncToggle.test.js ui: Common.js and thirteen more files off Semantic 2026-08-08 18:04:00 -06:00
Zim.js zim: recompute the outdated-Zims flag after startup and on Delete (#706) 2026-09-12 15:19:36 -06:00
Zim.test.js zim: recompute the outdated-Zims flag after startup and on Delete (#706) 2026-09-12 15:19:36 -06:00