@@ -40,46 +37,92 @@ import { MatIconModule } from '@angular/material/icon';
`
:host {
display: block;
+ height: 100%;
}
mat-card {
cursor: pointer;
- }
-
- h4 {
- margin: 0;
- padding: 8px;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ position: relative;
+ overflow: hidden;
+ background: transparent !important;
+ box-shadow: none !important;
+ border: none !important;
+ padding: 0 !important;
}
.poster {
width: 100%;
+ aspect-ratio: 2/3;
object-fit: cover;
+ display: block;
+ border-radius: 8px;
}
.poster-placeholder {
width: 100%;
- height: 200px;
+ aspect-ratio: 2/3;
display: flex;
align-items: center;
justify-content: center;
+ background: rgba(0, 0, 0, 0.05);
+ border-radius: 8px;
+
+ mat-icon {
+ font-size: 48px;
+ width: 48px;
+ height: 48px;
+ opacity: 0.3;
+ }
}
- .type-badge {
- position: absolute;
- top: 8px;
- right: 8px;
- padding: 4px 8px;
- border-radius: 4px;
- font-size: 12px;
- text-transform: uppercase;
+ h4 {
+ margin: 0;
+ padding: 10px 0 2px 0;
+ font-size: 0.9rem;
+ font-weight: 500;
+ line-height: 1.3em;
+ height: 2.6em; /* Fixed height for 2 lines */
+ color: var(--text-color, #fff);
+
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ }
+
+ p {
+ margin: 0;
+ padding: 0 0 10px 0;
+ font-size: 0.75rem;
+ line-height: 1.2em;
+ height: 1.2em; /* Fixed height for 1 line */
+ color: var(--text-color-secondary, rgba(255, 255, 255, 0.7));
+ opacity: 0.9; /* Improved readability */
+
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
}
.playlist-badge {
display: flex;
align-items: center;
gap: 4px;
- margin-top: 8px;
- font-size: 12px;
+ margin-top: auto;
+ padding: 0 0 10px 0;
+ font-size: 11px;
+ opacity: 0.8;
+ color: var(--text-color-secondary, inherit);
+
+ mat-icon {
+ font-size: 14px;
+ width: 14px;
+ height: 14px;
+ }
}
`,
],
@@ -93,4 +136,4 @@ export class SearchResultItemComponent {
@Input() showPlaylistInfo = false;
@Output() itemClick = new EventEmitter
();
-}
+}
\ No newline at end of file
diff --git a/apps/web/src/app/xtream-tauri/portal-channels-list/portal-channels-list.component.ts b/apps/web/src/app/xtream-tauri/portal-channels-list/portal-channels-list.component.ts
index 2e3ac8e41..0729ff577 100644
--- a/apps/web/src/app/xtream-tauri/portal-channels-list/portal-channels-list.component.ts
+++ b/apps/web/src/app/xtream-tauri/portal-channels-list/portal-channels-list.component.ts
@@ -89,14 +89,11 @@ export class PortalChannelsListComponent implements AfterViewInit {
this.favoritesService
.getFavorites(playlist.id)
.subscribe((favorites) => {
- // Map using content.id instead of xtream_id
favorites.forEach((fav: any) => {
this.favorites.set(fav.xtream_id, true);
});
- console.log(this.favorites);
});
}
- // Removed loadCurrentEpgData() call since we're using virtual scroll
}
ngAfterViewInit() {
diff --git a/apps/web/src/app/xtream-tauri/search-results/search-results.component.html b/apps/web/src/app/xtream-tauri/search-results/search-results.component.html
index acb1ede0d..8aa520953 100644
--- a/apps/web/src/app/xtream-tauri/search-results/search-results.component.html
+++ b/apps/web/src/app/xtream-tauri/search-results/search-results.component.html
@@ -1,24 +1,43 @@
-
+
diff --git a/apps/web/src/app/xtream-tauri/search-results/search-results.component.scss b/apps/web/src/app/xtream-tauri/search-results/search-results.component.scss
index 13d6fc1b6..532921c11 100644
--- a/apps/web/src/app/xtream-tauri/search-results/search-results.component.scss
+++ b/apps/web/src/app/xtream-tauri/search-results/search-results.component.scss
@@ -7,31 +7,75 @@
}
.search-page {
- padding: 20px;
+ padding: 0 20px 20px 20px;
}
.header {
- display: flex;
- justify-content: space-between;
- align-items: center;
+ position: sticky;
+ top: 0;
+ z-index: 100;
+ // Use theme background variable or fallback
+ background: var(--background, var(--mat-sidenav-content-background-color, #fff));
+ padding: 20px 0 10px 0;
margin-bottom: 20px;
-}
+ // Subtle shadow or border for separation
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.02);
+
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ gap: 16px;
-.search-container {
- flex-shrink: 0;
-
- .search-field {
- width: 100%;
+ .header-top {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ gap: 20px;
}
- .type-filters {
- mat-checkbox {
- margin-right: 1rem;
+ .header-left {
+ display: flex;
+ align-items: center;
+ gap: 32px;
+ flex: 1;
+ flex-wrap: wrap;
+
+ h2 {
+ margin: 0;
+ white-space: nowrap;
+ }
+
+ .type-filters {
+ display: flex;
+ gap: 20px;
+ align-items: center;
+
+ mat-checkbox {
+ margin: 0;
+ }
}
}
- .results-count {
- font-size: 0.9rem;
+ .header-right {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+
+ .results-count {
+ font-size: 0.85rem;
+ color: var(--text-color-secondary, rgba(0,0,0,0.7));
+ background: rgba(0, 0, 0, 0.06);
+ padding: 6px 12px;
+ border-radius: 16px;
+ white-space: nowrap;
+ font-weight: 500;
+ display: flex;
+ align-items: center;
+ }
+ }
+
+ .search-input-container {
+ margin-bottom: 0;
}
}
@@ -50,54 +94,72 @@
mat-card {
cursor: pointer;
+ transition: transform 0.2s, box-shadow 0.2s;
+
+ &:hover {
+ transform: translateY(-2px);
+ box-shadow: 0 4px 12px rgba(0,0,0,0.1);
+ }
+
.poster,
.poster-placeholder {
- border-radius: 13px;
+ border-radius: 8px;
width: 100%;
aspect-ratio: 2/3;
object-fit: cover;
- margin-bottom: 0.5rem;
+ margin-bottom: 0.75rem;
}
.poster-placeholder {
display: flex;
align-items: center;
justify-content: center;
+ background: rgba(0,0,0,0.05);
+
mat-icon {
font-size: 48px;
width: 48px;
height: 48px;
+ opacity: 0.3;
}
}
h3 {
margin: 0.5rem 0;
font-size: 1rem;
- font-weight: normal;
+ font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
p {
- font-size: 0.8rem;
- color: rgba(0, 0, 0, 0.6);
- margin: 0.5rem 0;
+ font-size: 0.85rem;
+ color: var(--text-color-secondary, rgba(0, 0, 0, 0.6));
+ margin: 0 0 0.75rem 0;
+ line-height: 1.4;
+ display: -webkit-box;
+ -webkit-line-clamp: 2;
+ -webkit-box-orient: vertical;
+ overflow: hidden;
}
.type-badge {
display: inline-block;
padding: 0.25rem 0.5rem;
border-radius: 4px;
- font-size: 0.8rem;
+ font-size: 0.75rem;
+ font-weight: 600;
text-transform: uppercase;
+ letter-spacing: 0.5px;
+
&.live {
- background: #e53935;
- color: white;
+ background: rgba(229, 57, 53, 0.1);
+ color: #e53935;
}
&.movie {
- background: #1e88e5;
- color: white;
+ background: rgba(30, 136, 229, 0.1);
+ color: #1e88e5;
}
&.series {
- background: #43a047;
- color: white;
+ background: rgba(67, 160, 71, 0.1);
+ color: #43a047;
}
}
}
@@ -109,18 +171,45 @@
flex-direction: column;
align-items: center;
justify-content: center;
- padding: 2rem;
+ padding: 4rem 2rem;
+ text-align: center;
mat-icon {
- font-size: 48px;
- width: 48px;
- height: 48px;
- margin-bottom: 1rem;
+ font-size: 64px;
+ width: 64px;
+ height: 64px;
+ margin-bottom: 1.5rem;
+ opacity: 0.5;
}
- p {
- font-size: 1.1rem;
- margin: 0;
+ .no-items-content {
+ h3 {
+ margin: 0 0 0.5rem;
+ font-size: 1.5rem;
+ font-weight: 500;
+ color: var(--text-color);
+ }
+
+ p {
+ font-size: 1.1rem;
+ margin: 0;
+ opacity: 0.8;
+ }
+
+ .search-term-note {
+ margin-top: 1rem;
+ font-size: 0.9rem;
+ font-style: italic;
+ opacity: 0.6;
+ }
+ }
+
+ &.initial-state {
+ opacity: 0.8;
+ mat-icon {
+ color: var(--primary-color);
+ opacity: 0.6;
+ }
}
}
@@ -130,6 +219,11 @@
height: 100vh;
}
+ /* Ensure sticky header background matches overlay background */
+ .header {
+ background: var(--background);
+ }
+
.results-grid {
mat-card {
position: relative;
@@ -200,49 +294,6 @@
}
:host-context(.global-search-overlay) {
- .search-page {
- background: var(--background);
- height: 100vh;
- }
-
- .results-grid {
- mat-card {
- position: relative;
-
- .poster,
- .poster-placeholder {
- margin-top: 24px;
- }
-
- .playlist-badge {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- background: rgba(0, 0, 0, 0.7);
- padding: 6px 8px;
- font-size: 12px;
- color: white;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- border-top-left-radius: inherit;
- border-top-right-radius: inherit;
- backdrop-filter: blur(5px);
- display: flex;
- align-items: center;
- gap: 4px;
-
- mat-icon {
- font-size: 14px;
- width: 14px;
- height: 14px;
- flex-shrink: 0;
- }
- }
- }
- }
-
.playlist-group {
.playlist-title {
background: var(--surface);
diff --git a/apps/web/src/app/xtream-tauri/search-results/search-results.component.ts b/apps/web/src/app/xtream-tauri/search-results/search-results.component.ts
index b2a9e35e2..b24d965e8 100644
--- a/apps/web/src/app/xtream-tauri/search-results/search-results.component.ts
+++ b/apps/web/src/app/xtream-tauri/search-results/search-results.component.ts
@@ -51,9 +51,7 @@ interface SearchResultsData {
SearchResultItemComponent,
TranslatePipe,
],
- providers: [
- XtreamStore
- ],
+ providers: [],
templateUrl: './search-results.component.html',
styleUrls: ['./search-results.component.scss'],
})
@@ -112,7 +110,7 @@ export class SearchResultsComponent implements AfterViewInit {
});
}
- private executeSearch() {
+ executeSearch() {
const types = Object.entries(this.filters)
.filter(([_, enabled]) => enabled)
.map(([type]) => type);
diff --git a/apps/web/src/assets/i18n/en.json b/apps/web/src/assets/i18n/en.json
index 0a5b99de1..a593b21a1 100644
--- a/apps/web/src/assets/i18n/en.json
+++ b/apps/web/src/assets/i18n/en.json
@@ -384,6 +384,7 @@
"LIBRARY": "Library",
"SEARCH": "Search",
"RECENT": "Recent",
+ "RECENTLY_ADDED": "Recently added",
"FAVORITES": "Favorites",
"HOME": "Home",
"PLAYLIST_INFO": "Playlist info",
@@ -422,6 +423,10 @@
"TITLE": "No results found",
"NO_SEARCH_RESULTS": "Nothing found, try to change you search request"
},
+ "SEARCH_VIEW": {
+ "INITIAL_TITLE": "Search for content",
+ "INITIAL_DESCRIPTION": "Enter at least 3 characters to search across live TV, movies and series."
+ },
"STREAM_URL_COPIED": "Stream URL copied to clipboard",
"COPY_STREAM_URL": "Copy Stream URL",
"SELECT_CATEGORY": "Select a category",