One file icon, green when downloaded; mark unread is an envelope
- The separate check (and warning) beside a file's type icon is gone: the type icon itself is green once the file is downloaded and red when the download failed, with the details in its tooltip. One icon per row keeps the column lined up. On Classic's blue selection they are a lighter green and red rather than white. - Mark unread under an item's title was a solid circle, which read as a record button. It is Font Awesome's closed envelope now. - Drops the unused circle-check, circle-exclamation and circle icons. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016HdTEWQNrzyFULijigkmMn
This commit is contained in:
@@ -37,10 +37,10 @@ The long form, with what was wrong before and how it was found, is in
|
|||||||
Download latest dialogs (save, download, cancel). The icons are Font Awesome Free, embedded as
|
Download latest dialogs (save, download, cancel). The icons are Font Awesome Free, embedded as
|
||||||
SVG: only the ones used, no font to download, and nothing fetched from anyone else. They
|
SVG: only the ones used, no font to download, and nothing fetched from anyone else. They
|
||||||
replace font characters such as ⟳ ⤓ ↗, which came out thin and tiny and differed from font to
|
replace font characters such as ⟳ ⤓ ↗, which came out thin and tiny and differed from font to
|
||||||
font. Keep is a flag everywhere, as it was in the original.
|
font. Keep is a flag everywhere, as it was in the original, and mark unread is an envelope.
|
||||||
- A file's state and type are icons: a check when it is downloaded, a warning when it failed
|
- A file's type is an icon (audio, video, image, PDF, torrent, other), green once it is
|
||||||
(the error is in the tooltip), and nothing while it waits; audio, video, image, PDF, torrent
|
downloaded and red when the download failed, with the details in its tooltip. One icon per
|
||||||
and other files each have their own. The DOWNLOADED and PENDING labels are gone.
|
row keeps the column lined up. The DOWNLOADED and PENDING labels are gone.
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ test('the three panes are there and the item text lands in the bottom one', asyn
|
|||||||
|
|
||||||
// Only the downloaded one gets a player, and max_new_per_check is 1, so find it by
|
// Only the downloaded one gets a player, and max_new_per_check is 1, so find it by
|
||||||
// its chip rather than assuming which episode the daemon happened to fetch.
|
// its chip rather than assuming which episode the daemon happened to fetch.
|
||||||
const downloaded = page.locator('.ep', { has: page.locator('[title="Downloaded"]') }).first();
|
const downloaded = page.locator('.ep', { has: page.locator('.kind.here') }).first();
|
||||||
await downloaded.click();
|
await downloaded.click();
|
||||||
await expect(page.locator('#files audio')).toBeVisible();
|
await expect(page.locator('#files audio')).toBeVisible();
|
||||||
await expect(page.locator('#files .encbox [title="Save to this computer"]')).toBeVisible();
|
await expect(page.locator('#files .encbox [title="Save to this computer"]')).toBeVisible();
|
||||||
@@ -110,9 +110,8 @@ test('a downloaded file that is not audio gets no player', async ({ page }) => {
|
|||||||
|
|
||||||
await expect(page.locator('#detail .dt')).toHaveText('An Article');
|
await expect(page.locator('#detail .dt')).toHaveText('An Article');
|
||||||
await expect(page.locator('#files audio')).toHaveCount(0);
|
await expect(page.locator('#files audio')).toHaveCount(0);
|
||||||
// What it is and that it is here, as icons with the words in their tooltips.
|
// What it is and that it is here: one icon, green, with the words in its tooltip.
|
||||||
await expect(page.locator('#files .encbox [title="image"]')).toBeVisible();
|
await expect(page.locator('#files .encbox .kind.here')).toHaveAttribute('title', 'image, downloaded');
|
||||||
await expect(page.locator('#files .encbox [title="Downloaded"]')).toBeVisible();
|
|
||||||
// Still offered as a file, just not as an episode: viewable and keepable.
|
// Still offered as a file, just not as an episode: viewable and keepable.
|
||||||
await expect(page.locator('#files [title="Save to this computer"]')).toBeVisible();
|
await expect(page.locator('#files [title="Save to this computer"]')).toBeVisible();
|
||||||
const view = page.locator('#files a[title="View in a new tab"]');
|
const view = page.locator('#files a[title="View in a new tab"]');
|
||||||
@@ -131,7 +130,7 @@ test('an item with several enclosures lists them all', async ({ page }) => {
|
|||||||
await row.click();
|
await row.click();
|
||||||
// The Files pane lists every one: the audio and the image.
|
// The Files pane lists every one: the audio and the image.
|
||||||
await expect(page.locator('#files .encbox')).toHaveCount(2);
|
await expect(page.locator('#files .encbox')).toHaveCount(2);
|
||||||
await expect(page.locator('#files .encbox').nth(1).locator('[title="image"]')).toBeVisible();
|
await expect(page.locator('#files .encbox').nth(1).locator('.kind[title^="image"]')).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('the filter tabs change what is listed', async ({ page }) => {
|
test('the filter tabs change what is listed', async ({ page }) => {
|
||||||
@@ -674,7 +673,7 @@ test('a deleted file looks as if it was never downloaded', async ({ page }) => {
|
|||||||
await page.locator('#files button[data-a="del"]').click();
|
await page.locator('#files button[data-a="del"]').click();
|
||||||
|
|
||||||
// No "reaped", no chip at all: just the way to get it again.
|
// No "reaped", no chip at all: just the way to get it again.
|
||||||
await expect(row.locator('[title="Downloaded"]')).toHaveCount(0);
|
await expect(row.locator('.kind.here')).toHaveCount(0);
|
||||||
await expect(row).not.toContainText(/reaped/i);
|
await expect(row).not.toContainText(/reaped/i);
|
||||||
await row.click();
|
await row.click();
|
||||||
await expect(page.locator('#files')).not.toContainText(/reaped/i);
|
await expect(page.locator('#files')).not.toContainText(/reaped/i);
|
||||||
|
|||||||
@@ -238,11 +238,11 @@ a.btn{text-decoration:none;color:inherit}
|
|||||||
.btn.ico{padding:4px 9px;min-width:32px;font-size:14px;line-height:1.25;text-align:center}
|
.btn.ico{padding:4px 9px;min-width:32px;font-size:14px;line-height:1.25;text-align:center}
|
||||||
/* An icon (Font Awesome, embedded as SVG) in the button's own colour. */
|
/* An icon (Font Awesome, embedded as SVG) in the button's own colour. */
|
||||||
.i{display:inline-block;width:16px;height:16px;vertical-align:-3px;flex:none;fill:currentColor}
|
.i{display:inline-block;width:16px;height:16px;vertical-align:-3px;flex:none;fill:currentColor}
|
||||||
/* A file's state and type, as icons in place of the old DOWNLOADED / PENDING / audio chips. */
|
/* A file's type as an icon, in place of the old DOWNLOADED / PENDING / audio chips: green once
|
||||||
.fst,.kind{display:inline-grid;place-items:center}
|
it is here, red when the download failed. */
|
||||||
.fst{color:var(--good)}
|
.kind{display:inline-grid;place-items:center;color:var(--dim)}
|
||||||
.fst.bad{color:var(--bad)}
|
.kind.here{color:var(--good)}
|
||||||
.kind{color:var(--dim)}
|
.kind.bad{color:var(--bad)}
|
||||||
.fhead .art .i{width:22px;height:22px}
|
.fhead .art .i{width:22px;height:22px}
|
||||||
.toolbar{
|
.toolbar{
|
||||||
display:flex;gap:10px;align-items:center;margin-bottom:12px;flex-wrap:wrap;
|
display:flex;gap:10px;align-items:center;margin-bottom:12px;flex-wrap:wrap;
|
||||||
@@ -503,8 +503,10 @@ input[type=range]::-moz-range-thumb{width:12px;height:12px;border:0;border-radiu
|
|||||||
:root[data-theme="classic"] .ep.sel .st,
|
:root[data-theme="classic"] .ep.sel .st,
|
||||||
:root[data-theme="classic"] .ep.sel .fl,
|
:root[data-theme="classic"] .ep.sel .fl,
|
||||||
:root[data-theme="classic"] .ep.sel .file,
|
:root[data-theme="classic"] .ep.sel .file,
|
||||||
:root[data-theme="classic"] .ep.sel .fst,
|
|
||||||
:root[data-theme="classic"] .ep.sel .kind{color:#fff}
|
:root[data-theme="classic"] .ep.sel .kind{color:#fff}
|
||||||
|
/* Green and red stay green and red on the blue, just lighter so they read. */
|
||||||
|
:root[data-theme="classic"] .ep.sel .kind.here{color:#a6f3a6}
|
||||||
|
:root[data-theme="classic"] .ep.sel .kind.bad{color:#ffb8ad}
|
||||||
/* Lists were white in the original; the pale blue-grey belongs to the source list alone. */
|
/* Lists were white in the original; the pale blue-grey belongs to the source list alone. */
|
||||||
:root[data-theme="classic"] .childrow{background:#fff}
|
:root[data-theme="classic"] .childrow{background:#fff}
|
||||||
:root[data-theme="classic"] .dt{background:linear-gradient(#80aae6,#3f78cf);color:#fff;padding:6px 12px;border-radius:4px}
|
:root[data-theme="classic"] .dt{background:linear-gradient(#80aae6,#3f78cf);color:#fff;padding:6px 12px;border-radius:4px}
|
||||||
@@ -616,9 +618,7 @@ const ICON={
|
|||||||
directory:fa('0 0 448 512','<path fill="currentColor" d="M0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 64l0 320c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96zm64 0l0 64 64 0 0-64-64 0zm320 0l-192 0 0 64 192 0 0-64zM64 224l0 64 64 0 0-64-64 0zm320 0l-192 0 0 64 192 0 0-64zM64 352l0 64 64 0 0-64-64 0zm320 0l-192 0 0 64 192 0 0-64z"/>'), // solid/table-list
|
directory:fa('0 0 448 512','<path fill="currentColor" d="M0 96C0 60.7 28.7 32 64 32l320 0c35.3 0 64 28.7 64 64l0 320c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96zm64 0l0 64 64 0 0-64-64 0zm320 0l-192 0 0 64 192 0 0-64zM64 224l0 64 64 0 0-64-64 0zm320 0l-192 0 0 64 192 0 0-64zM64 352l0 64 64 0 0-64-64 0zm320 0l-192 0 0 64 192 0 0-64z"/>'), // solid/table-list
|
||||||
popular:fa('0 0 576 512','<path fill="currentColor" d="M309.5-18.9c-4.1-8-12.4-13.1-21.4-13.1s-17.3 5.1-21.4 13.1L193.1 125.3 33.2 150.7c-8.9 1.4-16.3 7.7-19.1 16.3s-.5 18 5.8 24.4l114.4 114.5-25.2 159.9c-1.4 8.9 2.3 17.9 9.6 23.2s16.9 6.1 25 2L288.1 417.6 432.4 491c8 4.1 17.7 3.3 25-2s11-14.2 9.6-23.2L441.7 305.9 556.1 191.4c6.4-6.4 8.6-15.8 5.8-24.4s-10.1-14.9-19.1-16.3L383 125.3 309.5-18.9z"/>'), // solid/star
|
popular:fa('0 0 576 512','<path fill="currentColor" d="M309.5-18.9c-4.1-8-12.4-13.1-21.4-13.1s-17.3 5.1-21.4 13.1L193.1 125.3 33.2 150.7c-8.9 1.4-16.3 7.7-19.1 16.3s-.5 18 5.8 24.4l114.4 114.5-25.2 159.9c-1.4 8.9 2.3 17.9 9.6 23.2s16.9 6.1 25 2L288.1 417.6 432.4 491c8 4.1 17.7 3.3 25-2s11-14.2 9.6-23.2L441.7 305.9 556.1 191.4c6.4-6.4 8.6-15.8 5.8-24.4s-10.1-14.9-19.1-16.3L383 125.3 309.5-18.9z"/>'), // solid/star
|
||||||
all:fa('0 0 512 512','<path fill="currentColor" d="M232.5 5.2c14.9-6.9 32.1-6.9 47 0l218.6 101c8.5 3.9 13.9 12.4 13.9 21.8s-5.4 17.9-13.9 21.8l-218.6 101c-14.9 6.9-32.1 6.9-47 0L13.9 149.8C5.4 145.8 0 137.3 0 128s5.4-17.9 13.9-21.8L232.5 5.2zM48.1 218.4l164.3 75.9c27.7 12.8 59.6 12.8 87.3 0l164.3-75.9 34.1 15.8c8.5 3.9 13.9 12.4 13.9 21.8s-5.4 17.9-13.9 21.8l-218.6 101c-14.9 6.9-32.1 6.9-47 0L13.9 277.8C5.4 273.8 0 265.3 0 256s5.4-17.9 13.9-21.8l34.1-15.8zM13.9 362.2l34.1-15.8 164.3 75.9c27.7 12.8 59.6 12.8 87.3 0l164.3-75.9 34.1 15.8c8.5 3.9 13.9 12.4 13.9 21.8s-5.4 17.9-13.9 21.8l-218.6 101c-14.9 6.9-32.1 6.9-47 0L13.9 405.8C5.4 401.8 0 393.3 0 384s5.4-17.9 13.9-21.8z"/>'), // solid/layer-group
|
all:fa('0 0 512 512','<path fill="currentColor" d="M232.5 5.2c14.9-6.9 32.1-6.9 47 0l218.6 101c8.5 3.9 13.9 12.4 13.9 21.8s-5.4 17.9-13.9 21.8l-218.6 101c-14.9 6.9-32.1 6.9-47 0L13.9 149.8C5.4 145.8 0 137.3 0 128s5.4-17.9 13.9-21.8L232.5 5.2zM48.1 218.4l164.3 75.9c27.7 12.8 59.6 12.8 87.3 0l164.3-75.9 34.1 15.8c8.5 3.9 13.9 12.4 13.9 21.8s-5.4 17.9-13.9 21.8l-218.6 101c-14.9 6.9-32.1 6.9-47 0L13.9 277.8C5.4 273.8 0 265.3 0 256s5.4-17.9 13.9-21.8l34.1-15.8zM13.9 362.2l34.1-15.8 164.3 75.9c27.7 12.8 59.6 12.8 87.3 0l164.3-75.9 34.1 15.8c8.5 3.9 13.9 12.4 13.9 21.8s-5.4 17.9-13.9 21.8l-218.6 101c-14.9 6.9-32.1 6.9-47 0L13.9 405.8C5.4 401.8 0 393.3 0 384s5.4-17.9 13.9-21.8z"/>'), // solid/layer-group
|
||||||
dot:fa('0 0 512 512','<path fill="currentColor" d="M0 256a256 256 0 1 1 512 0 256 256 0 1 1 -512 0z"/>'), // solid/circle
|
unread:fa('0 0 512 512','<path fill="currentColor" d="M48 64c-26.5 0-48 21.5-48 48 0 15.1 7.1 29.3 19.2 38.4l208 156c17.1 12.8 40.5 12.8 57.6 0l208-156c12.1-9.1 19.2-23.3 19.2-38.4 0-26.5-21.5-48-48-48L48 64zM0 196L0 384c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-188-198.4 148.8c-34.1 25.6-81.1 25.6-115.2 0L0 196z"/>'), // solid/envelope: a closed letter, not a record button
|
||||||
done:fa('0 0 512 512','<path fill="currentColor" d="M256 512a256 256 0 1 1 0-512 256 256 0 1 1 0 512zM374 145.7c-10.7-7.8-25.7-5.4-33.5 5.3L221.1 315.2 169 263.1c-9.4-9.4-24.6-9.4-33.9 0s-9.4 24.6 0 33.9l72 72c5 5 11.8 7.5 18.8 7s13.4-4.1 17.5-9.8L379.3 179.2c7.8-10.7 5.4-25.7-5.3-33.5z"/>'), // solid/circle-check
|
|
||||||
alert:fa('0 0 512 512','<path fill="currentColor" d="M256 512a256 256 0 1 1 0-512 256 256 0 1 1 0 512zm0-192a32 32 0 1 0 0 64 32 32 0 1 0 0-64zm0-192c-18.2 0-32.7 15.5-31.4 33.7l7.4 104c.9 12.6 11.4 22.3 23.9 22.3 12.6 0 23-9.7 23.9-22.3l7.4-104c1.3-18.2-13.1-33.7-31.4-33.7z"/>'), // solid/circle-exclamation
|
|
||||||
audio:fa('0 0 448 512','<path fill="currentColor" d="M64 224c0-88.4 71.6-160 160-160s160 71.6 160 160l0 37.5c-10-3.5-20.8-5.5-32-5.5l-16 0c-26.5 0-48 21.5-48 48l0 128c0 26.5 21.5 48 48 48l16 0c53 0 96-43 96-96l0-160C448 100.3 347.7 0 224 0S0 100.3 0 224L0 384c0 53 43 96 96 96l16 0c26.5 0 48-21.5 48-48l0-128c0-26.5-21.5-48-48-48l-16 0c-11.2 0-22 1.9-32 5.5L64 224z"/>'), // solid/headphones
|
audio:fa('0 0 448 512','<path fill="currentColor" d="M64 224c0-88.4 71.6-160 160-160s160 71.6 160 160l0 37.5c-10-3.5-20.8-5.5-32-5.5l-16 0c-26.5 0-48 21.5-48 48l0 128c0 26.5 21.5 48 48 48l16 0c53 0 96-43 96-96l0-160C448 100.3 347.7 0 224 0S0 100.3 0 224L0 384c0 53 43 96 96 96l16 0c26.5 0 48-21.5 48-48l0-128c0-26.5-21.5-48-48-48l-16 0c-11.2 0-22 1.9-32 5.5L64 224z"/>'), // solid/headphones
|
||||||
video:fa('0 0 576 512','<path fill="currentColor" d="M96 64c-35.3 0-64 28.7-64 64l0 256c0 35.3 28.7 64 64 64l256 0c35.3 0 64-28.7 64-64l0-256c0-35.3-28.7-64-64-64L96 64zM464 336l73.5 58.8c4.2 3.4 9.4 5.2 14.8 5.2 13.1 0 23.7-10.6 23.7-23.7l0-240.6c0-13.1-10.6-23.7-23.7-23.7-5.4 0-10.6 1.8-14.8 5.2L464 176 464 336z"/>'), // solid/video
|
video:fa('0 0 576 512','<path fill="currentColor" d="M96 64c-35.3 0-64 28.7-64 64l0 256c0 35.3 28.7 64 64 64l256 0c35.3 0 64-28.7 64-64l0-256c0-35.3-28.7-64-64-64L96 64zM464 336l73.5 58.8c4.2 3.4 9.4 5.2 14.8 5.2 13.1 0 23.7-10.6 23.7-23.7l0-240.6c0-13.1-10.6-23.7-23.7-23.7-5.4 0-10.6 1.8-14.8 5.2L464 176 464 336z"/>'), // solid/video
|
||||||
image:fa('0 0 448 512','<path fill="currentColor" d="M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zm64 80a48 48 0 1 1 0 96 48 48 0 1 1 0-96zM272 224c8.4 0 16.1 4.4 20.5 11.5l88 144c4.5 7.4 4.7 16.7 .5 24.3S368.7 416 360 416L88 416c-8.9 0-17.2-5-21.3-12.9s-3.5-17.5 1.6-24.8l56-80c4.5-6.4 11.8-10.2 19.7-10.2s15.2 3.8 19.7 10.2l26.4 37.8 61.4-100.5c4.4-7.1 12.1-11.5 20.5-11.5z"/>'), // solid/image
|
image:fa('0 0 448 512','<path fill="currentColor" d="M64 32C28.7 32 0 60.7 0 96L0 416c0 35.3 28.7 64 64 64l320 0c35.3 0 64-28.7 64-64l0-320c0-35.3-28.7-64-64-64L64 32zm64 80a48 48 0 1 1 0 96 48 48 0 1 1 0-96zM272 224c8.4 0 16.1 4.4 20.5 11.5l88 144c4.5 7.4 4.7 16.7 .5 24.3S368.7 416 360 416L88 416c-8.9 0-17.2-5-21.3-12.9s-3.5-17.5 1.6-24.8l56-80c4.5-6.4 11.8-10.2 19.7-10.2s15.2 3.8 19.7 10.2l26.4 37.8 61.4-100.5c4.4-7.1 12.1-11.5 20.5-11.5z"/>'), // solid/image
|
||||||
@@ -973,7 +973,7 @@ function epEl(e){
|
|||||||
</div>
|
</div>
|
||||||
<span class="fd">${esc(feedName(e.feed_id))}</span>
|
<span class="fd">${esc(feedName(e.feed_id))}</span>
|
||||||
<div class="file">
|
<div class="file">
|
||||||
${enc?stateIcon(enc)+kindIcon(enc):''}
|
${enc?kindIcon(enc):''}
|
||||||
${enc&&enc.length?`<span>${mb(enc.length)}</span>`:''}
|
${enc&&enc.length?`<span>${mb(enc.length)}</span>`:''}
|
||||||
${enc&&!has?`<div class="dlbar" data-bar="${enc.id}"><i></i></div>`:''}
|
${enc&&!has?`<div class="dlbar" data-bar="${enc.id}"><i></i></div>`:''}
|
||||||
</div>
|
</div>
|
||||||
@@ -1013,20 +1013,16 @@ function kindOf(enc){
|
|||||||
return (ext && ext.length<=5) ? ext.toLowerCase() : 'file';
|
return (ext && ext.length<=5) ? ext.toLowerCase() : 'file';
|
||||||
}
|
}
|
||||||
|
|
||||||
/// What a file is, as an icon; the word is in its tooltip.
|
/// What a file is, as one icon coloured by whether it is here: green once downloaded, red when
|
||||||
|
/// the download failed, plain otherwise, so a file waiting and one deleted read alike. One icon
|
||||||
|
/// either way keeps the column lined up; the words are in its tooltip.
|
||||||
function kindIcon(enc){
|
function kindIcon(enc){
|
||||||
const k=kindOf(enc);
|
const k=kindOf(enc);
|
||||||
const i={audio:ICON.audio,video:ICON.video,image:ICON.image,pdf:ICON.doc,torrent:ICON.torrent}[k]||ICON.file;
|
const i={audio:ICON.audio,video:ICON.video,image:ICON.image,pdf:ICON.doc,torrent:ICON.torrent}[k]||ICON.file;
|
||||||
return `<span class="kind" title="${esc(k)}" aria-label="${esc(k)}">${i}</span>`;
|
const [cls,label]=enc.path ? [' here',`${k}, downloaded`]
|
||||||
}
|
: enc.state==='error' ? [' bad',`${k}, download failed${enc.last_error?': '+enc.last_error:''}`]
|
||||||
|
: ['',k];
|
||||||
/// Whether a file is here, as an icon: a check when downloaded, a warning when it failed, and
|
return `<span class="kind${cls}" title="${esc(label)}" aria-label="${esc(label)}">${i}</span>`;
|
||||||
/// nothing otherwise, so a file waiting to download and one deleted to save space read alike.
|
|
||||||
function stateIcon(enc){
|
|
||||||
if(enc.path) return `<span class="fst" title="Downloaded" aria-label="Downloaded">${ICON.done}</span>`;
|
|
||||||
if(enc.state!=='error') return '';
|
|
||||||
const why=esc(enc.last_error||'Download failed');
|
|
||||||
return `<span class="fst bad" title="${why}" aria-label="${why}">${ICON.alert}</span>`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function feedArt(id=S.feed){ const f=S.feeds.find(x=>x.id===id); return f&&f.image; }
|
function feedArt(id=S.feed){ const f=S.feeds.find(x=>x.id===id); return f&&f.image; }
|
||||||
@@ -1118,7 +1114,7 @@ function showDetail(e){
|
|||||||
<span>${dateOf(e.published)}</span>
|
<span>${dateOf(e.published)}</span>
|
||||||
${e.duration?`<span class="dot"></span><span>${clock(e.duration)}</span>`:''}
|
${e.duration?`<span class="dot"></span><span>${clock(e.duration)}</span>`:''}
|
||||||
<button class="btn ico" data-a="read" title="Mark ${e.read?'unread':'read'}"
|
<button class="btn ico" data-a="read" title="Mark ${e.read?'unread':'read'}"
|
||||||
aria-label="Mark ${e.read?'unread':'read'}">${e.read?ICON.dot:ICON.check}</button>
|
aria-label="Mark ${e.read?'unread':'read'}">${e.read?ICON.unread:ICON.check}</button>
|
||||||
<button class="btn ico" data-a="flag" title="${e.flagged?'Kept: never deleted. Stop keeping':'Keep, so it is never deleted'}"
|
<button class="btn ico" data-a="flag" title="${e.flagged?'Kept: never deleted. Stop keeping':'Keep, so it is never deleted'}"
|
||||||
aria-label="${e.flagged?'Stop keeping':'Keep'}">${e.flagged?ICON.flagOn:ICON.flag}</button>
|
aria-label="${e.flagged?'Stop keeping':'Keep'}">${e.flagged?ICON.flagOn:ICON.flag}</button>
|
||||||
${e.link?`<a class="btn ico" href="${esc(e.link)}" target="_blank" rel="noopener noreferrer"
|
${e.link?`<a class="btn ico" href="${esc(e.link)}" target="_blank" rel="noopener noreferrer"
|
||||||
@@ -1152,7 +1148,7 @@ function encBox(x){
|
|||||||
if(x.path && !isPlayable(x)){
|
if(x.path && !isPlayable(x)){
|
||||||
// On disk, but not audio or video: view it, keep it, or remove it -- no player.
|
// On disk, but not audio or video: view it, keep it, or remove it -- no player.
|
||||||
return `<div class="encbox">
|
return `<div class="encbox">
|
||||||
${kindIcon(x)}${stateIcon(x)}
|
${kindIcon(x)}
|
||||||
<span class="meta" style="flex:1">${size}</span>
|
<span class="meta" style="flex:1">${size}</span>
|
||||||
<a class="btn ico" href="/media/${x.id}" target="_blank" rel="noopener noreferrer" title="View in a new tab" aria-label="View in a new tab">${ICON.open}</a>
|
<a class="btn ico" href="/media/${x.id}" target="_blank" rel="noopener noreferrer" title="View in a new tab" aria-label="View in a new tab">${ICON.open}</a>
|
||||||
${saveBtn}
|
${saveBtn}
|
||||||
@@ -1172,7 +1168,7 @@ function encBox(x){
|
|||||||
// through here, which would make ipx a fetch-anything relay.
|
// through here, which would make ipx a fetch-anything relay.
|
||||||
const viewable = !isPlayable(x) && x.state !== 'pending';
|
const viewable = !isPlayable(x) && x.state !== 'pending';
|
||||||
return `<div class="encbox">
|
return `<div class="encbox">
|
||||||
${kindIcon(x)}${stateIcon(x)}
|
${kindIcon(x)}
|
||||||
<span class="meta" style="flex:1">${size}</span>
|
<span class="meta" style="flex:1">${size}</span>
|
||||||
${x.state==='error'&&x.last_error?`<span class="err">${esc(x.last_error)}</span>`:''}
|
${x.state==='error'&&x.last_error?`<span class="err">${esc(x.last_error)}</span>`:''}
|
||||||
${viewable?`<a class="btn ico" href="${esc(x.url)}" target="_blank" rel="noopener noreferrer" title="View in a new tab" aria-label="View in a new tab">${ICON.open}</a>`:''}
|
${viewable?`<a class="btn ico" href="${esc(x.url)}" target="_blank" rel="noopener noreferrer" title="View in a new tab" aria-label="View in a new tab">${ICON.open}</a>`:''}
|
||||||
|
|||||||
Reference in New Issue
Block a user