Give listFeeds its container: Add a feed loads its Popular list again

The dialog and the Directory/Popular pane both rendered into id="popular", and
listFeeds looked it up by id, so the dialog's list landed in the pane behind it.

Fixes #1

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZbKERNSt4vQfyGV8rvkqp
This commit is contained in:
2026-09-14 21:28:49 +00:00
parent eeb72fd677
commit af38583b53
6 changed files with 55 additions and 6 deletions

View File

@@ -0,0 +1,14 @@
{
"permissions": {
"allow": [
"Bash(rtk grep *)",
"Bash(rtk read *)",
"Bash(rtk git *)"
],
"additionalDirectories": [
"/config/.claude/skills/security-audit",
"/config/security-audit-skill",
"/config/.cargo/registry"
]
}
}

13
.rtk/filters.toml Normal file
View File

@@ -0,0 +1,13 @@
# Project-local RTK filters — commit this file with your repo.
# Filters here override user-global and built-in filters.
# Docs: https://github.com/rtk-ai/rtk#custom-filters
schema_version = 1
# Example: suppress build noise from a custom tool
# [filters.my-tool]
# description = "Compact my-tool output"
# match_command = "^my-tool\\s+build"
# strip_ansi = true
# strip_lines_matching = ["^\\s*$", "^Downloading", "^Installing"]
# max_lines = 30
# on_empty = "my-tool: ok"

View File

@@ -14,6 +14,11 @@ The long form, with what was wrong before and how it was found, is in
- An unused icon glyph (`minus`) left over from before Unsubscribe settled on `circleMinus`. - An unused icon glyph (`minus`) left over from before Unsubscribe settled on `circleMinus`.
### Fixed
- Add a feed opened over Directory or Popular now shows its Popular list instead of staying on
"Loading…", and no longer cuts the Directory behind it down to ten.
## [0.5.4] - 2026-09-14 ## [0.5.4] - 2026-09-14
### Added ### Added

View File

@@ -154,3 +154,14 @@ Deliberate simplifications get a `ponytail:` comment naming the ceiling and the
(documented in [docs/sso.md](docs/sso.md)). (documented in [docs/sso.md](docs/sso.md)).
* A feed's `<description>` subtitle is dropped whenever `content:encoded` exists, which loses * A feed's `<description>` subtitle is dropped whenever `content:encoded` exists, which loses
Substack-style subtitles. Substack-style subtitles.
<!-- rtk-instructions v2 -->
# Command output
Command output here is condensed to save tokens, keeping every signal and
dropping costly noise. Treat it as the complete result: run commands
normally, and batch related commands into one call to avoid extra turns.
Truncated results state their recovery path in their own output. Re-run a
command as `rtk proxy <cmd>` only when its result is unusable: empty when
output was clearly expected, contradicting its exit code, or garbled.
<!-- /rtk-instructions -->

View File

@@ -703,6 +703,12 @@ test('Popular lists what everyone here reads, but never a private feed', async (
await expect(offered.filter({ hasText: /Test Subscriptions/ })).toHaveCount(0); await expect(offered.filter({ hasText: /Test Subscriptions/ })).toHaveCount(0);
await expect(offered.filter({ hasText: /Paid Show|paid-show/ })).toHaveCount(0); await expect(offered.filter({ hasText: /Paid Show|paid-show/ })).toHaveCount(0);
// Add a feed opened over Directory fills its own list, not the pane behind it.
await piper.locator('#addFeed').click();
await expect(piper.locator('#modalCard .childrow', { hasText: 'Test Show' })).toBeVisible();
await expect(offered).toHaveCount(dir.length);
await piper.locator('#modalCard button[title="Cancel"]').click();
const row = async () => const row = async () =>
(await (await piper.request.get('/api/popular')).json()).find(p => p.id === 'test-show'); (await (await piper.request.get('/api/popular')).json()).find(p => p.id === 'test-show');
const before = await row(); const before = await row();

View File

@@ -1625,11 +1625,11 @@ $('#addFeed').onclick=()=>{
<input type="text" id="nkw"><span class="hint">Only items matching a keyword are downloaded.</span></div> <input type="text" id="nkw"><span class="hint">Only items matching a keyword are downloaded.</span></div>
<label class="check"><input type="checkbox" id="nexp"> Allow items marked explicit</label> <label class="check"><input type="checkbox" id="nexp"> Allow items marked explicit</label>
<div class="field"><label>Popular on this server</label> <div class="field"><label>Popular on this server</label>
<div class="childlist" id="popular"><p class="hint">Loading…</p></div></div> <div class="childlist" id="npopular"><p class="hint">Loading…</p></div></div>
<div class="cardacts"><button class="btn ico" onclick="closeModal()" title="Cancel" aria-label="Cancel">${ICON.close}</button> <div class="cardacts"><button class="btn ico" onclick="closeModal()" title="Cancel" aria-label="Cancel">${ICON.close}</button>
<button class="btn ico primary" id="nsave" title="Add feed" aria-label="Add feed">${ICON.plus}</button></div>`); <button class="btn ico primary" id="nsave" title="Add feed" aria-label="Add feed">${ICON.plus}</button></div>`);
$('#nurl').focus(); $('#nurl').focus();
listFeeds('/api/popular'); listFeeds('/api/popular',$('#npopular'));
$('#nsave').onclick=async()=>{ $('#nsave').onclick=async()=>{
const url=$('#nurl').value.trim(); if(!url) return; const url=$('#nurl').value.trim(); if(!url) return;
$('#nsave').disabled=true; $('#nsave').title='Adding…'; $('#nsave').disabled=true; $('#nsave').title='Adding…';
@@ -1644,9 +1644,9 @@ $('#addFeed').onclick=()=>{
}; };
// What everyone here reads, you included, as a place to start. The rows carry an id, never a // What everyone here reads, you included, as a place to start. The rows carry an id, never a
// URL, so a key in someone's feed address never reaches this page. // URL, so a key in someone's feed address never reaches this page. The caller hands over the
async function listFeeds(url){ // box: looked up by id, the Add a feed dialog's list landed in the Directory pane behind it.
const box=$('#popular'); async function listFeeds(url,box){
let rows=[]; let rows=[];
try{ rows=await api(url)||[]; }catch{} try{ rows=await api(url)||[]; }catch{}
box.innerHTML=rows.length?'':'<p class="hint">Nothing yet. Feeds people here subscribe to show up here.</p>'; box.innerHTML=rows.length?'':'<p class="hint">Nothing yet. Feeds people here subscribe to show up here.</p>';
@@ -1691,7 +1691,7 @@ async function renderListed(v){
${listening?`<div class="sub" style="margin:18px 0 8px;font-weight:600;color:var(--fg)">Currently Listening</div> ${listening?`<div class="sub" style="margin:18px 0 8px;font-weight:600;color:var(--fg)">Currently Listening</div>
<div class="childlist" id="listening"><p class="hint">Loading…</p></div>`:''}`; <div class="childlist" id="listening"><p class="hint">Loading…</p></div>`:''}`;
$('#count').textContent=v.title; $('#count').textContent=v.title;
const n=await listFeeds(v.url); const n=await listFeeds(v.url,$('#popular',box));
if(VIEWS[S.feed]===v) $('#count').textContent=`${v.title}: ${n} feed${n===1?'':'s'}`; if(VIEWS[S.feed]===v) $('#count').textContent=`${v.title}: ${n} feed${n===1?'':'s'}`;
if(listening) renderListening(); if(listening) renderListening();
} }