Compare commits

..

No commits in common. "8edbef0a60bcd9713448e018cb755883abfbfe27" and "f6905fae829563c424f998d040110d04cbdcac4c" have entirely different histories.

4 changed files with 40 additions and 134 deletions

4
package-lock.json generated
View File

@ -1,12 +1,12 @@
{ {
"name": "twitch-vod-manager", "name": "twitch-vod-manager",
"version": "4.6.24", "version": "4.6.23",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "twitch-vod-manager", "name": "twitch-vod-manager",
"version": "4.6.24", "version": "4.6.23",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"axios": "^1.6.0", "axios": "^1.6.0",

View File

@ -1,6 +1,6 @@
{ {
"name": "twitch-vod-manager", "name": "twitch-vod-manager",
"version": "4.6.24", "version": "4.6.23",
"description": "Twitch VOD Manager - Download Twitch VODs easily", "description": "Twitch VOD Manager - Download Twitch VODs easily",
"main": "dist/main.js", "main": "dist/main.js",
"author": "xRangerDE", "author": "xRangerDE",

View File

@ -241,7 +241,7 @@
<div class="section-title" id="streamerSectionTitle" style="display:flex; align-items:center; gap:6px; justify-content:space-between;"> <div class="section-title" id="streamerSectionTitle" style="display:flex; align-items:center; gap:6px; justify-content:space-between;">
<span id="streamerSectionTitleText">Streamer</span> <span id="streamerSectionTitleText">Streamer</span>
<button id="btnStreamerBulkRemove" class="btn-close" type="button" onclick="bulkRemoveStreamers()" title="Bulk remove" style="display:none;">x</button> <button id="btnStreamerBulkRemove" class="btn-icon" type="button" onclick="bulkRemoveStreamers()" title="Bulk remove" style="display:none;">x</button>
</div> </div>
<input type="text" id="streamerListFilter" placeholder="Filter..." oninput="onStreamerListFilterChange()" style="display:none; width:calc(100% - 16px); margin:0 8px 8px; background:var(--bg-card); border:1px solid var(--border-soft); border-radius:4px; padding:4px 8px; color:var(--text); font-size:12px;"> <input type="text" id="streamerListFilter" placeholder="Filter..." oninput="onStreamerListFilterChange()" style="display:none; width:calc(100% - 16px); margin:0 8px 8px; background:var(--bg-card); border:1px solid var(--border-soft); border-radius:4px; padding:4px 8px; color:var(--text); font-size:12px;">
<div class="streamers" id="streamerList"></div> <div class="streamers" id="streamerList"></div>
@ -283,7 +283,7 @@
<div id="streamerProfileHeader" class="streamer-profile-header" style="display:none;"></div> <div id="streamerProfileHeader" class="streamer-profile-header" style="display:none;"></div>
<div class="vod-filter-row" style="display:flex; align-items:center; gap:8px; margin-bottom:12px; flex-wrap:wrap;"> <div class="vod-filter-row" style="display:flex; align-items:center; gap:8px; margin-bottom:12px; flex-wrap:wrap;">
<input type="text" id="vodFilterInput" placeholder="Filter VODs..." oninput="onVodFilterInput()" style="flex:1; min-width:180px; background: var(--bg-card); border:1px solid var(--border-soft); border-radius:6px; padding:8px 12px; color: var(--text); font-size:13px;"> <input type="text" id="vodFilterInput" placeholder="Filter VODs..." oninput="onVodFilterInput()" style="flex:1; min-width:180px; background: var(--bg-card); border:1px solid var(--border-soft); border-radius:6px; padding:8px 12px; color: var(--text); font-size:13px;">
<button id="vodFilterClearBtn" class="btn-close" onclick="clearVodFilter()" title="Clear filter" style="display:none;">x</button> <button id="vodFilterClearBtn" class="btn-icon" onclick="clearVodFilter()" title="Clear filter" style="display:none;">x</button>
<label id="vodSortLabel" for="vodSortSelect" style="color: var(--text-secondary); font-size:12px; margin-left:8px;">Sort:</label> <label id="vodSortLabel" for="vodSortSelect" style="color: var(--text-secondary); font-size:12px; margin-left:8px;">Sort:</label>
<select id="vodSortSelect" onchange="onVodSortChange()" style="background: var(--bg-card); border:1px solid var(--border-soft); border-radius:6px; padding:7px 10px; color: var(--text); font-size:13px;"> <select id="vodSortSelect" onchange="onVodSortChange()" style="background: var(--bg-card); border:1px solid var(--border-soft); border-radius:6px; padding:7px 10px; color: var(--text); font-size:13px;">
<option value="date_desc">Newest first</option> <option value="date_desc">Newest first</option>

View File

@ -249,19 +249,11 @@ body {
.add-streamer input { .add-streamer input {
flex: 1; flex: 1;
background: var(--bg-card); background: var(--bg-card);
border: 1px solid var(--border-soft); border: 1px solid rgba(255,255,255,0.1);
border-radius: 6px; border-radius: 4px;
padding: 8px 12px; padding: 8px 12px;
color: var(--text); color: var(--text);
font-size: 13px; font-size: 13px;
transition: border-color 0.18s, box-shadow 0.18s, background 0.18s;
}
.add-streamer input:focus {
outline: none;
border-color: var(--accent);
background: rgba(145, 70, 255, 0.08);
box-shadow: 0 0 0 3px rgba(145, 70, 255, 0.18);
} }
.add-streamer input::placeholder { .add-streamer input::placeholder {
@ -271,47 +263,11 @@ body {
.add-streamer button { .add-streamer button {
background: var(--accent); background: var(--accent);
border: none; border: none;
border-radius: 6px; border-radius: 4px;
color: white; color: white;
width: 36px; width: 36px;
cursor: pointer; cursor: pointer;
font-size: 18px; font-size: 18px;
font-weight: 600;
transition: background 0.18s, transform 0.12s, box-shadow 0.18s;
}
.add-streamer button:hover {
background: var(--accent-hover);
box-shadow: 0 4px 14px rgba(145, 70, 255, 0.35);
}
.add-streamer button:active {
transform: scale(0.96);
}
/* ============================================
GLOBAL TEXT-INPUT POLISH focus ring + smooth transitions
============================================ */
input[type="text"],
input[type="search"],
input[type="number"],
input[type="password"],
input[type="email"],
textarea,
select {
transition: border-color 0.18s, box-shadow 0.18s, background 0.18s;
}
input[type="text"]:focus,
input[type="search"]:focus,
input[type="number"]:focus,
input[type="password"]:focus,
input[type="email"]:focus,
textarea:focus,
select:focus {
outline: none;
border-color: var(--accent) !important;
box-shadow: 0 0 0 3px rgba(145, 70, 255, 0.18);
} }
/* Queue Section */ /* Queue Section */
@ -382,27 +338,11 @@ select:focus {
display: flex; display: flex;
align-items: flex-start; align-items: flex-start;
gap: 10px; gap: 10px;
padding: 10px 8px; padding: 8px;
background: var(--bg-card); background: var(--bg-card);
border-radius: 6px; border-radius: 4px;
margin-bottom: 6px; margin-bottom: 6px;
font-size: 12px; font-size: 12px;
border-left: 3px solid transparent;
transition: border-color 0.2s, background 0.2s;
}
.queue-item:has(.status.downloading) {
border-left-color: var(--accent);
background: rgba(145, 70, 255, 0.06);
}
.queue-item:has(.status.error) {
border-left-color: var(--error);
}
.queue-item:has(.status.completed) {
border-left-color: var(--success);
opacity: 0.85;
} }
.queue-item .status { .queue-item .status {
@ -410,14 +350,12 @@ select:focus {
height: 8px; height: 8px;
border-radius: 50%; border-radius: 50%;
background: var(--text-secondary); background: var(--text-secondary);
flex-shrink: 0;
margin-top: 4px;
} }
.queue-item .status.pending { background: var(--warning); box-shadow: 0 0 6px rgba(255, 167, 38, 0.5); } .queue-item .status.pending { background: var(--warning); }
.queue-item .status.downloading { background: var(--accent); animation: pulse 1s infinite; box-shadow: 0 0 8px rgba(145, 70, 255, 0.6); } .queue-item .status.downloading { background: var(--accent); animation: pulse 1s infinite; }
.queue-item .status.completed { background: var(--success); box-shadow: 0 0 6px rgba(0, 200, 83, 0.5); } .queue-item .status.completed { background: var(--success); }
.queue-item .status.error { background: var(--error); box-shadow: 0 0 6px rgba(255, 70, 70, 0.5); } .queue-item .status.error { background: var(--error); }
@keyframes pulse { @keyframes pulse {
0%, 100% { opacity: 1; } 0%, 100% { opacity: 1; }
@ -658,44 +596,38 @@ select:focus {
.header-search input { .header-search input {
background: var(--bg-card); background: var(--bg-card);
border: 1px solid var(--border-soft); border: 1px solid rgba(255,255,255,0.1);
border-radius: 6px; border-radius: 4px;
padding: 8px 12px; padding: 8px 12px;
color: var(--text); color: var(--text);
font-size: 13px; font-size: 13px;
width: 200px; width: 200px;
} }
.header-search input::placeholder { .header-search input:focus {
color: var(--text-secondary); outline: none;
border-color: var(--accent);
} }
.header-search button { .header-search button {
background: var(--accent); background: var(--accent);
border: none; border: none;
border-radius: 6px; border-radius: 4px;
color: white; color: white;
padding: 8px 14px; padding: 8px 12px;
cursor: pointer; cursor: pointer;
font-size: 16px; font-size: 14px;
font-weight: 700; font-weight: bold;
transition: background 0.18s, transform 0.12s, box-shadow 0.18s;
line-height: 1;
} }
.header-search button:hover { .header-search button:hover {
background: var(--accent-hover); opacity: 0.9;
box-shadow: 0 4px 14px rgba(145, 70, 255, 0.35);
}
.header-search button:active {
transform: scale(0.94);
} }
.btn-icon { .btn-icon {
background: var(--bg-card); background: var(--bg-card);
border: 1px solid var(--border-soft); border: none;
border-radius: 6px; border-radius: 4px;
color: var(--text); color: var(--text);
padding: 8px 14px; padding: 8px 14px;
cursor: pointer; cursor: pointer;
@ -703,27 +635,10 @@ select:focus {
align-items: center; align-items: center;
gap: 6px; gap: 6px;
font-size: 13px; font-size: 13px;
font-weight: 500;
transition: background 0.18s, border-color 0.18s, transform 0.12s, box-shadow 0.18s;
} }
.btn-icon:hover { .btn-icon:hover {
background: rgba(145, 70, 255, 0.12); background: #2a2a2e;
border-color: rgba(145, 70, 255, 0.45);
color: #fff;
}
.btn-icon:hover svg {
animation: btn-icon-spin 0.6s ease-out;
}
.btn-icon:active {
transform: scale(0.96);
}
@keyframes btn-icon-spin {
from { transform: rotate(0deg); }
to { transform: rotate(180deg); }
} }
.content { .content {
@ -1241,10 +1156,9 @@ select:focus {
color: #ff8a8a; color: #ff8a8a;
} }
/* .btn-close square X-close button for filter clears, inline removals. /* .btn-icon square X-close button for filter clears, inline removals.
Renamed from .btn-icon to avoid clashing with the existing top-bar 1.6em wide, transparent base, hover only colours the X. */
icon+text button class that's used for Refresh. */ .btn-icon {
.btn-close {
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@ -1260,7 +1174,7 @@ select:focus {
line-height: 1; line-height: 1;
} }
.btn-close:hover:not(:disabled) { .btn-icon:hover:not(:disabled) {
background: rgba(255, 70, 70, 0.10); background: rgba(255, 70, 70, 0.10);
border-color: rgba(255, 70, 70, 0.45); border-color: rgba(255, 70, 70, 0.45);
color: #ff6b6b; color: #ff6b6b;
@ -2284,35 +2198,27 @@ body.theme-light .modal {
bottom: 16px; bottom: 16px;
z-index: 2200; z-index: 2200;
max-width: min(90vw, 520px); max-width: min(90vw, 520px);
background: linear-gradient(135deg, rgba(28, 28, 34, 0.98), rgba(20, 20, 24, 0.98)); background: rgba(20, 20, 24, 0.96);
color: #e6e6ea; color: #e6e6ea;
border: 1px solid rgba(255, 255, 255, 0.10); border: 1px solid rgba(255, 255, 255, 0.12);
border-left: 3px solid var(--accent); border-radius: 8px;
border-radius: 10px; padding: 10px 12px;
padding: 12px 16px 12px 14px;
font-size: 13px; font-size: 13px;
line-height: 1.45; line-height: 1.45;
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(145, 70, 255, 0.12); box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
opacity: 0; opacity: 0;
transform: translateX(20px); transform: translateY(10px);
pointer-events: none; pointer-events: none;
transition: opacity 0.22s ease, transform 0.22s cubic-bezier(0.16, 1, 0.3, 1); transition: opacity 0.18s ease, transform 0.18s ease;
backdrop-filter: blur(8px);
} }
.app-toast.show { .app-toast.show {
opacity: 1; opacity: 1;
transform: translateX(0); transform: translateY(0);
} }
.app-toast.warn { .app-toast.warn {
border-left-color: var(--warning); border-color: rgba(255, 167, 38, 0.7);
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 167, 38, 0.25);
}
.app-toast.error {
border-left-color: var(--error);
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45), 0 0 0 1px rgba(255, 70, 70, 0.25);
} }
/* ============================================ /* ============================================