Search Currently Listening from the search box (#127)
Currently Listening's search box said "Search items…" and did nothing: loadEntries returns early for a place with its own list. Typing now redraws the list with the search sent along, as /api/entries already takes one, title and text, and says so when nothing in progress matches. The keys list says / searches it too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
### Fixed
|
||||
|
||||
- A feed whose address answers with nothing, as a lapsed domain does behind a DNS filter's block page, shows as failing, with what to do about it, instead of as a show that has not posted yet.
|
||||
- The search box finds episodes in Currently Listening. It did nothing there.
|
||||
- On Postgres, a write no longer waits for the database server's disk. A scan read about one feed a second and now reads 1,500 in 20 seconds.
|
||||
- Checking every feed no longer makes every icon in the feed list flash while it runs: the list keeps the icons it has already drawn.
|
||||
|
||||
|
||||
@@ -263,6 +263,15 @@ test('Currently Listening, its own place below the Directory, resumes an episode
|
||||
await expect(row).toBeVisible({ timeout: 20_000 });
|
||||
await expect(row).toContainText('14:18 left');
|
||||
|
||||
// The search box looks through it, as it does a feed's items (#127).
|
||||
await page.locator('#epSearch').fill('second');
|
||||
await expect(row).toBeVisible();
|
||||
await page.locator('#epSearch').fill('nothing-is-called-this');
|
||||
await expect(row).toHaveCount(0);
|
||||
await expect(page.locator('#listening')).toContainText('Nothing you are listening to mentions');
|
||||
await page.locator('#epSearch').fill('');
|
||||
await expect(row).toBeVisible();
|
||||
|
||||
// Removing it forgets where you got to, so it is still gone on the next visit.
|
||||
await row.locator('[data-a=remove]').click();
|
||||
await expect(row).toHaveCount(0);
|
||||
|
||||
@@ -259,7 +259,8 @@ async function renderListed(v){
|
||||
</div>
|
||||
<div class="childlist" id="listening"><p class="hint">Loading…</p></div>`;
|
||||
$('#count').textContent=v.title;
|
||||
const n=await renderListening(v.url,$('#listening',box));
|
||||
// The search box looks through these too, title and text, as it does a feed's items (#127).
|
||||
const n=await renderListening(S.q?`${v.url}&q=${encodeURIComponent(S.q)}`:v.url,$('#listening',box));
|
||||
if(VIEWS[S.feed]===v) $('#count').textContent=`${v.title}: ${plural(n,'episode')}`;
|
||||
}
|
||||
|
||||
@@ -269,7 +270,8 @@ async function renderListed(v){
|
||||
async function renderListening(url,box){
|
||||
let rows=[];
|
||||
try{ rows=(await api(url)).entries||[]; }catch{}
|
||||
box.innerHTML=rows.length?'':'<p class="hint">Nothing in progress. Episodes you start and do not finish show up here.</p>';
|
||||
box.innerHTML=rows.length?'':S.q?`<p class="hint">Nothing you are listening to mentions “${esc(S.q)}”.</p>`
|
||||
:'<p class="hint">Nothing in progress. Episodes you start and do not finish show up here.</p>';
|
||||
for(const e of rows){
|
||||
// Carries its episode, for paintListenRow to repaint as the player moves.
|
||||
const el: HTMLDivElement & {entry?: any}=document.createElement('div');
|
||||
@@ -329,9 +331,12 @@ $('#tbRead').onclick=()=>{ const e=cur(); if(e) epAction('read',e,null); };
|
||||
$('#tbFlag').onclick=()=>{ const e=cur(); if(e) epAction('flag',e,null); };
|
||||
let searchT;
|
||||
$('#epSearch').oninput=ev=>{ clearTimeout(searchT);
|
||||
// The Directory looks through what it already has; the rest ask the server (#126).
|
||||
// The Directory looks through what it already has; Currently Listening and the rest ask the
|
||||
// server (#126, #127).
|
||||
searchT=setTimeout(()=>{ S.q=ev.target.value; S.offset=0;
|
||||
if(S.feed===':directory'){ dirShow=null; drawDirectory(); } else loadEntries(); },250); };
|
||||
if(S.feed===':directory'){ dirShow=null; drawDirectory(); }
|
||||
else if(S.feed===':listening') renderListed(VIEWS[':listening']);
|
||||
else loadEntries(); },250); };
|
||||
// Crossing the phone breakpoint moves the files between their pane and the text.
|
||||
window.matchMedia?.('(max-width:820px)')?.addEventListener?.('change',()=>{ const e=cur(); if(e) showDetail(e); });
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ function keysModal(){
|
||||
[g('a'),'All Subscriptions'],[g('d'),'Directory'],
|
||||
[g('l'),'Currently Listening'],[g('s'),'Settings'],
|
||||
[k('Shift')+' '+k('J'),'Next feed'],[k('Shift')+' '+k('K'),'Previous feed'],
|
||||
[k('/'),'Search items, or the Directory'],[k('r'),'Refresh'],[k('['),'Show or hide the feed list'],
|
||||
[k('/'),'Search items, Currently Listening or the Directory'],[k('r'),'Refresh'],[k('['),'Show or hide the feed list'],
|
||||
['Items'],
|
||||
[k('j')+' or '+k('n'),'Next item'],[k('k')+' or '+k('p'),'Previous item'],
|
||||
[k('Shift')+' '+k('A'),'Mark all read'],
|
||||
|
||||
Reference in New Issue
Block a user