responsive design & bugfixes

This commit is contained in:
Chneemann 2024-08-21 04:34:54 +02:00
parent fd7cb3a8dc
commit 55b63966cf
6 changed files with 178 additions and 30 deletions

View file

@ -30,8 +30,7 @@ def video_list(request):
@permission_classes([IsAuthenticated]) @permission_classes([IsAuthenticated])
def check_video(request, id): def check_video(request, id):
""" """
Check if a specific video exists in 480p, 720p, and 1080p resolutions Check if a specific video exists in different resolutions (480p, 720p, 1080p).
URL: /content/movie/<video_id>/
""" """
resolutions = ['480', '720', '1080'] resolutions = ['480', '720', '1080']
result = {} result = {}
@ -49,9 +48,13 @@ def check_video(request, id):
result[res] = os.path.exists(video_file_path) result[res] = os.path.exists(video_file_path)
return JsonResponse(result) return JsonResponse(result)
@api_view(['POST']) @api_view(['POST'])
@permission_classes([IsAuthenticated]) @permission_classes([IsAuthenticated])
def video_upload(request): def video_upload(request):
"""
Handle the upload of a video file.
"""
parser_classes = (MultiPartParser, FormParser) parser_classes = (MultiPartParser, FormParser)
if request.method == 'POST': if request.method == 'POST':
serializer = VideoSerializer(data=request.data) serializer = VideoSerializer(data=request.data)

View file

@ -3,6 +3,7 @@
<div *ngIf="recentMovies().length > 0" class="category"> <div *ngIf="recentMovies().length > 0" class="category">
<p>Added in the last 7 days</p> <p>Added in the last 7 days</p>
<div class="movies"> <div class="movies">
<!-- Filme hier einfügen -->
@for (movie of recentMovies(); track movie) { @for (movie of recentMovies(); track movie) {
<div class="movie" (click)="openCurrentMovie(movie.id)"> <div class="movie" (click)="openCurrentMovie(movie.id)">
<img <img
@ -19,16 +20,22 @@
/> />
</div> </div>
} }
<!-- Buttons for scrolling -->
<div class="scroll-buttons">
<button class="scroll-left" (click)="scrollLeft($event)"></button>
<button class="scroll-right" (click)="scrollRight($event)"></button>
</div> </div>
</div> </div>
</div>
<!-- Genre columns --> <!-- Genre columns -->
@for (filmGenre of filmGenres; track filmGenre) { @for (filmGenre of filmGenres; track filmGenre) {
<!-- Movie available in genre --> <!-- Movie available in genre -->
@if (allMovies(filmGenre).length > 0) { @if (allMovies(filmGenre.code).length > 0) {
<div class="category"> <div class="category">
<p>{{ filmGenre }}</p> <p>{{ filmGenre.name }}</p>
<div class="movies"> <div class="movies">
@for (movie of allMovies(filmGenre); track movie) { @for (movie of allMovies(filmGenre.code); track movie) {
<div class="movie" (click)="openCurrentMovie(movie.id)"> <div class="movie" (click)="openCurrentMovie(movie.id)">
<img <img
[ngClass]="{ selected: movie.id === currentMovie }" [ngClass]="{ selected: movie.id === currentMovie }"
@ -44,6 +51,11 @@
/> />
</div> </div>
} }
<!-- Buttons for scrolling -->
<div class="scroll-buttons">
<button class="scroll-left" (click)="scrollLeft($event)"></button>
<button class="scroll-right" (click)="scrollRight($event)"></button>
</div>
</div> </div>
</div> </div>
} } } }

View file

