Update UI elements for consistency

This commit is contained in:
Trevor Mears
2025-12-29 23:41:40 -08:00
parent 3fffdddf4b
commit 3b0d311756
5 changed files with 105 additions and 17 deletions
+64 -10
View File
@@ -264,6 +264,44 @@ h4 {
color: var(--color-text-muted);
}
/* Search wrapper for clear button */
.search-wrapper {
position: relative;
width: 100%;
min-width: 150px;
}
.search-wrapper .search-input {
padding-right: 30px;
/* Room for clear button */
}
.search-clear {
position: absolute;
right: 6px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: var(--color-text-muted);
font-size: 1.2rem;
line-height: 1;
cursor: pointer;
padding: 4px;
opacity: 0;
transition: opacity var(--transition-fast), color var(--transition-fast);
}
.search-wrapper:hover .search-clear,
.search-input:focus~.search-clear {
opacity: 0.6;
}
.search-clear:hover {
opacity: 1;
color: var(--color-text-primary);
}
.sidebar-controls {
display: flex;
align-items: center;
@@ -622,6 +660,12 @@ video::cue {
gap: var(--space-md);
}
.guide-controls {
display: flex;
align-items: center;
gap: var(--space-md);
}
.guide-date {
font-weight: 600;
}
@@ -1214,8 +1258,8 @@ kbd {
}
.epg-program.current {
background: var(--color-primary-bg);
border-left: 3px solid var(--color-primary);
background: var(--color-accent-dim);
border-left: 3px solid var(--color-accent);
}
.epg-program-time {
@@ -1550,10 +1594,7 @@ kbd {
align-items: center;
}
.movies-controls .source-select,
.movies-controls .search-input {
min-width: 200px;
}
/* Favorites Button */
/* Favorites Button Base */
@@ -1760,11 +1801,19 @@ kbd {
align-items: center;
}
.series-controls .source-select,
.series-controls .search-input {
/* Unified Control Sizing */
.guide-controls .source-select,
.movies-controls .source-select,
.series-controls .source-select {
min-width: 150px;
}
.guide-controls .search-wrapper,
.movies-controls .search-wrapper,
.series-controls .search-wrapper {
width: 220px;
}
.series-content {
flex: 1;
overflow: hidden;
@@ -2023,8 +2072,13 @@ kbd {
/* Animation Utilities */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.spin {
+16 -5
View File
@@ -76,7 +76,10 @@
<!-- Channel Sidebar -->
<aside class="channel-sidebar">
<div class="sidebar-header">
<input type="text" id="channel-search" placeholder="Search channels..." class="search-input">
<div class="search-wrapper">
<input type="text" id="channel-search" placeholder="Search channels..." class="search-input">
<button type="button" class="search-clear" title="Clear search">&times;</button>
</div>
<div class="sidebar-controls">
<select id="source-select" class="source-select">
<option value="">All Sources</option>
@@ -129,11 +132,13 @@
<div class="guide-header">
<h2>TV Guide</h2>
<div class="guide-controls">
<input type="text" id="epg-search" placeholder="Search channels..." class="search-input"
style="min-width: 200px;">
<select id="epg-group-select" class="source-select">
<option value="">All Groups</option>
</select>
<div class="search-wrapper">
<input type="text" id="epg-search" placeholder="Search channels..." class="search-input">
<button type="button" class="search-clear" title="Clear search">&times;</button>
</div>
<button id="guide-prev" class="btn btn-ghost">&larr; Earlier</button>
<span id="guide-date" class="guide-date">Today</span>
<button id="guide-next" class="btn btn-ghost">Later &rarr;</button>
@@ -158,7 +163,10 @@
<select id="movies-category-select" class="source-select">
<option value="">All Categories</option>
</select>
<input type="text" id="movies-search" placeholder="Search movies..." class="search-input">
<div class="search-wrapper">
<input type="text" id="movies-search" placeholder="Search movies..." class="search-input">
<button type="button" class="search-clear" title="Clear search">&times;</button>
</div>
<button id="movies-favorites-btn" class="btn btn-icon btn-ghost" title="Show Favorites Only">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="icon">
<path
@@ -185,7 +193,10 @@
<select id="series-category-select" class="source-select">
<option value="">All Categories</option>
</select>
<input type="text" id="series-search" placeholder="Search series..." class="search-input">
<div class="search-wrapper">
<input type="text" id="series-search" placeholder="Search series..." class="search-input">
<button type="button" class="search-clear" title="Clear search">&times;</button>
</div>
<button id="series-favorites-btn" class="btn btn-icon btn-ghost" title="Show Favorites Only">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="icon">
<path
+13
View File
@@ -37,6 +37,19 @@ class App {
this.channelList.toggleAllGroups();
});
// Search clear buttons (global handler for all)
document.querySelectorAll('.search-clear').forEach(btn => {
btn.addEventListener('click', () => {
const wrapper = btn.closest('.search-wrapper');
const input = wrapper?.querySelector('.search-input');
if (input) {
input.value = '';
input.dispatchEvent(new Event('input', { bubbles: true }));
input.focus();
}
});
});
// Initialize home page
await this.pages.home.init();
this.navigateTo('home');
+6 -1
View File
@@ -292,7 +292,7 @@ class MoviesPage {
<span class="play-icon">${Icons.play}</span>
</div>
<button class="favorite-btn ${isFav ? 'active' : ''}" title="${isFav ? 'Remove from Favorites' : 'Add to Favorites'}">
<span class="fav-icon">${Icons.favorite}</span>
<span class="fav-icon">${isFav ? Icons.favorite : Icons.favoriteOutline}</span>
</button>
</div>
<div class="movie-info">
@@ -367,6 +367,7 @@ class MoviesPage {
async toggleFavorite(movie, btn) {
const favKey = `${movie.sourceId}:${movie.stream_id}`;
const isFav = this.favoriteIds.has(favKey);
const iconSpan = btn.querySelector('.fav-icon');
try {
// Optimistic update
@@ -374,11 +375,13 @@ class MoviesPage {
this.favoriteIds.delete(favKey);
btn.classList.remove('active');
btn.title = 'Add to Favorites';
if (iconSpan) iconSpan.innerHTML = Icons.favoriteOutline;
await API.favorites.remove(movie.sourceId, movie.stream_id, 'movie');
} else {
this.favoriteIds.add(favKey);
btn.classList.add('active');
btn.title = 'Remove from Favorites';
if (iconSpan) iconSpan.innerHTML = Icons.favorite;
await API.favorites.add(movie.sourceId, movie.stream_id, 'movie');
}
} catch (err) {
@@ -387,9 +390,11 @@ class MoviesPage {
if (isFav) {
this.favoriteIds.add(favKey);
btn.classList.add('active');
if (iconSpan) iconSpan.innerHTML = Icons.favorite;
} else {
this.favoriteIds.delete(favKey);
btn.classList.remove('active');
if (iconSpan) iconSpan.innerHTML = Icons.favoriteOutline;
}
}
}
+6 -1
View File
@@ -302,7 +302,7 @@ class SeriesPage {
<span class="play-icon">${Icons.play}</span>
</div>
<button class="favorite-btn ${isFav ? 'active' : ''}" title="${isFav ? 'Remove from Favorites' : 'Add to Favorites'}">
<span class="fav-icon">${Icons.favorite}</span>
<span class="fav-icon">${isFav ? Icons.favorite : Icons.favoriteOutline}</span>
</button>
</div>
<div class="series-card-info">
@@ -450,6 +450,7 @@ class SeriesPage {
async toggleFavorite(series, btn) {
const favKey = `${series.sourceId}:${series.series_id}`;
const isFav = this.favoriteIds.has(favKey);
const iconSpan = btn.querySelector('.fav-icon');
try {
// Optimistic update
@@ -457,11 +458,13 @@ class SeriesPage {
this.favoriteIds.delete(favKey);
btn.classList.remove('active');
btn.title = 'Add to Favorites';
if (iconSpan) iconSpan.innerHTML = Icons.favoriteOutline;
await API.favorites.remove(series.sourceId, series.series_id, 'series');
} else {
this.favoriteIds.add(favKey);
btn.classList.add('active');
btn.title = 'Remove from Favorites';
if (iconSpan) iconSpan.innerHTML = Icons.favorite;
await API.favorites.add(series.sourceId, series.series_id, 'series');
}
} catch (err) {
@@ -470,9 +473,11 @@ class SeriesPage {
if (isFav) {
this.favoriteIds.add(favKey);
btn.classList.add('active');
if (iconSpan) iconSpan.innerHTML = Icons.favorite;
} else {
this.favoriteIds.delete(favKey);
btn.classList.remove('active');
if (iconSpan) iconSpan.innerHTML = Icons.favoriteOutline;
}
}
}