mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 01:56:16 -08:00
feat: search playlists by title
This commit is contained in:
1 parent
83ad115b43
commit
c839254deb
3 files changed
+89
-47
No files matched your search
@@ -1,10 +1,24 @@
|
||||
<ng-container *ngIf="allPlaylistsLoaded$ | async; else skeletonView">
|
||||
<mat-form-field
|
||||
class="full-width"
|
||||
subscriptSizing="dynamic"
|
||||
style="border-radius: 0px"
|
||||
>
|
||||
<input
|
||||
matInput
|
||||
#searchQuery
|
||||
type="search"
|
||||
[placeholder]="'HOME.PLAYLISTS.SEARCH_PLAYLISTS' | translate"
|
||||
(input)="onSearchQueryUpdate(searchQuery.value)"
|
||||
/></mat-form-field>
|
||||
|
||||
<mat-nav-list
|
||||
cdkDropList
|
||||
(cdkDropListDropped)="drop($event, playlists)"
|
||||
*ngIf="playlists$ | async as playlists"
|
||||
class="playlists-list"
|
||||
>
|
||||
<mat-list-item *ngIf="playlists.length === 0">
|
||||
<mat-list-item *ngIf="playlists.length === 0; else playlistsTemplate">
|
||||
<mat-icon class="favorites-icon" matListItemAvatar>search</mat-icon>
|
||||
<div matListItemTitle>
|
||||
{{ 'HOME.PLAYLISTS.NO_PLAYLISTS' | translate }}
|
||||
@@ -13,51 +27,56 @@
|
||||
{{ 'HOME.PLAYLISTS.ADD_FIRST' | translate }}
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-list-item
|
||||
*ngIf="playlists.length > 0"
|
||||
(click)="getGlobalFavorites()"
|
||||
>
|
||||
<mat-icon class="favorites-icon" matListItemAvatar>star</mat-icon>
|
||||
<div matListItemTitle>
|
||||
{{ 'HOME.PLAYLISTS.GLOBAL_FAVORITES' | translate }}
|
||||
</div>
|
||||
<div matListItemLine class="meta">
|
||||
{{ 'HOME.PLAYLISTS.GLOBAL_FAVORITES_DESCRIPTION' | translate }}
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<app-playlist-item
|
||||
*ngFor="let item of playlists; last as last"
|
||||
[item]="item"
|
||||
[showActions]="!sidebarMode"
|
||||
(editPlaylistClicked)="openInfoDialog($event)"
|
||||
(playlistClicked)="getPlaylist(item)"
|
||||
(refreshClicked)="refreshPlaylist($event)"
|
||||
(removeClicked)="removeClicked($event)"
|
||||
></app-playlist-item>
|
||||
<ng-template #playlistsTemplate>
|
||||
<mat-list-item (click)="getGlobalFavorites()">
|
||||
<mat-icon class="favorites-icon" matListItemAvatar
|
||||
>star</mat-icon
|
||||
>
|
||||
<div matListItemTitle>
|
||||
{{ 'HOME.PLAYLISTS.GLOBAL_FAVORITES' | translate }}
|
||||
</div>
|
||||
<div matListItemLine class="meta">
|
||||
{{
|
||||
'HOME.PLAYLISTS.GLOBAL_FAVORITES_DESCRIPTION'
|
||||
| translate
|
||||
}}
|
||||
</div>
|
||||
</mat-list-item>
|
||||
<mat-divider></mat-divider>
|
||||
|
||||
<div *ngIf="isMigrationPossible" id="migration-container">
|
||||
<p>{{ migrationMessage }}</p>
|
||||
<button
|
||||
mat-button
|
||||
(click)="migratePlaylists()"
|
||||
class="migration-btn"
|
||||
color="accent"
|
||||
>
|
||||
<mat-icon>playlist_add</mat-icon>
|
||||
Migrate playlists</button
|
||||
>
|
||||
<button
|
||||
mat-button
|
||||
(click)="deleteMigratedPlaylists()"
|
||||
class="migration-btn"
|
||||
color="accent"
|
||||
>
|
||||
<mat-icon>delete</mat-icon>
|
||||
Delete all playlists
|
||||
</button>
|
||||
</div>
|
||||
<app-playlist-item
|
||||
*ngFor="let item of playlists; last as last; trackBy: trackByFn"
|
||||
[item]="item"
|
||||
[showActions]="!sidebarMode"
|
||||
(editPlaylistClicked)="openInfoDialog($event)"
|
||||
(playlistClicked)="getPlaylist(item)"
|
||||
(refreshClicked)="refreshPlaylist($event)"
|
||||
(removeClicked)="removeClicked($event)"
|
||||
></app-playlist-item>
|
||||
|
||||
<div *ngIf="isMigrationPossible" id="migration-container">
|
||||
<p>{{ migrationMessage }}</p>
|
||||
<button
|
||||
mat-button
|
||||
(click)="migratePlaylists()"
|
||||
class="migration-btn"
|
||||
color="accent"
|
||||
>
|
||||
<mat-icon>playlist_add</mat-icon>
|
||||
Migrate playlists</button
|
||||
>
|
||||
<button
|
||||
mat-button
|
||||
(click)="deleteMigratedPlaylists()"
|
||||
class="migration-btn"
|
||||
color="accent"
|
||||
>
|
||||
<mat-icon>delete</mat-icon>
|
||||
{{ 'SETTINGS.REMOVE_DIALOG.TITLE' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
</mat-nav-list>
|
||||
</ng-container>
|
||||
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.playlists-list {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.meta {
|
||||
font-size: 12px !important;
|
||||
color: #666;
|
||||
|
||||
@@ -12,7 +12,7 @@ import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { Router } from '@angular/router';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { map } from 'rxjs';
|
||||
import { BehaviorSubject, combineLatest, map } from 'rxjs';
|
||||
import { GLOBAL_FAVORITES_PLAYLIST_ID } from '../../../../shared/constants';
|
||||
import { IpcCommand } from '../../../../shared/ipc-command.class';
|
||||
import { Playlist } from '../../../../shared/playlist.interface';
|
||||
@@ -42,9 +42,20 @@ import { PlaylistInfoComponent } from './playlist-info/playlist-info.component';
|
||||
styleUrls: ['./recent-playlists.component.scss'],
|
||||
})
|
||||
export class RecentPlaylistsComponent implements OnDestroy {
|
||||
playlists$ = this.store.select(selectAllPlaylistsMeta).pipe(
|
||||
searchQuery = new BehaviorSubject('');
|
||||
|
||||
playlists$ = combineLatest([
|
||||
this.store.select(selectAllPlaylistsMeta),
|
||||
this.searchQuery,
|
||||
]).pipe(
|
||||
// eslint-disable-next-line @ngrx/avoid-mapping-selectors
|
||||
map((playlists) => playlists.sort((a, b) => a.position - b.position))
|
||||
map(([playlists, searchQuery]) =>
|
||||
playlists
|
||||
.sort((a, b) => a.position - b.position)
|
||||
.filter((item) =>
|
||||
item.title.toLowerCase().includes(searchQuery.toLowerCase())
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
allPlaylistsLoaded$ = this.store.select(selectPlaylistsLoadingFlag);
|
||||
@@ -229,4 +240,12 @@ export class RecentPlaylistsComponent implements OnDestroy {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
trackByFn(_index: number, item: PlaylistMeta) {
|
||||
return item._id;
|
||||
}
|
||||
|
||||
onSearchQueryUpdate(searchQuery: string) {
|
||||
this.searchQuery.next(searchQuery);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user