kryten-webqueue 0.7.1__tar.gz → 0.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/CHANGELOG.md +3 -3
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/PKG-INFO +1 -1
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/catalog/db.py +30 -26
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/queue/shadow.py +5 -7
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/static/css/main.css +39 -48
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/queue/index.html +7 -13
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/pyproject.toml +1 -1
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/.github/workflows/python-publish.yml +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/.github/workflows/release.yml +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/.gitignore +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/README.md +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/config.example.json +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/deploy/kryten-webqueue.service +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/deploy/nginx-queue.conf +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/docs/IMPLEMENTATION_SPEC.md +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/docs/IMPL_API_GATE.md +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/docs/IMPL_ECONOMY.md +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/docs/IMPL_KRYTEN_PY.md +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/docs/IMPL_ROBOT.md +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/docs/PRE_PLAN_GAPS.md +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/docs/PRODUCT_PLAN.md +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/__init__.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/__main__.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/api_gate/__init__.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/api_gate/client.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/app.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/auth/__init__.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/auth/otp.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/auth/rate_limit.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/auth/session.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/catalog/__init__.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/catalog/images.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/catalog/sync.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/config.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/jobs/__init__.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/jobs/manager.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/playlists/__init__.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/playlists/fire.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/playlists/importer.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/playlists/scheduler.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/queue/__init__.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/queue/ordering.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/queue/poller.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/routes/__init__.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/routes/admin_jobs.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/routes/admin_playlists.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/routes/admin_queue.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/routes/admin_schedules.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/routes/auth.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/routes/catalog.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/routes/pages.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/routes/queue.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/routes/user.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/static/js/main.js +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/admin/index.html +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/admin/playlists.html +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/admin/queue_mgmt.html +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/admin/schedules.html +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/auth/login.html +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/base.html +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/catalog/browse.html +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/catalog/item_detail.html +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/catalog/item_not_found.html +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/user/dashboard.html +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/ws/__init__.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/ws/handler.py +0 -0
- {kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/ws/manager.py +0 -0
|
@@ -4,12 +4,12 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
-
## [0.7.
|
|
7
|
+
## [0.7.2] - 2026-06-08
|
|
8
8
|
|
|
9
9
|
### Changed
|
|
10
10
|
|
|
11
|
-
- **Now Playing
|
|
12
|
-
- **"Hide Previous" now defaults to
|
|
11
|
+
- **Now Playing card redesigned for readability.** The card is now a vertical stack: the title spans the full width across the top (with a divider), then a row pairs a 2:3 poster with the time display, the progress bar, and the **Remaining** time directly under the bar. Below that, the item **description** and **category/tag chips** are shown when available. The now-playing state is enriched server-side with the catalog description and category/tag names for the playing item.
|
|
12
|
+
- **"Hide Previous" now defaults to on** so the Queue page opens focused on what's still to come.
|
|
13
13
|
|
|
14
14
|
## [0.7.0] - 2026-06-08
|
|
15
15
|
|
|
@@ -374,31 +374,6 @@ class Database:
|
|
|
374
374
|
async def get_item_admin(self, friendly_token: str) -> dict | None:
|
|
375
375
|
return await self._fetch_one("SELECT * FROM catalog WHERE friendly_token = ?", [friendly_token])
|
|
376
376
|
|
|
377
|
-
async def get_item_facets(self, friendly_token: str) -> dict:
|
|
378
|
-
"""Return category and tag names for a single catalog item."""
|
|
379
|
-
cats = await self._fetch_all(
|
|
380
|
-
"""
|
|
381
|
-
SELECT cat.name FROM catalog_categories cc
|
|
382
|
-
JOIN categories cat ON cc.category_id = cat.id
|
|
383
|
-
WHERE cc.friendly_token = ?
|
|
384
|
-
ORDER BY cat.name
|
|
385
|
-
""",
|
|
386
|
-
[friendly_token],
|
|
387
|
-
)
|
|
388
|
-
tags = await self._fetch_all(
|
|
389
|
-
"""
|
|
390
|
-
SELECT t.name FROM catalog_tags ct
|
|
391
|
-
JOIN tags t ON ct.tag_id = t.id
|
|
392
|
-
WHERE ct.friendly_token = ?
|
|
393
|
-
ORDER BY t.name
|
|
394
|
-
""",
|
|
395
|
-
[friendly_token],
|
|
396
|
-
)
|
|
397
|
-
return {
|
|
398
|
-
"categories": [c["name"] for c in cats],
|
|
399
|
-
"tags": [t["name"] for t in tags],
|
|
400
|
-
}
|
|
401
|
-
|
|
402
377
|
async def get_catalog_brief(self, tokens: list[str], manifest_urls: list[str]) -> dict[str, dict]:
|
|
403
378
|
"""Return a lookup of catalog metadata keyed by BOTH friendly_token and
|
|
404
379
|
manifest_url, for enriching queue-shadow items that may only carry one.
|
|
@@ -408,7 +383,7 @@ class Database:
|
|
|
408
383
|
return {}
|
|
409
384
|
placeholders = ",".join("?" * len(keys))
|
|
410
385
|
rows = await self._fetch_all(
|
|
411
|
-
"SELECT friendly_token, manifest_url, title,
|
|
386
|
+
"SELECT friendly_token, manifest_url, title, duration_sec, "
|
|
412
387
|
"cover_art_path, thumbnail_url FROM catalog "
|
|
413
388
|
f"WHERE friendly_token IN ({placeholders}) OR manifest_url IN ({placeholders})",
|
|
414
389
|
keys + keys,
|
|
@@ -422,6 +397,35 @@ class Database:
|
|
|
422
397
|
lookup[data["manifest_url"]] = data
|
|
423
398
|
return lookup
|
|
424
399
|
|
|
400
|
+
async def get_item_facets(self, friendly_token: str) -> dict:
|
|
401
|
+
"""Return description + category/tag names for a single catalog item.
|
|
402
|
+
|
|
403
|
+
Used to enrich the now-playing card. Returns empty values when the
|
|
404
|
+
token is unknown.
|
|
405
|
+
"""
|
|
406
|
+
if not friendly_token:
|
|
407
|
+
return {"description": None, "categories": [], "tags": []}
|
|
408
|
+
row = await self._fetch_one(
|
|
409
|
+
"SELECT description FROM catalog WHERE friendly_token = ?", [friendly_token]
|
|
410
|
+
)
|
|
411
|
+
cats = await self._fetch_all(
|
|
412
|
+
"SELECT cat.name FROM categories cat "
|
|
413
|
+
"JOIN catalog_categories cc ON cc.category_id = cat.id "
|
|
414
|
+
"WHERE cc.friendly_token = ? ORDER BY cat.name",
|
|
415
|
+
[friendly_token],
|
|
416
|
+
)
|
|
417
|
+
tags = await self._fetch_all(
|
|
418
|
+
"SELECT t.name FROM tags t "
|
|
419
|
+
"JOIN catalog_tags ct ON ct.tag_id = t.id "
|
|
420
|
+
"WHERE ct.friendly_token = ? ORDER BY t.name",
|
|
421
|
+
[friendly_token],
|
|
422
|
+
)
|
|
423
|
+
return {
|
|
424
|
+
"description": (row or {}).get("description"),
|
|
425
|
+
"categories": [c["name"] for c in cats],
|
|
426
|
+
"tags": [t["name"] for t in tags],
|
|
427
|
+
}
|
|
428
|
+
|
|
425
429
|
async def is_restricted(self, friendly_token: str) -> bool:
|
|
426
430
|
sql = """
|
|
427
431
|
SELECT 1 FROM saved_playlist_items spi
|
|
@@ -201,8 +201,6 @@ class QueueShadow:
|
|
|
201
201
|
if meta:
|
|
202
202
|
np.setdefault("cover_art_path", meta.get("cover_art_path"))
|
|
203
203
|
np.setdefault("thumbnail_url", meta.get("thumbnail_url"))
|
|
204
|
-
if not np.get("description"):
|
|
205
|
-
np["description"] = meta.get("description")
|
|
206
204
|
if not np.get("friendly_token"):
|
|
207
205
|
np["friendly_token"] = meta.get("friendly_token")
|
|
208
206
|
# Ensure now-playing carries a playlist uid so the frontend can
|
|
@@ -219,15 +217,15 @@ class QueueShadow:
|
|
|
219
217
|
):
|
|
220
218
|
np["uid"] = it.get("uid")
|
|
221
219
|
break
|
|
222
|
-
# Attach category/tag
|
|
223
|
-
|
|
224
|
-
if ft:
|
|
220
|
+
# Attach description + category/tag names for the now-playing card.
|
|
221
|
+
if np.get("friendly_token"):
|
|
225
222
|
try:
|
|
226
|
-
facets = await db.get_item_facets(
|
|
223
|
+
facets = await db.get_item_facets(np["friendly_token"])
|
|
224
|
+
np.setdefault("description", facets.get("description"))
|
|
227
225
|
np["categories"] = facets.get("categories") or []
|
|
228
226
|
np["tags"] = facets.get("tags") or []
|
|
229
227
|
except Exception:
|
|
230
|
-
logger.debug("Failed to
|
|
228
|
+
logger.debug("Failed to enrich now-playing facets", exc_info=True)
|
|
231
229
|
state["now_playing"] = np
|
|
232
230
|
|
|
233
231
|
return state
|
|
@@ -325,27 +325,26 @@ a:hover {
|
|
|
325
325
|
border: 1px solid var(--accent);
|
|
326
326
|
box-shadow: 0 0 0 1px rgba(108, 92, 231, 0.25), 0 6px 18px rgba(108, 92, 231, 0.18);
|
|
327
327
|
}
|
|
328
|
-
/* Title spans the full card
|
|
328
|
+
/* Title spans the full width of the card. */
|
|
329
329
|
.np-title {
|
|
330
330
|
margin: 0;
|
|
331
331
|
font-size: 1.4rem;
|
|
332
332
|
line-height: 1.25;
|
|
333
333
|
overflow-wrap: anywhere;
|
|
334
|
-
border-bottom: 1px solid var(--border);
|
|
335
334
|
padding-bottom: 0.75rem;
|
|
335
|
+
border-bottom: 1px solid var(--border);
|
|
336
336
|
}
|
|
337
|
-
/*
|
|
337
|
+
/* Image + time display sit side by side. */
|
|
338
338
|
.np-body {
|
|
339
339
|
display: flex;
|
|
340
340
|
gap: 1.25rem;
|
|
341
|
-
align-items:
|
|
341
|
+
align-items: flex-start;
|
|
342
342
|
}
|
|
343
|
-
.np-
|
|
343
|
+
.np-info {
|
|
344
344
|
flex: 1;
|
|
345
345
|
min-width: 0;
|
|
346
346
|
display: flex;
|
|
347
347
|
flex-direction: column;
|
|
348
|
-
justify-content: flex-start;
|
|
349
348
|
gap: 0.5rem;
|
|
350
349
|
}
|
|
351
350
|
.np-progress {
|
|
@@ -360,43 +359,9 @@ a:hover {
|
|
|
360
359
|
transition: width 1s linear;
|
|
361
360
|
}
|
|
362
361
|
.np-time {
|
|
363
|
-
font-size:
|
|
362
|
+
font-size: 1rem;
|
|
364
363
|
color: var(--text-primary);
|
|
365
|
-
|
|
366
|
-
/* Details below the poster/time row: category + tag chips, then description. */
|
|
367
|
-
.np-details {
|
|
368
|
-
border-top: 1px solid var(--border);
|
|
369
|
-
padding-top: 0.75rem;
|
|
370
|
-
display: flex;
|
|
371
|
-
flex-direction: column;
|
|
372
|
-
gap: 0.6rem;
|
|
373
|
-
}
|
|
374
|
-
.np-facets {
|
|
375
|
-
display: flex;
|
|
376
|
-
flex-wrap: wrap;
|
|
377
|
-
gap: 0.4rem;
|
|
378
|
-
}
|
|
379
|
-
.np-chip {
|
|
380
|
-
font-size: 0.7rem;
|
|
381
|
-
padding: 0.15rem 0.5rem;
|
|
382
|
-
border-radius: 999px;
|
|
383
|
-
white-space: nowrap;
|
|
384
|
-
}
|
|
385
|
-
.np-chip-cat {
|
|
386
|
-
background: var(--accent);
|
|
387
|
-
color: #fff;
|
|
388
|
-
}
|
|
389
|
-
.np-chip-tag {
|
|
390
|
-
background: var(--bg-elevated, #2a2a38);
|
|
391
|
-
color: var(--text-secondary);
|
|
392
|
-
border: 1px solid var(--border);
|
|
393
|
-
}
|
|
394
|
-
.np-description {
|
|
395
|
-
font-size: 0.85rem;
|
|
396
|
-
line-height: 1.5;
|
|
397
|
-
color: var(--text-secondary);
|
|
398
|
-
margin: 0;
|
|
399
|
-
overflow-wrap: anywhere;
|
|
364
|
+
font-variant-numeric: tabular-nums;
|
|
400
365
|
}
|
|
401
366
|
|
|
402
367
|
.queue-list {
|
|
@@ -524,18 +489,44 @@ a:hover {
|
|
|
524
489
|
color: var(--text-secondary);
|
|
525
490
|
}
|
|
526
491
|
.np-meta {
|
|
492
|
+
font-size: 0.85rem;
|
|
493
|
+
color: var(--text-secondary);
|
|
494
|
+
}
|
|
495
|
+
.np-remaining {
|
|
527
496
|
font-size: 0.9rem;
|
|
528
497
|
color: var(--text-secondary);
|
|
529
|
-
|
|
498
|
+
font-variant-numeric: tabular-nums;
|
|
530
499
|
}
|
|
531
|
-
.
|
|
500
|
+
/* Description + category/tag chips sit below the image / time row. */
|
|
501
|
+
.np-description {
|
|
532
502
|
font-size: 0.9rem;
|
|
533
|
-
|
|
503
|
+
line-height: 1.5;
|
|
504
|
+
color: var(--text-secondary);
|
|
505
|
+
padding-top: 0.75rem;
|
|
506
|
+
border-top: 1px solid var(--border);
|
|
507
|
+
white-space: pre-line;
|
|
508
|
+
overflow-wrap: anywhere;
|
|
534
509
|
}
|
|
535
|
-
.np-
|
|
536
|
-
|
|
510
|
+
.np-chips {
|
|
511
|
+
display: flex;
|
|
512
|
+
flex-wrap: wrap;
|
|
513
|
+
gap: 0.4rem;
|
|
514
|
+
}
|
|
515
|
+
.np-chip {
|
|
516
|
+
font-size: 0.72rem;
|
|
517
|
+
padding: 0.2rem 0.55rem;
|
|
518
|
+
border-radius: 999px;
|
|
519
|
+
line-height: 1.3;
|
|
520
|
+
}
|
|
521
|
+
.np-chip-cat {
|
|
522
|
+
background: rgba(108, 92, 231, 0.22);
|
|
523
|
+
color: var(--text-primary);
|
|
524
|
+
border: 1px solid var(--accent);
|
|
525
|
+
}
|
|
526
|
+
.np-chip-tag {
|
|
527
|
+
background: var(--bg-elevated, #2a2a38);
|
|
537
528
|
color: var(--text-secondary);
|
|
538
|
-
|
|
529
|
+
border: 1px solid var(--border);
|
|
539
530
|
}
|
|
540
531
|
|
|
541
532
|
/* WebSocket status */
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
<div class="queue-section-header">
|
|
16
16
|
<h2>Up Next</h2>
|
|
17
17
|
<label class="toggle-switch" title="Hide items before the currently playing one">
|
|
18
|
-
<input type="checkbox" id="hide-previous-toggle"
|
|
18
|
+
<input type="checkbox" id="hide-previous-toggle" onchange="toggleHidePrevious(this.checked)" checked>
|
|
19
19
|
<span class="toggle-slider"></span>
|
|
20
20
|
<span>Hide Previous</span>
|
|
21
21
|
</label>
|
|
@@ -104,31 +104,25 @@ function renderQueue(state) {
|
|
|
104
104
|
const pct = total > 0 ? (elapsed / total * 100) : 0;
|
|
105
105
|
const cats = Array.isArray(np.categories) ? np.categories : [];
|
|
106
106
|
const tags = Array.isArray(np.tags) ? np.tags : [];
|
|
107
|
-
const
|
|
107
|
+
const chips = [
|
|
108
108
|
...cats.map(c => `<span class="np-chip np-chip-cat">${escapeHtml(c)}</span>`),
|
|
109
109
|
...tags.map(t => `<span class="np-chip np-chip-tag">${escapeHtml(t)}</span>`),
|
|
110
110
|
].join('');
|
|
111
|
-
const desc = (np.description || '').trim();
|
|
112
111
|
npEl.innerHTML = `
|
|
113
112
|
<h3 class="np-title">${escapeHtml(np.title || 'Unknown')}</h3>
|
|
114
|
-
${np.paid_by ? `<div class="np-meta"><span class="np-user">Queued by ${escapeHtml(np.paid_by)}</span></div>` : ''}
|
|
115
113
|
<div class="np-body">
|
|
116
114
|
<div class="np-cover">${coverHtml(np)}</div>
|
|
117
|
-
<div class="np-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
</div>
|
|
115
|
+
<div class="np-info">
|
|
116
|
+
${np.paid_by ? `<div class="np-meta"><span class="np-user">Queued by ${escapeHtml(np.paid_by)}</span></div>` : ''}
|
|
117
|
+
<div class="np-time">${formatTime(elapsed)} / ${formatTime(total)}</div>
|
|
121
118
|
<div class="np-progress">
|
|
122
119
|
<div class="progress-bar" style="width: ${pct}%"></div>
|
|
123
120
|
</div>
|
|
124
121
|
<div class="np-remaining">${formatTime(remaining)} remaining</div>
|
|
125
122
|
</div>
|
|
126
123
|
</div>
|
|
127
|
-
${
|
|
128
|
-
|
|
129
|
-
${facetHtml ? `<div class="np-facets">${facetHtml}</div>` : ''}
|
|
130
|
-
${desc ? `<p class="np-description">${escapeHtml(desc)}</p>` : ''}
|
|
131
|
-
</div>` : ''}
|
|
124
|
+
${np.description ? `<div class="np-description">${escapeHtml(np.description)}</div>` : ''}
|
|
125
|
+
${chips ? `<div class="np-chips">${chips}</div>` : ''}
|
|
132
126
|
`;
|
|
133
127
|
} else {
|
|
134
128
|
npEl.innerHTML = '<p class="empty-state">Nothing playing</p>';
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/admin/playlists.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/admin/queue_mgmt.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/admin/schedules.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/catalog/browse.html
RENAMED
|
File without changes
|
{kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/catalog/item_detail.html
RENAMED
|
File without changes
|
|
File without changes
|
{kryten_webqueue-0.7.1 → kryten_webqueue-0.7.2}/kryten_webqueue/templates/user/dashboard.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|