Compare commits
2 Commits
7177cdb9ab
...
2539f82868
| Author | SHA1 | Date | |
|---|---|---|---|
| 2539f82868 | |||
| 7784da495b |
@@ -39,10 +39,34 @@
|
||||
|
||||
.content-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 2fr 1fr;
|
||||
/* 3fr/1fr (not 2fr/1fr) so the 9-column playlist table gets enough room;
|
||||
at 2fr/1fr it was ~50px too narrow and looped with a scrollbar.
|
||||
minmax(0, …) removes the track's automatic min-content floor, without
|
||||
which the table's intrinsic width would widen the track itself. */
|
||||
grid-template-columns: minmax(0, 3fr) minmax(0, 1fr);
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
/* The table needs ~830px and side by side it cannot get that below ~1440px.
|
||||
Stack the cards instead of forcing a horizontal scrollbar on the table. */
|
||||
@media (max-width: 1439px) {
|
||||
.content-grid {
|
||||
/* minmax(0, 1fr) matters here too: a bare 1fr keeps the min-content
|
||||
floor, which let the 830px table widen the track and push the
|
||||
page into horizontal overflow. */
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
/* Last-resort containment: on a genuinely narrow screen the table cannot
|
||||
fit, and an unclipped table is painted straight over the Add Content
|
||||
card, because that card is later in the DOM and therefore paints on top.
|
||||
Clip here so the table scrolls inside its own card instead. */
|
||||
.playlist-table-scroll {
|
||||
overflow-x: auto;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.playlist-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
@@ -50,13 +74,13 @@
|
||||
|
||||
.playlist-table th {
|
||||
background: #f8f9fa;
|
||||
padding: 12px;
|
||||
padding: 8px;
|
||||
text-align: left;
|
||||
border-bottom: 2px solid #dee2e6;
|
||||
}
|
||||
|
||||
.playlist-table td {
|
||||
padding: 12px;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #dee2e6;
|
||||
}
|
||||
|
||||
@@ -87,6 +111,56 @@
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
/* On a narrow viewport the thumbnail + name + button no longer fit on
|
||||
one line; wrapping drops the Add button below instead of squeezing
|
||||
the name under it. */
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* Left group: thumbnail + name/size. min-width:0 lets long names ellipsise
|
||||
instead of pushing the Add button out of the card. */
|
||||
.avail-main {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
min-width: 0;
|
||||
}
|
||||
.avail-thumb {
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
flex: 0 0 auto;
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
background: #e9ecef;
|
||||
border: 1px solid #dee2e6;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 22px;
|
||||
line-height: 1;
|
||||
}
|
||||
.avail-thumb img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
display: block;
|
||||
}
|
||||
.avail-info {
|
||||
min-width: 0;
|
||||
}
|
||||
.avail-name {
|
||||
font-size: 14px;
|
||||
/* Long media filenames carry the meaningful part at the END
|
||||
(…_slide_003.png), so breaking mid-word is better than ellipsis,
|
||||
which would hide the distinguishing characters. `anywhere` allows
|
||||
breaks inside the unbroken run and keeps min-content width tiny. */
|
||||
overflow-wrap: anywhere;
|
||||
word-break: break-word;
|
||||
}
|
||||
.avail-meta {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* Audio toggle styles */
|
||||
@@ -216,6 +290,15 @@
|
||||
color: #e2e8f0;
|
||||
}
|
||||
|
||||
body.dark-mode .avail-thumb {
|
||||
background: #2d3748;
|
||||
border-color: #4a5568;
|
||||
}
|
||||
|
||||
body.dark-mode .avail-meta {
|
||||
color: #a0aec0;
|
||||
}
|
||||
|
||||
/* Dark mode for duration spinner */
|
||||
body.dark-mode .duration-display {
|
||||
background: #2d3748;
|
||||
@@ -245,11 +328,18 @@
|
||||
body.dark-mode .duration-spinner button.btn-decrease {
|
||||
color: #f56565;
|
||||
}
|
||||
|
||||
/* The page needs more than base.html's 1200px container to show the
|
||||
playlist table and the Add Content card side by side. This template
|
||||
already declared max-width:1400px on its own wrapper, but a child cannot
|
||||
widen its parent, so it had no effect. Widen the base container instead. */
|
||||
body > .container {
|
||||
max-width: 1400px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="container" style="max-width: 1400px;">
|
||||
<div class="playlist-header">
|
||||
<h1>🎬 {{ playlist.name }}</h1>
|
||||
<div class="playlist-header"> <h1>🎬 {{ playlist.name }}</h1>
|
||||
{% if playlist.description %}
|
||||
<p style="margin: 5px 0; opacity: 0.9;">{{ playlist.description }}</p>
|
||||
{% endif %}
|
||||
@@ -290,6 +380,7 @@
|
||||
</div>
|
||||
|
||||
{% if playlist_content %}
|
||||
<div class="playlist-table-scroll">
|
||||
<table class="playlist-table" id="playlist-table">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -397,6 +488,7 @@
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% else %}
|
||||
<div style="text-align: center; padding: 40px; color: #999;">
|
||||
<div style="font-size: 48px;">📭</div>
|
||||
@@ -428,21 +520,32 @@
|
||||
<div class="available-content">
|
||||
{% for content in available_content %}
|
||||
<div class="content-item">
|
||||
<div>
|
||||
<div>
|
||||
{% if content.content_type == 'image' %}📷
|
||||
{% elif content.content_type == 'video' %}🎥
|
||||
{% elif content.content_type == 'pdf' %}📄
|
||||
{% else %}📁{% endif %}
|
||||
<div class="avail-main">
|
||||
<div class="avail-thumb">
|
||||
{% if content.content_type == 'image' %}
|
||||
{# Preview the real image so the user can see what
|
||||
is being added. Falls back to the camera icon
|
||||
if the file is missing or fails to load. #}
|
||||
<img src="{{ url_for('static', filename='uploads/' + content.current_media_path) }}"
|
||||
alt="{{ content.original_display_name }}"
|
||||
loading="lazy"
|
||||
onerror="this.parentElement.innerHTML='<span>📷</span>';">
|
||||
{% elif content.content_type == 'video' %}<span>🎥</span>
|
||||
{% elif content.content_type == 'pdf' %}<span>📄</span>
|
||||
{% else %}<span>📁</span>{% endif %}
|
||||
</div>
|
||||
<div class="avail-info">
|
||||
<div class="avail-name" title="{{ content.original_display_name }}">
|
||||
{{ content.original_display_name }}
|
||||
</div>
|
||||
<div style="font-size: 12px; color: #999;">
|
||||
<div class="avail-meta">
|
||||
{{ content.file_size_mb }} MB
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<form method="POST"
|
||||
action="{{ url_for('content.add_content_to_playlist', playlist_id=playlist.id) }}"
|
||||
style="display: inline;">
|
||||
style="display: inline; flex: 0 0 auto;">
|
||||
<input type="hidden" name="content_id" value="{{ content.id }}">
|
||||
<input type="hidden" name="duration" value="{{ content.duration }}">
|
||||
<button type="submit" class="btn btn-success btn-sm">
|
||||
|
||||
Reference in New Issue
Block a user