diff --git a/frontend/src/app/components/home/browse/browse.component.html b/frontend/src/app/components/home/browse/browse.component.html index 2e9268d..3b84321 100644 --- a/frontend/src/app/components/home/browse/browse.component.html +++ b/frontend/src/app/components/home/browse/browse.component.html @@ -11,9 +11,9 @@ -
+
600); + isWideScreen() { + return window.innerWidth > 600; } onMovieIsUploadedChange(newStatus: { [resolution: string]: boolean }) { diff --git a/frontend/src/app/components/home/browse/categories/categories.component.html b/frontend/src/app/components/home/browse/categories/categories.component.html index c0d4b58..074147e 100644 --- a/frontend/src/app/components/home/browse/categories/categories.component.html +++ b/frontend/src/app/components/home/browse/categories/categories.component.html @@ -1,82 +1,44 @@ -
- -
+@if (movies.length > 0) { +
+ + @if (recentMovies().length > 0) { +

New movies added this week

-
- - @for (movie of recentMovies(); track movie) { -
- -
- } - -
- - -
-
+
+ } - -
+ + @if (favoriteMovies.length > 0) { +

Favorites

-
- - @for (favorite of favoriteMovies; track favorite) { - - @for (movie of movies; track movie) { - - @if (movie.id === favorite) { -
- -
- } } } - -
- - -
-
+
+ } + @for (filmGenre of filmGenres; track filmGenre) { - + @if (allMovies(filmGenre.code).length > 0) {

{{ filmGenre.name }}

-
- - @for (movie of allMovies(filmGenre.code); track movie) { - -
- - @if (watchedMovies.includes(movie.id)) { -
- -
- } -
- } - -
- - -
-
+
} }
+} diff --git a/frontend/src/app/components/home/browse/categories/categories.component.scss b/frontend/src/app/components/home/browse/categories/categories.component.scss index 4066b26..a143806 100644 --- a/frontend/src/app/components/home/browse/categories/categories.component.scss +++ b/frontend/src/app/components/home/browse/categories/categories.component.scss @@ -16,103 +16,6 @@ section { } } -// Movies - -.movie { - position: relative; - width: 213px; - height: 120px; - padding: 6px; - .banner { - img { - width: 213px; - height: 120px; - transition: scale 300ms ease-in-out; - border: 2px solid rgba($black, 0); - cursor: pointer; - &:hover { - scale: 1.02; - border: 2px solid $blue; - } - } - } - .watched { - position: absolute; - top: 15px; - right: 15px; - z-index: 2; - img { - width: 24px; - height: auto; - filter: brightness(0) saturate(100%) invert(100%) sepia(28%) saturate(1%) - hue-rotate(288deg) brightness(101%) contrast(101%) - drop-shadow(0 0 5px rgba(38, 143, 255, 1)); - } - } -} - -.selected { - border: 2px solid $blue !important; -} - -.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 - -.scroll-buttons { - position: absolute; - top: 50%; - width: 100%; - display: none; - justify-content: space-between; - pointer-events: none; - transform: translateY(-50%); -} - -.scroll-buttons.show { - display: flex; -} - -.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 { @@ -130,12 +33,6 @@ section { /*------------- RESPONSIVE -------------*/ -@media screen and (max-width: 600px) { - .hide-scrollbar { - height: calc(100% - 120px); - } -} - @media screen and (max-width: 400px) { .category { p { @@ -144,3 +41,13 @@ section { } } } + +@media screen and (max-width: 600px) { + section { + margin: 0 12px; + } + + .hide-scrollbar { + height: calc(100% - 120px); + } +} diff --git a/frontend/src/app/components/home/browse/categories/categories.component.ts b/frontend/src/app/components/home/browse/categories/categories.component.ts index 0fbd051..9a04e2d 100644 --- a/frontend/src/app/components/home/browse/categories/categories.component.ts +++ b/frontend/src/app/components/home/browse/categories/categories.component.ts @@ -8,11 +8,12 @@ import { Output, } from '@angular/core'; import { environment } from '../../../../../environments/environment'; +import { MoviesListComponent } from './movie-list/movie-list.component'; @Component({ selector: 'app-categories', standalone: true, - imports: [CommonModule], + imports: [CommonModule, MoviesListComponent], templateUrl: './categories.component.html', styleUrl: './categories.component.scss', }) @@ -47,6 +48,12 @@ export class CategoriesComponent implements AfterViewInit { { code: 'western', name: 'Western' }, ]; + getFavoriteMovies() { + return this.movies.filter((movie) => + this.favoriteMovies.includes(movie.id) + ); + } + ngAfterViewInit() { this.checkScroll(); } diff --git a/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.html b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.html new file mode 100644 index 0000000..5a6b3b4 --- /dev/null +++ b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.html @@ -0,0 +1,33 @@ +
+ + @for (movie of movies; track movie) { +
+ +
+ +
+
+ } + + +
+ + +
+
diff --git a/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.scss b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.scss new file mode 100644 index 0000000..c9e6404 --- /dev/null +++ b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.scss @@ -0,0 +1,99 @@ +@use "./../../../../../../assets/style/colors.scss" as *; + +.movies { + display: flex; + overflow-x: auto; + overflow-y: hidden; + -ms-overflow-style: none; + scrollbar-width: none; + padding-bottom: 24px; +} + +.movies::-webkit-scrollbar { + display: none; +} + +.movie { + position: relative; + width: 213px; + height: 120px; + padding: 6px; + .banner { + img { + width: 213px; + height: 120px; + transition: scale 300ms ease-in-out; + border: 2px solid rgba($black, 0); + cursor: pointer; + &:hover { + scale: 1.02; + border: 2px solid $blue; + } + } + } + .watched { + position: absolute; + top: 15px; + right: 15px; + z-index: 2; + img { + width: 24px; + height: auto; + filter: brightness(0) saturate(100%) invert(100%) sepia(28%) saturate(1%) + hue-rotate(288deg) brightness(101%) contrast(101%) + drop-shadow(0 0 5px rgba(38, 143, 255, 1)); + } + } +} + +.selected { + border: 2px solid $blue !important; +} + +// Scroll buttons + +.scroll-buttons { + position: absolute; + top: 50%; + width: 100%; + display: none; + justify-content: space-between; + pointer-events: none; + transform: translateY(-50%); +} + +.scroll-buttons.show { + display: flex; +} + +.scroll-left, +.scroll-right { + position: absolute; + 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 { + left: -25px; +} + +.scroll-right { + right: -25px; +} + +/*------------- RESPONSIVE -------------*/ + +@media screen and (max-width: 600px) { + .hide-scrollbar { + height: calc(100% - 120px); + } +} diff --git a/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.spec.ts b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.spec.ts new file mode 100644 index 0000000..8edebd7 --- /dev/null +++ b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { MoviesListComponent } from './movie-list.component'; + +describe('MoviesListComponent', () => { + let component: MoviesListComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [MoviesListComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(MoviesListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.ts b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.ts new file mode 100644 index 0000000..50809f2 --- /dev/null +++ b/frontend/src/app/components/home/browse/categories/movie-list/movie-list.component.ts @@ -0,0 +1,47 @@ +import { Component, Input, Output, EventEmitter } from '@angular/core'; +import { environment } from '../../../../../../environments/environment'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-movie-list', + standalone: true, + imports: [CommonModule], + templateUrl: './movie-list.component.html', + styleUrls: ['./movie-list.component.scss'], +}) +export class MoviesListComponent { + @Input() movies: any[] = []; + @Input() currentMovie: number = 0; + @Input() watchedMovies: any[] = []; + @Input() movieCategory: string = ''; + @Output() currentMovieId = new EventEmitter(); + + getThumbnailUrl(movieId: number, fileName: string): string { + return `${environment.baseUrl}/media/thumbnails/${movieId}/${fileName}_480p.jpg`; + } + + openCurrentMovie(movieId: number) { + this.currentMovie = movieId; + this.currentMovieId.emit(movieId); + } + + 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; + } + } +} diff --git a/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.html b/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.html index c3a6f4a..d829c44 100644 --- a/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.html +++ b/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.html @@ -1,12 +1,12 @@
@@ -30,21 +30,21 @@
{{ currentMovie[0].title }}
{{ currentMovie[0].description }}
; @Input() currentMovie: any[] = []; - @Input() screenWidth: boolean = false; + @Input() isWideScreen: boolean = false; @Input() favoriteMovies: any[] = []; @Input() watchedMovies: any[] = []; @Output() playMovie = new EventEmitter(); diff --git a/frontend/src/assets/img/arrow_forward.svg b/frontend/src/assets/img/arrow_forward.svg index 2c983e6..a65bab7 100644 --- a/frontend/src/assets/img/arrow_forward.svg +++ b/frontend/src/assets/img/arrow_forward.svg @@ -1 +1,3 @@ - \ No newline at end of file + + + \ No newline at end of file