mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
refactor: code and style improvements
This commit is contained in:
1 parent
a7524b4b38
commit
dadaf0eb74
10 files changed
+102
-144
No files matched your search
@@ -4,7 +4,9 @@
|
||||
(searchTextChanged)="setSearchPhrase($event)"
|
||||
[clientSideSearch]="currentLayout === 'category_content' ? false : true"
|
||||
[searchVisible]="
|
||||
currentLayout === 'category' || currentLayout === 'category_content'
|
||||
(currentLayout === 'category' ||
|
||||
currentLayout === 'category_content') &&
|
||||
items?.length > 0
|
||||
"
|
||||
[contentTypeNavigationItems]="navigationContentTypes"
|
||||
[contentType]="selectedContentType"
|
||||
@@ -55,16 +57,15 @@
|
||||
[items]="items"
|
||||
(itemClicked)="itemClicked($event)"
|
||||
/>
|
||||
<mat-paginator
|
||||
*ngIf="
|
||||
currentLayout === 'category_content' && length && length > 0
|
||||
"
|
||||
[length]="length"
|
||||
[pageIndex]="pageIndex"
|
||||
[pageSize]="pageSize"
|
||||
(page)="handlePageChange($event)"
|
||||
aria-label="Select page"
|
||||
/>
|
||||
@if (currentLayout === 'category_content' && length && length > 0) {
|
||||
<mat-paginator
|
||||
[length]="length"
|
||||
[pageIndex]="pageIndex"
|
||||
[pageSize]="pageSize"
|
||||
(page)="handlePageChange($event)"
|
||||
aria-label="Select page"
|
||||
/>
|
||||
}
|
||||
}
|
||||
@case ('vod-details') {
|
||||
<app-vod-details
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AsyncPipe, NgFor, NgIf } from '@angular/common';
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { Component, NgZone, OnInit, Signal, effect } from '@angular/core';
|
||||
import { toSignal } from '@angular/core/rxjs-interop';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
@@ -57,8 +57,6 @@ import { StalkerSeriesViewComponent } from './stalker-series-view/stalker-series
|
||||
CategoryViewComponent,
|
||||
MatPaginatorModule,
|
||||
NavigationBarComponent,
|
||||
NgFor,
|
||||
NgIf,
|
||||
NgxSkeletonLoaderModule,
|
||||
PlaylistErrorViewComponent,
|
||||
StalkerSeriesViewComponent,
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
@if (items?.length > 0) {
|
||||
<div class="grid">
|
||||
<mat-card
|
||||
*ngFor="
|
||||
let item of items | filterBy: searchPhrase() : 'name';
|
||||
trackBy: trackByFn
|
||||
"
|
||||
(click)="itemClicked.emit(item)"
|
||||
>
|
||||
<mat-card-content>
|
||||
<img
|
||||
class="stream-icon"
|
||||
*ngIf="item.stream_icon || item.cover || item.logo"
|
||||
[ngSrc]="item.stream_icon || item.cover || item.logo"
|
||||
fill
|
||||
priority
|
||||
placeholder
|
||||
placeholder="data:image/png;base64,iVBORw0K..."
|
||||
/>
|
||||
<div
|
||||
class="stream-icon-placeholder"
|
||||
*ngIf="!item.stream_icon && !item.cover && !item.logo"
|
||||
></div>
|
||||
<div
|
||||
*ngIf="item.rating || item.rating_imdb"
|
||||
class="rating"
|
||||
[matTooltip]="'XTREAM.IMDB_RATING' | translate"
|
||||
>
|
||||
<mat-icon>star</mat-icon
|
||||
>{{ item.rating || item.rating_imdb }}
|
||||
</div>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<div class="title">{{ item.name }}</div>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
<div
|
||||
class="no-content"
|
||||
*ngIf="!(items | filterBy: searchPhrase() : 'name')?.length"
|
||||
>
|
||||
<mat-icon class="icon">search</mat-icon>
|
||||
<div>
|
||||
{{ 'PORTALS.EMPTY_LIST_VIEW.NO_SEARCH_RESULTS' | translate }}
|
||||
</div>
|
||||
</div>
|
||||
@for (item of items | filterBy: searchPhrase() : 'name'; track $index) {
|
||||
<mat-card (click)="itemClicked.emit(item)">
|
||||
<mat-card-content>
|
||||
@if (item.stream_icon || item.cover || item.logo) {
|
||||
<img
|
||||
class="stream-icon"
|
||||
[ngSrc]="
|
||||
item.stream_icon || item.cover || item.logo
|
||||
"
|
||||
fill
|
||||
priority
|
||||
placeholder
|
||||
placeholder="data:image/png;base64,iVBORw0K..."
|
||||
/>
|
||||
}
|
||||
@if (!item.stream_icon && !item.cover && !item.logo) {
|
||||
<div class="stream-icon-placeholder"></div>
|
||||
}
|
||||
@if (item.rating || item.rating_imdb) {
|
||||
<div
|
||||
class="rating"
|
||||
[matTooltip]="'XTREAM.IMDB_RATING' | translate"
|
||||
>
|
||||
<mat-icon>star</mat-icon
|
||||
>{{ item.rating || item.rating_imdb }}
|
||||
</div>
|
||||
}
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<div class="title">{{ item.name || 'No name' }}</div>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
}
|
||||
@if (!(items | filterBy: searchPhrase() : 'name')?.length) {
|
||||
<app-playlist-error-view
|
||||
title="No results"
|
||||
[description]="
|
||||
'PORTALS.EMPTY_LIST_VIEW.NO_SEARCH_RESULTS' | translate
|
||||
"
|
||||
[showActionButtons]="false"
|
||||
[viewType]="'NO_SEARCH_RESULTS'"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
} @else {
|
||||
<app-playlist-error-view
|
||||
|
||||
@@ -82,13 +82,3 @@ mat-card:hover {
|
||||
width: 18px;
|
||||
}
|
||||
}
|
||||
|
||||
.no-content {
|
||||
text-align: center;
|
||||
|
||||
.icon {
|
||||
font-size: 64px;
|
||||
height: 64px;
|
||||
width: 64px;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import { NgFor, NgIf, NgOptimizedImage } from '@angular/common';
|
||||
import { NgOptimizedImage } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, Output, inject } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
@@ -16,12 +15,9 @@ import { PortalStore } from '../portal.store';
|
||||
styleUrls: ['./category-content-view.component.scss'],
|
||||
standalone: true,
|
||||
imports: [
|
||||
NgFor,
|
||||
FilterPipe,
|
||||
MatCardModule,
|
||||
MatIconModule,
|
||||
NgIf,
|
||||
FilterPipe,
|
||||
FormsModule,
|
||||
MatTooltipModule,
|
||||
NgOptimizedImage,
|
||||
PlaylistErrorViewComponent,
|
||||
@@ -33,10 +29,5 @@ export class CategoryContentViewComponent {
|
||||
@Output() itemClicked = new EventEmitter<XtreamItem>();
|
||||
|
||||
portalStore = inject(PortalStore);
|
||||
|
||||
searchPhrase = this.portalStore.searchPhrase;
|
||||
|
||||
trackByFn(_index: number, item: XtreamItem) {
|
||||
return item.stream_id;
|
||||
}
|
||||
}
|
||||
@@ -1,40 +1,23 @@
|
||||
:host {
|
||||
overflow-y: auto;
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
mat-card-content {
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.no-content {
|
||||
text-align: center;
|
||||
|
||||
.icon {
|
||||
font-size: 64px;
|
||||
height: 64px;
|
||||
width: 64px;
|
||||
}
|
||||
}
|
||||
|
||||
.grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
|
||||
/* padding-bottom: 20px; */
|
||||
|
||||
.category-item {
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
}
|
||||
.category-item {
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
.grid {
|
||||
.category-item {
|
||||
width: 100%;
|
||||
}
|
||||
.category-item {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,4 @@
|
||||
import { NgFor, NgIf } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, Output, inject } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatCardModule } from '@angular/material/card';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
@@ -14,37 +12,36 @@ import { PortalStore } from '../portal.store';
|
||||
standalone: true,
|
||||
template: `
|
||||
@if (items?.length > 0) {
|
||||
<div class="grid">
|
||||
@for (
|
||||
item of items | filterBy: searchPhrase() : 'category_name';
|
||||
track $index
|
||||
) {
|
||||
<mat-card
|
||||
appearance="outlined"
|
||||
class="category-item"
|
||||
*ngFor="
|
||||
let item of items
|
||||
| filterBy: searchText() : 'category_name';
|
||||
trackBy: trackByFn
|
||||
"
|
||||
(click)="categoryClicked.emit(item)"
|
||||
>
|
||||
<mat-card-content>
|
||||
{{ item.category_name || item.name || 'no name' }}
|
||||
{{
|
||||
item.category_name ||
|
||||
item.name ||
|
||||
'No category name'
|
||||
}}
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<div
|
||||
class="no-content"
|
||||
*ngIf="
|
||||
!(items | filterBy: searchText() : 'category_name')
|
||||
?.length
|
||||
}
|
||||
@if (
|
||||
!(items | filterBy: searchPhrase() : 'category_name')?.length
|
||||
) {
|
||||
<app-playlist-error-view
|
||||
title="No results"
|
||||
[description]="
|
||||
'PORTALS.EMPTY_LIST_VIEW.NO_SEARCH_RESULTS' | translate
|
||||
"
|
||||
>
|
||||
<mat-icon class="icon">search</mat-icon>
|
||||
<div>
|
||||
{{
|
||||
'PORTALS.EMPTY_LIST_VIEW.NO_SEARCH_RESULTS'
|
||||
| translate
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
[showActionButtons]="false"
|
||||
[viewType]="'NO_SEARCH_RESULTS'"
|
||||
/>
|
||||
}
|
||||
} @else {
|
||||
<app-playlist-error-view
|
||||
[title]="'PORTALS.ERROR_VIEW.EMPTY_CATEGORY.TITLE' | translate"
|
||||
@@ -58,13 +55,10 @@ import { PortalStore } from '../portal.store';
|
||||
`,
|
||||
styleUrl: './category-view.component.scss',
|
||||
imports: [
|
||||
PlaylistErrorViewComponent,
|
||||
FilterPipe,
|
||||
FormsModule,
|
||||
MatCardModule,
|
||||
MatIconModule,
|
||||
NgFor,
|
||||
NgIf,
|
||||
PlaylistErrorViewComponent,
|
||||
TranslateModule,
|
||||
],
|
||||
})
|
||||
@@ -74,10 +68,5 @@ export class CategoryViewComponent {
|
||||
@Output() categoryClicked = new EventEmitter<XtreamCategory>();
|
||||
|
||||
portalStore = inject(PortalStore);
|
||||
|
||||
searchText = this.portalStore.searchPhrase;
|
||||
|
||||
trackByFn(_index: number, item: XtreamCategory) {
|
||||
return item.category_id;
|
||||
}
|
||||
searchPhrase = this.portalStore.searchPhrase;
|
||||
}
|
||||
@@ -6,6 +6,8 @@
|
||||
style="max-width: 350px"
|
||||
src="./assets/images/empty-category.svg"
|
||||
/>
|
||||
} @else if (viewType === 'NO_SEARCH_RESULTS') {
|
||||
<mat-icon class="icon">search</mat-icon>
|
||||
}
|
||||
<div>
|
||||
<h3>{{ title }}</h3>
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 64px;
|
||||
height: 64px;
|
||||
width: 64px;
|
||||
}
|
||||
|
||||
::ng-deep {
|
||||
.dark-theme {
|
||||
.expired-account {
|
||||
|
||||
@@ -9,13 +9,11 @@
|
||||
"
|
||||
>
|
||||
<div class="image">
|
||||
<img
|
||||
*ngIf="item.info?.movie_image; else placeholderCover"
|
||||
[src]="item.info?.movie_image"
|
||||
/>
|
||||
<ng-template #placeholderCover>
|
||||
@if (item.info?.movie_image) {
|
||||
<img [src]="item.info?.movie_image" />
|
||||
} @else {
|
||||
<div class="placeholder-cover"></div>
|
||||
</ng-template>
|
||||
}
|
||||
</div>
|
||||
<div class="details">
|
||||
<h2>{{ item.info.name }}</h2>
|
||||
|
||||
Reference in new issue
Block a user