refactor: refactor favorites and recently viewed components to use content card

This commit is contained in:
4gray committed 2026-02-04 22:13:23 +01:00
1 parent e6923d3fff
commit 2f1e455330
10 files changed
+55 -410

No files matched your search

@@ -38,40 +38,16 @@
@if (favorites().length) {
<div class="items-grid">
@for (item of favorites(); track $index) {
<div class="item-card" (click)="openFavorite(item)">
<div class="thumbnail-wrapper">
<button
mat-icon-button
class="remove-button"
[matTooltip]="'CHANNELS.REMOVE_FAVORITE' | translate"
(click)="$event.stopPropagation(); removeFromFavorites(item)"
>
<mat-icon>close</mat-icon>
</button>
<img
[src]="
item.poster_url ||
item.cover ||
'./assets/images/default-poster.png'
"
(error)="
$event.target.src =
'./assets/images/default-poster.png'
"
[alt]="item.title"
class="poster"
/>
<span class="type-badge" [class]="item.type">
{{ item.type }}
</span>
</div>
<div class="item-info">
<h3>{{ item?.title || item?.details?.info?.name }}</h3>
<p class="added-date">
{{ item?.added_at | date: 'd MMM, HH:mm' }}
</p>
</div>
</div>
<app-content-card
[posterUrl]="item.poster_url || item.cover"
[title]="item?.title || item?.details?.info?.name || 'Unknown'"
[type]="item.type"
[date]="item.added_at"
[showRemoveButton]="true"
[removeTooltip]="'CHANNELS.REMOVE_FAVORITE' | translate"
(cardClick)="openFavorite(item)"
(remove)="removeFromFavorites(item)"
/>
}
</div>
} @else {
@@ -1,4 +1,5 @@
@use '@angular/material' as mat;
@use '../../../shared/styles/content-grid' as grid;
:host {
display: flex;
@@ -47,107 +48,13 @@
}
.items-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
gap: 20px;
@include grid.content-grid(140px, 20px);
padding: 16px;
width: 100%;
box-sizing: border-box;
margin: 0;
}
.item-card {
cursor: pointer;
border-radius: 8px;
overflow: hidden;
transition: transform 0.2s ease, box-shadow 0.2s ease;
&:hover {
transform: translateY(-3px);
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);
}
.thumbnail-wrapper {
position: relative;
.poster {
width: 100%;
aspect-ratio: 2/3;
object-fit: cover;
display: block;
}
.remove-button {
position: absolute;
top: 4px;
right: 4px;
z-index: 1;
background: rgba(0, 0, 0, 0.5);
width: 28px;
height: 28px;
padding: 0;
&:hover {
background: rgba(0, 0, 0, 0.8);
}
mat-icon {
color: white;
font-size: 18px;
width: 18px;
height: 18px;
}
}
.type-badge {
position: absolute;
top: 6px;
left: 6px;
padding: 3px 6px;
border-radius: 4px;
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
background: rgba(0, 0, 0, 0.6);
color: #fff;
&.live {
color: #ef5350;
}
&.movie {
color: #42a5f5;
}
&.series {
color: #66bb6a;
}
}
}
.item-info {
padding: 8px 10px;
h3 {
margin: 0;
font-size: 0.8rem;
font-weight: 500;
line-height: 1.3;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.added-date {
margin: 4px 0 0;
font-size: 0.7rem;
opacity: 0.6;
}
}
}
.no-items {
display: flex;
flex-direction: column;
@@ -1,12 +1,9 @@
import { DatePipe } from '@angular/common';
import { Component, input, output } from '@angular/core';
import { MatIconButton } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatIcon } from '@angular/material/icon';
import { MatTooltip } from '@angular/material/tooltip';
import { TranslatePipe } from '@ngx-translate/core';
import { PlaylistSwitcherComponent, ResizableDirective } from 'components';
import { CategoryViewComponent } from '../../../xtream-tauri/category-view/category-view.component';
import { ContentCardComponent } from '../content-card/content-card.component';
@Component({
selector: 'app-favorites-layout',
@@ -17,11 +14,8 @@ import { CategoryViewComponent } from '../../../xtream-tauri/category-view/categ
],
imports: [
CategoryViewComponent,
DatePipe,
MatCardModule,
ContentCardComponent,
MatIcon,
MatIconButton,
MatTooltip,
PlaylistSwitcherComponent,
ResizableDirective,
TranslatePipe,
@@ -1 +1,2 @@
export * from './content-card/content-card.component';
export * from './header/header.component';