@ -1,22 +1,21 @@
@import "./../../../../../assets/style/colors.scss"; @import "./../../../../../assets/style/colors.scss";
section { section {
padding: 0 48px;
margin-top: 12px; margin-top: 12px;
padding: 0 24px;
margin: 0 24px;
} }
.category { .category {
position: relative;
height: 165px; height: 165px;
padding-top: 12px;
p { p {
font-size: 22px; font-size: 22px;
font-weight: 700; font-weight: 700;
} }
} }
.movies {
display: flex;
}
.movie { .movie {
width: 213px; width: 213px;
height: 120px; height: 120px;
@ -38,11 +37,71 @@ section {
border: 2px solid $blue !important; border: 2px solid $blue !important;
} }
// Movies
.movies {
display: flex;
overflow-x: auto;
overflow-y: hidden;
-ms-overflow-style: none;
scrollbar-width: none;
padding: 0 24x;
}
.movies::-webkit-scrollbar {
display: none;
}
.scroll-buttons {
position: absolute;
top: 50%;
width: 100%;
display: flex;
opacity: 0;
justify-content: space-between;
pointer-events: none;
transform: translateY(-50%);
}
.scroll-buttons.show {
opacity: 1; /* Sichtbar machen, wenn Klasse 'show' hinzugefügt wird */
}
.scroll-left,
.scroll-right {
background: url("./../../../../../assets/img/arrow_forward.svg") no-repeat
center;
background-size: 20px 30px;
border: none;
width: 40px;
height: 40px;
cursor: pointer;
pointer-events: auto;
&:hover {
transition: 125ms ease-in-out;
filter: brightness(0) saturate(100%) invert(26%) sepia(77%) saturate(2342%)
hue-rotate(228deg) brightness(83%) contrast(115%);
}
}
.scroll-left {
position: absolute;
left: -32px;
background-image: url("./../../../../../assets/img/arrow_back.svg");
}
.scroll-right {
position: absolute;
right: -38px;
background-image: url("./../../../../../assets/img/arrow_forward.svg");
}
// Hide scrollbar // Hide scrollbar
.hide-scrollbar { .hide-scrollbar {
overflow: scroll; overflow-y: auto;
height: 60%; overflow-x: hidden;
height: 50%;
-ms-overflow-style: none; -ms-overflow-style: none;
scrollbar-width: none; scrollbar-width: none;
} }
@ -50,3 +109,14 @@ section {
.hide-scrollbar::-webkit-scrollbar { .hide-scrollbar::-webkit-scrollbar {
width: 0px; width: 0px;
} }
/*------------- RESPONSIVE -------------*/
@media screen and (max-width: 400px) {
.category {
p {
font-size: 18px;
font-weight: 700;
}
}
}

View file

@ -1,5 +1,15 @@
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { Component, EventEmitter, Input, Output } from '@angular/core'; import {
ChangeDetectorRef,
Component,
ElementRef,
EventEmitter,
HostListener,
Input,
Output,
Renderer2,
ViewChild,
} from '@angular/core';
import { environment } from '../../../../environments/environment'; import { environment } from '../../../../environments/environment';
@Component({ @Component({
@ -15,26 +25,32 @@ export class CategoriesComponent {
@Output() currentMovieId = new EventEmitter<number>(); @Output() currentMovieId = new EventEmitter<number>();
environmentBaseUrl: string = environment.baseUrl; environmentBaseUrl: string = environment.baseUrl;
isScrollable: boolean = false;
filmGenres = [ filmGenres = [
'action', { code: 'action', name: 'Action' },
'adventure', { code: 'adventure', name: 'Adventure' },
'comedy', { code: 'comedy', name: 'Comedy' },
'drama', { code: 'drama', name: 'Drama' },
'horror', { code: 'horror', name: 'Horror' },
'science_fiction', { code: 'science_fiction', name: 'Science Fiction' },
'fantasy', { code: 'fantasy', name: 'Fantasy' },
'romance', { code: 'romance', name: 'Romance' },
'thriller', { code: 'thriller', name: 'Thriller' },
'mystery', { code: 'mystery', name: 'Mystery' },
'crime', { code: 'crime', name: 'Crime' },
'animation', { code: 'animation', name: 'Animation' },
'documentary', { code: 'documentary', name: 'Documentary' },
'musical', { code: 'musical', name: 'Musical' },
'war', { code: 'war', name: 'War' },
'western', { code: 'western', name: 'Western' },
{ code: 'other', name: 'Miscellaneous' },
]; ];
ngAfterViewInit() {
this.checkScroll();
}
openCurrentMovie(movieId: number) { openCurrentMovie(movieId: number) {
this.currentMovie = movieId; this.currentMovie = movieId;
this.currentMovieId.emit(movieId); this.currentMovieId.emit(movieId);
@ -50,8 +66,53 @@ export class CategoriesComponent {
sevenDaysAgo.setDate(today.getDate() - 7); sevenDaysAgo.setDate(today.getDate() - 7);
return this.movies.filter((movie) => { return this.movies.filter((movie) => {
const movieDate = new Date(movie.create); const movieDate = new Date(movie.created_at);
return movieDate >= sevenDaysAgo; return movieDate >= sevenDaysAgo;
}); });
} }
// Category scroll
@HostListener('window:resize')
onResize() {
this.checkScroll();
}
checkScroll() {
const containers = document.querySelectorAll(
'.movies'
) as NodeListOf<HTMLElement>;
containers.forEach((container) => {
const scrollButtons = container.parentElement?.querySelector(
'.scroll-buttons'
) as HTMLElement;
if (container && scrollButtons) {
if (container.scrollWidth > container.clientWidth) {
scrollButtons.classList.add('show');
} else {
scrollButtons.classList.remove('show');
}
}
});
}
scrollLeft(event: MouseEvent) {
const button = event.target as HTMLElement;
const container = button
.closest('.category')
?.querySelector('.movies') as HTMLElement;
if (container) {
container.scrollLeft -= 217;
}
}
scrollRight(event: MouseEvent) {
const button = event.target as HTMLElement;
const container = button
.closest('.category')
?.querySelector('.movies') as HTMLElement;
if (container) {
container.scrollLeft += 217;
}
}
} }

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="M400-80 0-480l400-400 71 71-329 329 329 329-71 71Z"/></svg>

After

Width:  |  Height:  |  Size: 175 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="#e8eaed"><path d="m321-80-71-71 329-329-329-329 71-71 400 400L321-80Z"/></svg>

After

Width:  |  Height:  |  Size: 176 B