diff --git a/CHANGELOG.md b/CHANGELOG.md index 8dd304c..5fd5ff0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,9 @@ The long form, with what was wrong before and how it was found, is in - A feed that fails to check gets a red ! in the feed list, and its page says why, in place of a pop-up per failure that everyone saw during a scan of every feed. - The theme is chosen in Settings only; the button beside the iPodderX name is gone. +- Add a feed asks only for the feed; Popular and Directory in the sidebar are where you browse. +- On a phone, an item's files, with play and delete, sit above its show notes rather than below + them, where long notes left them looking missing. ### Fixed diff --git a/tests/ui/app.spec.js b/tests/ui/app.spec.js index 9c2735e..03a5a65 100644 --- a/tests/ui/app.spec.js +++ b/tests/ui/app.spec.js @@ -770,9 +770,10 @@ test('Popular lists what everyone here reads, but never a private feed', async ( await pick('tabs', 'All').click(); await expect(tiles).toHaveCount(dir.length); - // Add a feed opened over Directory fills its own list, not the pane behind it. + // Add a feed is for an address; Popular and Directory are where you browse (issue #30). await piper.locator('#addFeed').click(); - await expect(piper.locator('#modalCard .childrow', { hasText: 'Test Show' })).toBeVisible(); + await expect(piper.locator('#nurl')).toBeVisible(); + await expect(piper.locator('#modalCard .childrow')).toHaveCount(0); await expect(tiles).toHaveCount(dir.length); await piper.locator('#modalCard button[title="Cancel"]').click(); @@ -1022,3 +1023,20 @@ test('the pinned heading sits over its pins, and the page is set in Inter', asyn expect((await page.request.get('/inter.woff2')).headers()['content-type']).toBe('font/woff2'); expect(await page.evaluate(() => document.fonts.ready.then(() => document.fonts.check('14px Inter')))).toBe(true); }); + +test.describe('on a phone', () => { + test.use({ viewport: { width: 390, height: 844 }, hasTouch: true, isMobile: true }); + + test('a downloaded file can be deleted, from above the show notes', async ({ page }) => { + await page.locator('#burger').click(); + await page.locator('.feed', { hasText: 'Test Show' }).click(); + await page.locator('.tabs button', { hasText: 'Downloaded' }).first().click(); + await page.locator('.ep').first().click(); + const del = page.locator('#detail [data-a="del"]'); + await expect(del).toBeInViewport(); + // Below a long set of notes it was screens down and looked missing (issue #21). + expect(await page.locator('#detail').evaluate(d => + !!(d.querySelector('.encbox').compareDocumentPosition(d.querySelector('.dbody')) & Node.DOCUMENT_POSITION_FOLLOWING))) + .toBe(true); + }); +}); diff --git a/web/index.html b/web/index.html index a6d0471..9e4715b 100644 --- a/web/index.html +++ b/web/index.html @@ -296,6 +296,7 @@ input:focus,select:focus{outline:0;border-color:var(--accent)} .dt{font-size:18px;font-weight:650;margin:0 0 5px;line-height:1.3;overflow-wrap:anywhere} .dmeta{color:var(--faint);font-size:12.5px;display:flex;gap:8px;flex-wrap:wrap;align-items:center;margin-bottom:14px} .dmeta .btn{padding:3px 9px;font-size:12px} +#detail .encbox{margin:0 0 10px} .dbody{font-size:14.5px;line-height:1.65;overflow-wrap:anywhere;color:var(--fg)} .dbody img{max-width:100%;height:auto;border-radius:6px} .dbody a{color:var(--accent)} @@ -549,7 +550,7 @@ input[type=range]::-moz-range-thumb{width:12px;height:12px;border:0;border-radiu /* One pane at a time: the list, then the item over it. */ #split{grid-template-columns:1fr;grid-template-rows:1fr;grid-template-areas:"list"} - /* Title and date only; the files follow the item's text in the reader instead. */ + /* Title and date only; the files sit above the item's text in the reader instead. */ #files,.ephead,.ep .fd,.ep .file,.ep .size,.ep .rowacts{display:none} .ep,#split.one .ep{grid-template-columns:20px 20px minmax(0,1fr) auto} #grab{display:none} @@ -1396,7 +1397,9 @@ function showDetail(e){ return; } const encs=e.enclosures.map(encBox).join('')||'

No files

'; - // A phone has no room for the files pane, so the files follow the text there instead. + // A phone has no room for the files pane, so the files go above the text there instead. + // Below it, a long set of show notes pushed play and delete screens down, and on an iPhone + // it looked as if a downloaded file could not be deleted at all (issue #21). const narrow=!!window.matchMedia?.('(max-width:820px)')?.matches; const f=S.feeds.find(x=>x.id===e.feed_id); const num=[e.season?`S${e.season}`:'',e.episode?`E${e.episode}`:''].filter(Boolean).join(''); @@ -1414,8 +1417,8 @@ function showDetail(e){ ${e.link?`${ICON.open}`:''} -
${(e.description&&e.description.trim())||'No show notes.'}
- ${narrow?encs:''}`; + ${narrow?encs:''} +
${(e.description&&e.description.trim())||'No show notes.'}
`; if(files) files.innerHTML=narrow?'':`
Files
${encs}`; // description was sanitized server-side with ammonia before it ever reached here $('#dback').onclick=()=>showDetail(null); @@ -1794,12 +1797,9 @@ $('#addFeed').onclick=()=>{
Only items matching a keyword are downloaded.
-
-

Loading…

`); $('#nurl').focus(); - listFeeds('/api/popular',$('#npopular')); $('#nsave').onclick=async()=>{ const url=$('#nurl').value.trim(); if(!url) return; $('#nsave').disabled=true; $('#nsave').title='Adding…'; @@ -1814,8 +1814,7 @@ $('#addFeed').onclick=()=>{ }; // 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. The caller hands over the -// box: looked up by id, the Add a feed dialog's list landed in the Directory pane behind it. +// URL, so a key in someone's feed address never reaches this page. const NONE_LISTED='

Nothing yet. Feeds people here subscribe to show up here.

'; async function listFeeds(url,box){ let rows=[];