@@ -3,7 +3,9 @@ const searchButton = document.getElementById("button-search");
3
3
const form = document . getElementById ( "form1" ) ;
4
4
const main = document . getElementById ( "main" ) ;
5
5
const IMGPATH = "https://image.tmdb.org/t/p/w1280" ;
6
+ const IMGPATH2 = "https://image.tmdb.org/t/p/w185" ;
6
7
const searchTitle = document . getElementById ( "search-title" ) ;
8
+ let currentIndex = sessionStorage . getItem ( 'currentIndex' ) ? parseInt ( sessionStorage . getItem ( 'currentIndex' ) ) : 0 ;
7
9
8
10
function showSpinner ( ) {
9
11
document . getElementById ( 'myModal' ) . classList . add ( 'modal-visible' ) ;
@@ -89,6 +91,7 @@ let initialMainContent = '';
89
91
90
92
document . addEventListener ( 'DOMContentLoaded' , ( ) => {
91
93
initialMainContent = document . getElementById ( 'main' ) . innerHTML ;
94
+ currentIndex = 0 ;
92
95
93
96
const actorId = localStorage . getItem ( 'selectedActorId' ) ;
94
97
if ( actorId ) {
@@ -97,8 +100,6 @@ document.addEventListener('DOMContentLoaded', () => {
97
100
else {
98
101
fetchActorDetails ( 2037 ) ;
99
102
}
100
-
101
- document . getElementById ( 'clear-search-btn' ) . style . display = 'none' ;
102
103
} ) ;
103
104
104
105
async function fetchActorDetails ( actorId ) {
@@ -151,7 +152,6 @@ async function populateActorDetails(actor, credits) {
151
152
const noImageText = document . createElement ( 'h2' ) ;
152
153
noImageText . textContent = 'Image Not Available' ;
153
154
noImageText . style . textAlign = 'center' ;
154
- noImageText . style . height = '800px' ;
155
155
document . querySelector ( '.actor-left' ) . appendChild ( noImageText ) ;
156
156
}
157
157
@@ -193,19 +193,52 @@ async function populateActorDetails(actor, credits) {
193
193
194
194
const movieList = document . createElement ( 'div' ) ;
195
195
movieList . classList . add ( 'movie-list' ) ;
196
+ movieList . style . display = 'flex' ;
197
+ movieList . style . flexWrap = 'wrap' ;
198
+ movieList . style . justifyContent = 'center' ;
199
+ movieList . style . gap = '5px' ;
200
+
201
+ let filmsToDisplay = credits . cast ;
202
+ filmsToDisplay = filmsToDisplay . sort ( ( a , b ) => b . popularity - a . popularity ) ;
196
203
197
- credits . cast . forEach ( ( movie , index ) => {
198
- const movieLink = document . createElement ( 'span' ) ;
199
- movieLink . textContent = movie . title ;
204
+ filmsToDisplay . forEach ( ( movie , index ) => {
205
+ const movieLink = document . createElement ( 'a' ) ;
200
206
movieLink . classList . add ( 'movie-link' ) ;
201
- movieLink . addEventListener ( 'click' , ( ) => {
202
- localStorage . setItem ( 'selectedMovieId' , movie . id ) ;
203
- window . location . href = 'movie-details.html' ;
204
- } ) ;
207
+ movieLink . href = 'javascript:void(0);' ;
208
+ movieLink . setAttribute ( 'onclick' , `selectMovieId(${ movie . id } );` ) ;
209
+
210
+ const movieItem = document . createElement ( 'div' ) ;
211
+ movieItem . classList . add ( 'movie-item' ) ;
212
+
213
+ const movieImage = document . createElement ( 'img' ) ;
214
+ movieImage . classList . add ( 'movie-image' ) ;
215
+
216
+ if ( movie . poster_path ) {
217
+ movieImage . src = IMGPATH2 + movie . poster_path ;
218
+ movieImage . alt = `${ movie . title } Poster` ;
219
+ } else {
220
+ movieImage . alt = 'Image Not Available' ;
221
+ movieImage . src = 'https://movie-verse.com/images/movie-default.jpg' ;
222
+ movieImage . style . filter = 'grayscale(100%)' ;
223
+ movieImage . style . objectFit = 'cover' ;
224
+ }
225
+
226
+ movieItem . appendChild ( movieImage ) ;
227
+
228
+ const movieDetails = document . createElement ( 'div' ) ;
229
+ movieDetails . classList . add ( 'movie-details' ) ;
230
+
231
+ const movieTitle = document . createElement ( 'p' ) ;
232
+ movieTitle . classList . add ( 'movie-title' ) ;
233
+ movieTitle . textContent = movie . title ;
234
+ movieDetails . appendChild ( movieTitle ) ;
235
+
236
+ movieItem . appendChild ( movieDetails ) ;
237
+ movieLink . appendChild ( movieItem ) ;
205
238
movieList . appendChild ( movieLink ) ;
206
239
207
240
if ( index < credits . cast . length - 1 ) {
208
- movieList . appendChild ( document . createTextNode ( ', ' ) ) ;
241
+ movieList . appendChild ( document . createTextNode ( '' ) ) ;
209
242
}
210
243
} ) ;
211
244
@@ -252,6 +285,20 @@ async function populateActorDetails(actor, credits) {
252
285
detailsContainer . appendChild ( mediaTitle ) ;
253
286
detailsContainer . appendChild ( mediaContainer ) ;
254
287
288
+ let imageWrapper = document . getElementById ( 'image-wrapper' ) ;
289
+ if ( ! imageWrapper ) {
290
+ imageWrapper = document . createElement ( 'div' ) ;
291
+ imageWrapper . id = 'image-wrapper' ;
292
+ imageWrapper . style = `
293
+ position: relative;
294
+ display: flex;
295
+ align-items: center;
296
+ justify-content: center;
297
+ width: 100%;
298
+ ` ;
299
+ mediaContainer . appendChild ( imageWrapper ) ;
300
+ }
301
+
255
302
let imageElement = document . getElementById ( 'series-media-image' ) ;
256
303
if ( ! imageElement ) {
257
304
imageElement = document . createElement ( 'img' ) ;
@@ -264,23 +311,29 @@ async function populateActorDetails(actor, credits) {
264
311
border-radius: 16px;
265
312
cursor: pointer;
266
313
` ;
267
- mediaContainer . appendChild ( imageElement ) ;
314
+ imageElement . loading = 'lazy' ;
315
+ imageWrapper . appendChild ( imageElement ) ;
268
316
}
269
317
270
318
if ( images . length > 0 ) {
271
- imageElement . src = `https://image.tmdb.org/t/p/w1280 ${ images [ 0 ] . file_path } ` ;
319
+ imageElement . src = `https://image.tmdb.org/t/p/w780 ${ images [ 0 ] . file_path } ` ;
272
320
}
273
321
274
- imageElement . addEventListener ( 'click' , function ( ) {
322
+ imageElement . addEventListener ( 'click' , function ( ) {
275
323
const imageUrl = this . src ;
324
+
276
325
const modalHtml = `
277
- <div id="image-modal" style="z-index: 100022222; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.8); display: flex; justify-content: center; align-items: center;">
278
- <img src="${ imageUrl } " style="max-width: 80%; max-height: 80%; border-radius: 10px; cursor: default;" onclick="event.stopPropagation();">
279
- <span style="position: absolute; top: 10px; right: 25px; font-size: 40px; cursor: pointer" id="removeBtn">×</span>
280
- </div>
281
- ` ;
326
+ <div id="image-modal" style="z-index: 100022222; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, 0.8); display: flex; justify-content: center; align-items: center;">
327
+ <button id="prevModalButton" style="position: absolute; left: 20px; top: 50%; transform: translateY(-50%); background-color: #7378c5; color: white; border-radius: 8px; height: 30px; width: 30px; border: none; cursor: pointer; z-index: 11;"><i class="fas fa-arrow-left"></i></button>
328
+ <img src="${ imageUrl } " style="max-width: 80%; max-height: 80%; border-radius: 10px; cursor: default; transition: opacity 0.5s ease-in-out;" onclick="event.stopPropagation();" alt="Media Image"/>
329
+ <button id="nextModalButton" style="position: absolute; right: 20px; top: 50%; transform: translateY(-50%); background-color: #7378c5; color: white; border-radius: 8px; height: 30px; width: 30px; border: none; cursor: pointer; z-index: 11;"><i class="fas fa-arrow-right"></i></button>
330
+ <span style="position: absolute; top: 10px; right: 25px; font-size: 40px; cursor: pointer" id="removeBtn">×</span>
331
+ </div>
332
+ ` ;
282
333
document . body . insertAdjacentHTML ( 'beforeend' , modalHtml ) ;
334
+
283
335
const modal = document . getElementById ( 'image-modal' ) ;
336
+ const modalImage = modal . querySelector ( 'img' ) ;
284
337
const closeModalBtn = document . getElementById ( 'removeBtn' ) ;
285
338
286
339
closeModalBtn . onclick = function ( ) {
@@ -292,8 +345,34 @@ async function populateActorDetails(actor, credits) {
292
345
this . remove ( ) ;
293
346
}
294
347
} ) ;
348
+
349
+ const prevModalButton = document . getElementById ( 'prevModalButton' ) ;
350
+ prevModalButton . onmouseover = ( ) => prevModalButton . style . backgroundColor = '#ff8623' ;
351
+ prevModalButton . onmouseout = ( ) => prevModalButton . style . backgroundColor = '#7378c5' ;
352
+ prevModalButton . onclick = ( ) => navigateMediaAndModal ( images , imageElement , modalImage , - 1 ) ;
353
+
354
+ const nextModalButton = document . getElementById ( 'nextModalButton' ) ;
355
+ nextModalButton . onmouseover = ( ) => nextModalButton . style . backgroundColor = '#ff8623' ;
356
+ nextModalButton . onmouseout = ( ) => nextModalButton . style . backgroundColor = '#7378c5' ;
357
+ nextModalButton . onclick = ( ) => navigateMediaAndModal ( images , imageElement , modalImage , 1 ) ;
295
358
} ) ;
296
359
360
+ function navigateMediaAndModal ( images , imgElement1 , imgElement2 , direction ) {
361
+ imgElement1 . style . opacity = '0' ;
362
+ imgElement2 . style . opacity = '0' ;
363
+ currentIndex = ( currentIndex + direction + images . length ) % images . length ;
364
+
365
+ setTimeout ( ( ) => {
366
+ imgElement1 . src = `https://image.tmdb.org/t/p/w780${ images [ currentIndex ] . file_path } ` ;
367
+ imgElement2 . src = `https://image.tmdb.org/t/p/w1280${ images [ currentIndex ] . file_path } ` ;
368
+ imgElement1 . style . opacity = '1' ;
369
+ imgElement2 . style . opacity = '1' ;
370
+ } , 500 ) ;
371
+
372
+ sessionStorage . setItem ( 'currentIndex' , currentIndex ) ;
373
+ updateDots ( currentIndex ) ;
374
+ }
375
+
297
376
let prevButton = document . getElementById ( 'prev-media-button' ) ;
298
377
let nextButton = document . getElementById ( 'next-media-button' ) ;
299
378
if ( ! prevButton || ! nextButton ) {
@@ -324,26 +403,74 @@ async function populateActorDetails(actor, credits) {
324
403
prevButton . style . left = '0' ;
325
404
nextButton . style . right = '0' ;
326
405
327
- mediaContainer . appendChild ( prevButton ) ;
328
- mediaContainer . appendChild ( nextButton ) ;
406
+ imageWrapper . appendChild ( prevButton ) ;
407
+ imageWrapper . appendChild ( nextButton ) ;
329
408
}
330
409
331
- let currentIndex = 0 ;
332
410
prevButton . onclick = ( ) => navigateMedia ( images , imageElement , - 1 ) ;
333
411
nextButton . onclick = ( ) => navigateMedia ( images , imageElement , 1 ) ;
334
412
335
413
function navigateMedia ( images , imgElement , direction ) {
336
- currentIndex += direction ;
337
- if ( currentIndex < 0 ) {
338
- currentIndex = images . length - 1 ;
339
- } else if ( currentIndex >= images . length ) {
340
- currentIndex = 0 ;
341
- }
342
414
imgElement . style . opacity = '0' ;
415
+ currentIndex = ( currentIndex + direction + images . length ) % images . length ;
343
416
setTimeout ( ( ) => {
344
- imgElement . src = `https://image.tmdb.org/t/p/w1280 ${ images [ currentIndex ] . file_path } ` ;
417
+ imgElement . src = `https://image.tmdb.org/t/p/w780 ${ images [ currentIndex ] . file_path } ` ;
345
418
imgElement . style . opacity = '1' ;
346
- } , 420 ) ;
419
+ } , 500 ) ;
420
+
421
+ sessionStorage . setItem ( 'currentIndex' , currentIndex ) ;
422
+ updateDots ( currentIndex ) ;
423
+ }
424
+
425
+ const indicatorContainer = document . createElement ( 'div' ) ;
426
+ indicatorContainer . style = `
427
+ display: flex;
428
+ flex-wrap: wrap;
429
+ justify-content: center;
430
+ margin-top: 15px;
431
+ ` ;
432
+
433
+ const maxDotsPerLine = 10 ;
434
+ let currentLine = document . createElement ( 'div' ) ;
435
+ currentLine . style . display = 'flex' ;
436
+
437
+ images . forEach ( ( _ , index ) => {
438
+ const dot = document . createElement ( 'div' ) ;
439
+ dot . className = 'indicator' ;
440
+ dot . style = `
441
+ width: 8px;
442
+ height: 8px;
443
+ margin: 0 5px;
444
+ background-color: ${ index === currentIndex ? '#ff8623' : '#bbb' } ;
445
+ border-radius: 50%;
446
+ cursor: pointer;
447
+ margin-bottom: 5px;
448
+ ` ;
449
+ dot . addEventListener ( 'click' , ( ) => {
450
+ navigateMedia ( images , imageElement , index - currentIndex ) ;
451
+ updateDots ( index ) ;
452
+ } ) ;
453
+
454
+ currentLine . appendChild ( dot ) ;
455
+
456
+ if ( ( index + 1 ) % maxDotsPerLine === 0 && index !== images . length - 1 ) {
457
+ indicatorContainer . appendChild ( currentLine ) ;
458
+ currentLine = document . createElement ( 'div' ) ;
459
+ currentLine . style . display = 'flex' ;
460
+ }
461
+ } ) ;
462
+
463
+ if ( currentLine . children . length > 0 ) {
464
+ indicatorContainer . appendChild ( currentLine ) ;
465
+ }
466
+
467
+ mediaContainer . appendChild ( indicatorContainer ) ;
468
+
469
+ function updateDots ( newIndex ) {
470
+ const dots = document . querySelectorAll ( '.indicator' ) ;
471
+ dots . forEach ( ( dot , index ) => {
472
+ dot . style . backgroundColor = index === newIndex ? '#ff8623' : '#bbb' ;
473
+ } ) ;
347
474
}
348
475
349
476
if ( window . innerWidth <= 767 ) {
@@ -357,6 +484,11 @@ async function populateActorDetails(actor, credits) {
357
484
applySettings ( ) ;
358
485
}
359
486
487
+ function selectMovieId ( movieId ) {
488
+ localStorage . setItem ( 'selectedMovieId' , movieId ) ;
489
+ window . location . href = 'movie-details.html' ;
490
+ }
491
+
360
492
function calculateAge ( birthday , deathday = null ) {
361
493
const birthDate = new Date ( birthday ) ;
362
494
const referenceDate = deathday ? new Date ( deathday ) : new Date ( ) ;
@@ -493,6 +625,7 @@ async function rotateUserStats() {
493
625
clearInterval ( statRotationInterval ) ;
494
626
updateStatDisplay ( ) ;
495
627
statRotationInterval = setInterval ( updateStatDisplay , 3000 ) ;
628
+ localTimeDiv . scrollIntoView ( { behavior : 'smooth' } ) ;
496
629
} ) ;
497
630
}
498
631
0 commit comments