feat: create GenreService to load film genres from API
This commit is contained in:
parent
75c99b28ad
commit
6bfd167122
4 changed files with 72 additions and 23 deletions
|
|
@ -3,6 +3,7 @@ from rest_framework.permissions import IsAuthenticated
|
|||
from rest_framework.response import Response
|
||||
from .serializer import VideoSerializer
|
||||
from .models import Video
|
||||
from .class_assets import FILM_GENRES
|
||||
from django.core.cache.backends.base import DEFAULT_TIMEOUT
|
||||
from django.views.decorators.cache import cache_page
|
||||
from django.conf import settings
|
||||
|
|
@ -24,6 +25,15 @@ def video_list(request):
|
|||
serializer = VideoSerializer(videos, many=True)
|
||||
return Response(serializer.data)
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def genre_list(request):
|
||||
"""
|
||||
Return a list of film genres from static choices.
|
||||
"""
|
||||
genres = [{'code': code, 'name': name} for code, name in FILM_GENRES]
|
||||
return Response(genres)
|
||||
|
||||
@api_view(['GET'])
|
||||
@permission_classes([IsAuthenticated])
|
||||
def check_video_resolutions(request, id):
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ urlpatterns = [
|
|||
# Content URLs
|
||||
path('videos/', video_views.video_list, name='video_list'),
|
||||
path('video/upload/', video_views.video_upload, name='video_upload'),
|
||||
path('video/genres/', video_views.genre_list, name='genre_list'),
|
||||
path('video/<int:id>/', video_views.check_video_resolutions, name='check_video_resolutions'),
|
||||
|
||||
# Users URLs
|
||||
|
|
|
|||
|
|
@ -5,10 +5,13 @@ import {
|
|||
EventEmitter,
|
||||
HostListener,
|
||||
Input,
|
||||
OnInit,
|
||||
Output,
|
||||
} from '@angular/core';
|
||||
import { environment } from '../../../../environments/environment';
|
||||
import { VideoListComponent } from './video-list/video-list.component';
|
||||
import { FilmGenre, GenreService } from '../../../services/genre.service';
|
||||
import { Subject, takeUntil } from 'rxjs';
|
||||
|
||||
@Component({
|
||||
selector: 'app-categories',
|
||||
|
|
@ -17,7 +20,7 @@ import { VideoListComponent } from './video-list/video-list.component';
|
|||
templateUrl: './categories.component.html',
|
||||
styleUrl: './categories.component.scss',
|
||||
})
|
||||
export class CategoriesComponent implements AfterViewInit {
|
||||
export class CategoriesComponent implements OnInit, AfterViewInit {
|
||||
@Input() videos: any[] = [];
|
||||
@Input() currentVideo: number = 0;
|
||||
@Input() favoriteVideos: any[] = [];
|
||||
|
|
@ -26,32 +29,34 @@ export class CategoriesComponent implements AfterViewInit {
|
|||
|
||||
environmentBaseUrl: string = environment.baseUrl;
|
||||
isScrollable: boolean = false;
|
||||
filmGenres: FilmGenre[] = [];
|
||||
|
||||
filmGenres = [
|
||||
{ code: 'action', name: 'Action' },
|
||||
{ code: 'adventure', name: 'Adventure' },
|
||||
{ code: 'animation', name: 'Animation' },
|
||||
{ code: 'anime', name: 'Anime' },
|
||||
{ code: 'comedy', name: 'Comedy' },
|
||||
{ code: 'crime', name: 'Crime' },
|
||||
{ code: 'documentary', name: 'Documentary' },
|
||||
{ code: 'drama', name: 'Drama' },
|
||||
{ code: 'fantasy', name: 'Fantasy' },
|
||||
{ code: 'horror', name: 'Horror' },
|
||||
{ code: 'musical', name: 'Musical' },
|
||||
{ code: 'mystery', name: 'Mystery' },
|
||||
{ code: 'other', name: 'Miscellaneous' },
|
||||
{ code: 'romance', name: 'Romance' },
|
||||
{ code: 'science_fiction', name: 'Science Fiction' },
|
||||
{ code: 'thriller', name: 'Thriller' },
|
||||
{ code: 'war', name: 'War' },
|
||||
{ code: 'western', name: 'Western' },
|
||||
];
|
||||
private destroy$ = new Subject<void>();
|
||||
|
||||
ngAfterViewInit() {
|
||||
constructor(private genreService: GenreService) {}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.getFilmGenreNames();
|
||||
}
|
||||
|
||||
ngAfterViewInit(): void {
|
||||
this.checkScroll();
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.destroy$.next();
|
||||
this.destroy$.complete();
|
||||
}
|
||||
|
||||
getFilmGenreNames(): void {
|
||||
this.genreService
|
||||
.getGenres()
|
||||
.pipe(takeUntil(this.destroy$))
|
||||
.subscribe((genres) => {
|
||||
this.filmGenres = genres;
|
||||
});
|
||||
}
|
||||
|
||||
openCurrentVideo(videoId: number) {
|
||||
this.currentVideo = videoId;
|
||||
this.currentVideoId.emit(videoId);
|
||||
|
|
|
|||
33
frontend/src/app/services/genre.service.ts
Normal file
33
frontend/src/app/services/genre.service.ts
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import { Observable, of, tap } from 'rxjs';
|
||||
import { ApiService } from './api.service';
|
||||
|
||||
export interface FilmGenre {
|
||||
code: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class GenreService {
|
||||
private genres: FilmGenre[] = [];
|
||||
|
||||
constructor(private apiService: ApiService) {}
|
||||
|
||||
/**
|
||||
* Returns the genres either from the cache or from the API endpoint.
|
||||
* @returns observable of movie genres
|
||||
*/
|
||||
getGenres(): Observable<FilmGenre[]> {
|
||||
if (this.genres.length > 0) {
|
||||
return of(this.genres);
|
||||
}
|
||||
|
||||
return this.apiService.get<FilmGenre[]>('/video/genres/', true).pipe(
|
||||
tap((data) => {
|
||||
this.genres = data;
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue