diff --git a/src/app/home/course/course.page.html b/src/app/home/course/course.page.html index b8559e9..dbca674 100644 --- a/src/app/home/course/course.page.html +++ b/src/app/home/course/course.page.html @@ -101,7 +101,19 @@ } - @if (list$ | async; as list) { + + + @if (filteredList$ | async; as list) { + @if (list.length === 0 && searchQuery) { + + + No videos found matching "{{ searchQuery }}" + + + } @for (lecture of list; track lecture.id) { ; + filteredList$: Observable; courseProgress = { viewed: 0, duration: 0 }; + searchQuery = ''; + searchQuery$ = new Subject(); isAndroid = /Android/i.test(navigator.userAgent); isIos = /iPad/i.test(navigator.userAgent) || /iPhone/i.test(navigator.userAgent); lastPlayedVideoKey: number = null; @@ -128,6 +133,10 @@ export class CoursePage implements OnInit, AfterViewInit, OnDestroy { return EMPTY; }) ); + + this.filteredList$ = combineLatest([this.list$, this.searchQuery$.pipe(startWith(''))]).pipe( + map(([videos, query]) => this.filterVideos(videos, query)) + ); } ngAfterViewInit() { @@ -276,6 +285,23 @@ export class CoursePage implements OnInit, AfterViewInit, OnDestroy { : videoInfo; } + filterVideos(videos: Lecture[], query: string): Lecture[] { + if (!query.trim()) { + return videos; + } + + const lowerQuery = query.toLowerCase(); + return videos.filter(video => + video.title.toLowerCase().includes(lowerQuery) || + (video.lecturer && video.lecturer.toLowerCase().includes(lowerQuery)) + ); + } + + onSearchChange(event: any) { + this.searchQuery = event.detail.value ?? ''; + this.searchQuery$.next(this.searchQuery); + } + viewVideo(video: Lecture) { video.sources = video.sources.filter(source => { if (source.type === 'video/youtube') {