Skip to content

Commit 04cb859

Browse files
committed
Final: Enhance app functionalities (#196)
1 parent 28d0b16 commit 04cb859

File tree

138 files changed

+63474
-87
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+63474
-87
lines changed

.idea/dataSources.local.xml

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MovieVerse-Frontend/js/favorites.js

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616

1717
let initialMoviesSelection = [];
1818
let initialTVSeriesSelection = [];
19+
const IMGPATH = `https://image.tmdb.org/t/p/w500`;
1920

2021
function translateFBC(value) {
2122
return atob(value);

MovieVerse-Frontend/js/movie-timeline.js

+48-10
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ function rotateImages(imageElements, interval = 3000) {
362362
function showMovies(movies, mainElement, startYear, endYear, append) {
363363
showSpinner();
364364

365+
// Add header for the selected year range if not appending
365366
if (!append) {
366367
mainElement.innerHTML = '';
367368
const header = document.createElement('h2');
@@ -370,31 +371,28 @@ function showMovies(movies, mainElement, startYear, endYear, append) {
370371
header.style.marginBottom = '20px';
371372
header.style.color = '#ff8623';
372373
header.style.fontSize = '23px';
373-
if (startYear === endYear) {
374-
header.textContent = `Movies released in ${startYear}`;
375-
} else {
376-
header.textContent = `Movies released between ${startYear} and ${endYear}`;
377-
}
374+
header.textContent = startYear === endYear ? `Movies released in ${startYear}` : `Movies released between ${startYear} and ${endYear}`;
375+
378376
const centerContainer1 = document.getElementById('center-container1');
379377
centerContainer1.innerHTML = '';
380378
centerContainer1.appendChild(header);
381379
centerContainer1.appendChild(mainElement);
382380
}
383381

384-
const observer = new IntersectionObserver(
382+
// Observer for loading additional images when movie enters viewport
383+
const imageObserver = new IntersectionObserver(
385384
async (entries, observer) => {
386385
for (const entry of entries) {
387386
if (entry.isIntersecting) {
388387
const movieEl = entry.target;
389388
const movieId = movieEl.dataset.id;
390389

390+
// Fetch and set up additional posters
391391
const additionalPosters = await getAdditionalPosters(movieId);
392392
let allPosters = [movieEl.dataset.posterPath, ...additionalPosters];
393-
394-
const movieImageContainer = movieEl.querySelector('.movie-images');
395-
396393
allPosters = allPosters.sort(() => 0.5 - Math.random()).slice(0, 10);
397394

395+
const movieImageContainer = movieEl.querySelector('.movie-images');
398396
const imagePromises = allPosters.map((poster, index) => {
399397
const img = new Image();
400398
img.src = `${IMGPATH + poster}`;
@@ -415,9 +413,11 @@ function showMovies(movies, mainElement, startYear, endYear, append) {
415413
});
416414
});
417415

416+
// Wait for images to load or timeout after 3 seconds
418417
const maxWait = new Promise(resolve => setTimeout(resolve, 3000));
419418
await Promise.race([Promise.all(imagePromises), maxWait]);
420419

420+
// Show the first poster image
421421
movieImageContainer.querySelector('.poster-img').style.opacity = '1';
422422

423423
rotateImages(Array.from(movieImageContainer.children));
@@ -441,6 +441,7 @@ function showMovies(movies, mainElement, startYear, endYear, append) {
441441
movieEl.dataset.posterPath = poster_path;
442442
movieEl.dataset.title = title;
443443

444+
// Limit the title to 8 words, adding "..." if necessary
444445
const words = title.split(' ');
445446
if (words.length >= 8) {
446447
words[7] = '...';
@@ -454,6 +455,7 @@ function showMovies(movies, mainElement, startYear, endYear, append) {
454455
overview = 'No overview available.';
455456
}
456457

458+
// Define HTML structure for the movie card
457459
movieEl.innerHTML = `
458460
<div class="movie-image-container">
459461
<div class="movie-images" style="position: relative; width: 100%; height: 435px; overflow: hidden;">
@@ -478,15 +480,51 @@ function showMovies(movies, mainElement, startYear, endYear, append) {
478480
});
479481

480482
mainElement.appendChild(movieEl);
481-
observer.observe(movieEl);
483+
imageObserver.observe(movieEl);
484+
485+
// Observer for the slide-up animation
486+
const slideObserver = new IntersectionObserver(
487+
entries => {
488+
entries.forEach(entry => {
489+
if (entry.isIntersecting) {
490+
entry.target.classList.add('visible');
491+
slideObserver.unobserve(entry.target);
492+
}
493+
});
494+
},
495+
{
496+
rootMargin: '50px 0px',
497+
threshold: 0.1,
498+
}
499+
);
500+
slideObserver.observe(movieEl);
482501
});
502+
483503
const centerContainer1 = document.getElementById('center-container1');
484504
centerContainer1.appendChild(mainElement);
485505

486506
createLoadMoreButton(startYear, endYear, mainElement);
487507
hideSpinner();
488508
}
489509

510+
// Inject CSS for sliding-up animation if it doesn't already exist
511+
if (!document.getElementById('slide-animation-style')) {
512+
const style = document.createElement('style');
513+
style.id = 'slide-animation-style';
514+
style.innerHTML = `
515+
.movie {
516+
opacity: 0;
517+
transform: translateY(20px);
518+
transition: opacity 0.6s ease, transform 0.6s ease;
519+
}
520+
.movie.visible {
521+
opacity: 1;
522+
transform: translateY(0);
523+
}
524+
`;
525+
document.head.appendChild(style);
526+
}
527+
490528
function createLoadMoreButton(startYear, endYear, mainElement) {
491529
const existingButtonDiv = mainElement.querySelector('.load-more-container');
492530
if (existingButtonDiv) {

MovieVerse-Frontend/js/search.js

+32-2
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,21 @@ function rotateImages(imageElements, interval = 3000) {
807807
async function showMovies(items, container, category) {
808808
container.innerHTML = '';
809809

810+
// Inject CSS for sliding-up animation if it doesn't already exist
811+
const style = document.createElement('style');
812+
style.innerHTML = `
813+
.movie {
814+
opacity: 0;
815+
transform: translateY(20px);
816+
transition: opacity 1s ease, transform 1s ease;
817+
}
818+
.movie.visible {
819+
opacity: 1;
820+
transform: translateY(0);
821+
}
822+
`;
823+
document.head.appendChild(style);
824+
810825
items.forEach(async item => {
811826
const hasVoteAverage = typeof item.vote_average === 'number';
812827
const isPerson = !hasVoteAverage;
@@ -815,15 +830,13 @@ async function showMovies(items, container, category) {
815830

816831
let title = item.title || item.name || 'N/A';
817832
const words = title.split(' ');
818-
819833
if (words.length >= 8) {
820834
words[7] = '...';
821835
title = words.slice(0, 8).join(' ');
822836
}
823837

824838
let overview = item.overview || 'Click to view the details of this movie/TV series.';
825839
const biography = item.biography || 'Click to view the details of this person.';
826-
827840
if (overview === '') {
828841
overview = 'Click to view the details of this movie/TV series.';
829842
}
@@ -971,6 +984,23 @@ async function showMovies(items, container, category) {
971984
const img = movieEl.querySelector('img');
972985
observer.observe(img);
973986
}
987+
988+
// Slide-up animation observer
989+
const slideObserver = new IntersectionObserver(
990+
entries => {
991+
entries.forEach(entry => {
992+
if (entry.isIntersecting) {
993+
entry.target.classList.add('visible');
994+
slideObserver.unobserve(entry.target);
995+
}
996+
});
997+
},
998+
{
999+
rootMargin: '50px 0px',
1000+
threshold: 0.1,
1001+
}
1002+
);
1003+
slideObserver.observe(movieEl);
9741004
});
9751005
}
9761006

MovieVerse-Mobile/.idea/caches/deviceStreaming.xml

+22-11
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

MovieVerse-Mobile/platforms/android/app/src/main/assets/www/MovieVerse-Frontend/js/favorites.js

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616

1717
let initialMoviesSelection = [];
1818
let initialTVSeriesSelection = [];
19+
const IMGPATH = `https://image.tmdb.org/t/p/w500`;
1920

2021
function translateFBC(value) {
2122
return atob(value);

MovieVerse-Mobile/platforms/android/app/src/main/assets/www/MovieVerse-Frontend/js/movie-timeline.js

+48-10
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,7 @@ function rotateImages(imageElements, interval = 3000) {
362362
function showMovies(movies, mainElement, startYear, endYear, append) {
363363
showSpinner();
364364

365+
// Add header for the selected year range if not appending
365366
if (!append) {
366367
mainElement.innerHTML = '';
367368
const header = document.createElement('h2');
@@ -370,31 +371,28 @@ function showMovies(movies, mainElement, startYear, endYear, append) {
370371
header.style.marginBottom = '20px';
371372
header.style.color = '#ff8623';
372373
header.style.fontSize = '23px';
373-
if (startYear === endYear) {
374-
header.textContent = `Movies released in ${startYear}`;
375-
} else {
376-
header.textContent = `Movies released between ${startYear} and ${endYear}`;
377-
}
374+
header.textContent = startYear === endYear ? `Movies released in ${startYear}` : `Movies released between ${startYear} and ${endYear}`;
375+
378376
const centerContainer1 = document.getElementById('center-container1');
379377
centerContainer1.innerHTML = '';
380378
centerContainer1.appendChild(header);
381379
centerContainer1.appendChild(mainElement);
382380
}
383381

384-
const observer = new IntersectionObserver(
382+
// Observer for loading additional images when movie enters viewport
383+
const imageObserver = new IntersectionObserver(
385384
async (entries, observer) => {
386385
for (const entry of entries) {
387386
if (entry.isIntersecting) {
388387
const movieEl = entry.target;
389388
const movieId = movieEl.dataset.id;
390389

390+
// Fetch and set up additional posters
391391
const additionalPosters = await getAdditionalPosters(movieId);
392392
let allPosters = [movieEl.dataset.posterPath, ...additionalPosters];
393-
394-
const movieImageContainer = movieEl.querySelector('.movie-images');
395-
396393
allPosters = allPosters.sort(() => 0.5 - Math.random()).slice(0, 10);
397394

395+
const movieImageContainer = movieEl.querySelector('.movie-images');
398396
const imagePromises = allPosters.map((poster, index) => {
399397
const img = new Image();
400398
img.src = `${IMGPATH + poster}`;
@@ -415,9 +413,11 @@ function showMovies(movies, mainElement, startYear, endYear, append) {
415413
});
416414
});
417415

416+
// Wait for images to load or timeout after 3 seconds
418417
const maxWait = new Promise(resolve => setTimeout(resolve, 3000));
419418
await Promise.race([Promise.all(imagePromises), maxWait]);
420419

420+
// Show the first poster image
421421
movieImageContainer.querySelector('.poster-img').style.opacity = '1';
422422

423423
rotateImages(Array.from(movieImageContainer.children));
@@ -441,6 +441,7 @@ function showMovies(movies, mainElement, startYear, endYear, append) {
441441
movieEl.dataset.posterPath = poster_path;
442442
movieEl.dataset.title = title;
443443

444+
// Limit the title to 8 words, adding "..." if necessary
444445
const words = title.split(' ');
445446
if (words.length >= 8) {
446447
words[7] = '...';
@@ -454,6 +455,7 @@ function showMovies(movies, mainElement, startYear, endYear, append) {
454455
overview = 'No overview available.';
455456
}
456457

458+
// Define HTML structure for the movie card
457459
movieEl.innerHTML = `
458460
<div class="movie-image-container">
459461
<div class="movie-images" style="position: relative; width: 100%; height: 435px; overflow: hidden;">
@@ -478,15 +480,51 @@ function showMovies(movies, mainElement, startYear, endYear, append) {
478480
});
479481

480482
mainElement.appendChild(movieEl);
481-
observer.observe(movieEl);
483+
imageObserver.observe(movieEl);
484+
485+
// Observer for the slide-up animation
486+
const slideObserver = new IntersectionObserver(
487+
entries => {
488+
entries.forEach(entry => {
489+
if (entry.isIntersecting) {
490+
entry.target.classList.add('visible');
491+
slideObserver.unobserve(entry.target);
492+
}
493+
});
494+
},
495+
{
496+
rootMargin: '50px 0px',
497+
threshold: 0.1,
498+
}
499+
);
500+
slideObserver.observe(movieEl);
482501
});
502+
483503
const centerContainer1 = document.getElementById('center-container1');
484504
centerContainer1.appendChild(mainElement);
485505

486506
createLoadMoreButton(startYear, endYear, mainElement);
487507
hideSpinner();
488508
}
489509

510+
// Inject CSS for sliding-up animation if it doesn't already exist
511+
if (!document.getElementById('slide-animation-style')) {
512+
const style = document.createElement('style');
513+
style.id = 'slide-animation-style';
514+
style.innerHTML = `
515+
.movie {
516+
opacity: 0;
517+
transform: translateY(20px);
518+
transition: opacity 0.6s ease, transform 0.6s ease;
519+
}
520+
.movie.visible {
521+
opacity: 1;
522+
transform: translateY(0);
523+
}
524+
`;
525+
document.head.appendChild(style);
526+
}
527+
490528
function createLoadMoreButton(startYear, endYear, mainElement) {
491529
const existingButtonDiv = mainElement.querySelector('.load-more-container');
492530
if (existingButtonDiv) {

0 commit comments

Comments
 (0)