├── images
└── logo.png
├── screenshots
├── favicon.png
├── filter.png
├── homepage.png
└── search.png
├── Readme.md
├── index.html
├── style.css
└── script_main.js
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lazyjinchuriki/cinephile/HEAD/images/logo.png
--------------------------------------------------------------------------------
/screenshots/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lazyjinchuriki/cinephile/HEAD/screenshots/favicon.png
--------------------------------------------------------------------------------
/screenshots/filter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lazyjinchuriki/cinephile/HEAD/screenshots/filter.png
--------------------------------------------------------------------------------
/screenshots/homepage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lazyjinchuriki/cinephile/HEAD/screenshots/homepage.png
--------------------------------------------------------------------------------
/screenshots/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lazyjinchuriki/cinephile/HEAD/screenshots/search.png
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | # Cinephile
2 | [](https://lazyjinchuriki.github.io/cinephile/)
3 |
4 | Cinephile is a `Movies` and `TvShows` finder website that allows you to get an overview and trailer of popular movies and shows. You can even search for your favourite Movies and Shows and get an overview and trailer for them.
5 |
6 | The website is built with basic HTML, CSS, and vanilla JavaScript, and uses `TMDB API` to fetch data on movies and TV shows.
7 |
8 | ## Tech Stacks
9 |
10 |   
11 |
12 | ## Features
13 |
14 | Cinephile offers the following features:
15 |
16 | - Search for movies and TV shows
17 | - Get an overview and trailer for movies and TV shows
18 | - View popular movies and TV shows
19 | - View top-rated movies and TV shows
20 | - View upcoming movies
21 | - Filter out movies and shows based on genres
22 | - Go to next and previous page
23 |
24 | ## Installation
25 |
26 | To install Cinephile, follow these steps:
27 |
28 | 1. Download the source code from the repository: https://github.com/lazyjinchuriki/cinephile
29 | 2. Extract the files from the downloaded ZIP archive.
30 | 3. Open the `index.html` file in your web browser.
31 |
32 | ## Usage
33 |
34 | Once you have installed Cinephile, you can use it by opening `index.html` in your web browser.
35 |
36 | ## Screenshots
37 |
38 | Here are some screenshots of Cinephile in action:
39 |
40 | 
41 | 
42 | 
43 |
44 | ## Credits
45 |
46 | Cinephile uses the following open source libraries:
47 |
48 | - TMDB API: https://www.themoviedb.org/documentation/api
49 |
50 | ## Contributing
51 |
52 | Contributions to Cinephile are always welcome. If you find any bugs or issues, please open an issue on GitHub or submit a pull request.
53 |
54 | ## Contact
55 |
56 | If you have any questions or concerns, you can contact the author of this project at [rahulkhushalani@proton.me](mailto:rahulkhushalani@proton.me).
57 |
58 | ### Donations
59 |
60 | If you found Gallery useful, consider buying me a coffee!
61 |
62 |
63 |
64 |
65 |
66 | ## Social
67 |
68 | If you're not coding right now, check out my socials:
69 |
70 | [](https://www.instagram.com/amundaneguy/)
71 | [](https://www.linkedin.com/in/rahul-khushalani-77ab21201/)
72 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Movie&TV App
9 |
10 |
11 |
12 |
13 |
54 |
55 |
56 |
93 |
94 |
95 |
101 |
102 |
103 |
104 |
105 |
106 |
111 |
112 |
113 |
119 |
120 |
128 |
132 |
136 |
137 |
138 |
139 |
202 |
203 |
204 |
205 |
206 |
207 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@200;400&display=swap');
2 |
3 | :root {
4 | --primary-color: #22254b;
5 | --secondary-color: #373b69;
6 | }
7 |
8 | * {
9 | box-sizing: border-box;
10 | }
11 |
12 | html{
13 | scroll-behavior: smooth;
14 | }
15 |
16 | body {
17 | background-color: var(--primary-color);
18 | font-family: 'Poppins', sans-serif;
19 | margin: 0;
20 | }
21 |
22 | body::-webkit-scrollbar {
23 | width: 12px;
24 | }
25 |
26 | body::-webkit-scrollbar-thumb {
27 | height: 40px;
28 | background-color: #7378c5;
29 | border-radius: 10px;
30 | }
31 |
32 | body::-webkit-scrollbar-thumb:hover {
33 | background: #4d5293;
34 | }
35 |
36 | body::-webkit-scrollbar-track {
37 | box-shadow: inset 2px 2px 5px #2d2d2d;
38 | background-color: #eeeeee;
39 | }
40 |
41 | header {
42 | justify-content: space-between;
43 | padding: 1rem;
44 | display: flex;
45 | background-color: var(--secondary-color);
46 | }
47 |
48 | middle{
49 | padding: 1rem;
50 | display: flex;
51 | justify-content: center;
52 | }
53 | .pageChange:hover{
54 | cursor: pointer;
55 | }
56 | .switch {
57 | width: 50px;
58 | height: 50px;
59 | position: relative;
60 | border: 2px solid var(--primary-color);
61 | border-radius: 50%;
62 | font-family: inherit;
63 | padding: 0.5rem 0.5rem;
64 | outline: none;
65 | margin-right: 5%;
66 | }
67 | .switch:hover{
68 | background-color: var(--primary-color);
69 | }
70 |
71 | /* for heading */
72 | .animate-charcter
73 | {
74 | text-transform: uppercase;
75 | background-image: linear-gradient(
76 | -225deg,
77 | #231557 0%,
78 | #44107a 29%,
79 | #ff1361 67%,
80 | #fff800 100%
81 | );
82 | background-size: auto auto;
83 | background-clip: border-box;
84 | background-size: 200% auto;
85 | color: #fff;
86 | background-clip: text;
87 | text-fill-color: transparent;
88 | -webkit-background-clip: text;
89 | -webkit-text-fill-color: transparent;
90 | animation: textclip 2s linear infinite;
91 | display: inline-block;
92 | font-size: 20px;
93 | }
94 |
95 | @keyframes textclip {
96 | to {
97 | background-position: 200% center;
98 | }
99 | }
100 | /* this is for flex container */
101 | .flex-container {
102 | display: flex;
103 | align-items: center;
104 | justify-content: center;
105 | }
106 | .flex-container img {
107 | margin-left: 10px;
108 | }
109 |
110 | .search {
111 | width: 90%;
112 | position: relative;
113 | right: 4%;
114 | background-color: transparent;
115 | border: 2px solid var(--primary-color);
116 | border-radius: 45px;
117 | font-family: inherit;
118 | font-size: 1rem;
119 | padding: 0.5rem 1rem;
120 | color: #fff;
121 | margin-left: 5%;
122 | }
123 |
124 | .search::placeholder {
125 | color: #7378c5;
126 | }
127 |
128 | .search:focus {
129 | outline: none;
130 | background-color: var(--primary-color);
131 | }
132 |
133 | /*For any screens at or below 244px.*/
134 | @media only screen and (max-width: 244px) {
135 | .search {
136 | width: 23vw;
137 | margin-top: 20px;
138 | }
139 | .flex-container {
140 | flex-direction: column;
141 | align-items: center;
142 | margin-top: -20px;
143 | }
144 | }
145 |
146 | /* For any screens between 245px and 309px. */
147 | @media only screen and (min-width: 245px) and (max-width: 309px) {
148 | .search {
149 | width: 30vw;
150 | margin-top: 20px;
151 | }
152 | .flex-container {
153 | flex-direction: column;
154 | align-items: center;
155 | margin-top: -20px;
156 | }
157 | }
158 |
159 | /*For any screens between 310px and 380px. Devices such as iPhone SE*/
160 | @media only screen and (min-width: 310px) and (max-width: 380px) {
161 | .search {
162 | width: 35vw;
163 | margin-top: 20px;
164 | }
165 | .flex-container {
166 | flex-direction: column;
167 | align-items: center;
168 | margin-top: -20px;
169 | }
170 | .flex-container img {
171 | margin-top: -20px;
172 | }
173 | }
174 | /*For any screens between 310px and 380px. Devices such as iPhone SE*/
175 | @media only screen and (min-width: 380px) and (max-width: 500px) {
176 | .search {
177 | width: 36vw;
178 | margin-top: 20px;
179 | }
180 | .flex-container {
181 | flex-direction: column;
182 | align-items: center;
183 | margin-top: -20px;
184 | }
185 | .flex-container img {
186 | margin-top: -20px;
187 | }
188 | }
189 |
190 | /*For any screens between 500px and 599px. Devices such as Pixel 5 and Surface Duo.*/
191 | @media only screen and (min-width: 500px) and (max-width: 599px) {
192 | .search {
193 | width: 50vw;
194 | margin-top: 20px;
195 | }
196 | .flex-container {
197 | flex-direction: column;
198 | align-items: center;
199 | margin-top: -20px;
200 | }
201 | .flex-container img {
202 | margin-top: -20px;
203 | }
204 | }
205 |
206 | /*For any screens at or above 600px. Enlarges search box to fit laptops, desktops, and TVs.*/
207 | @media only screen and (min-width: 600px) {
208 | .search {
209 | width: 60vw; /*View Width to expand based on user's device width*/
210 | }
211 |
212 | }
213 | @media only screen and (min-width: 900) {
214 | .search {
215 | width: 70vw; /*View Width to expand based on user's device width*/
216 | }
217 | }
218 |
219 | main {
220 | display: flex;
221 | flex-wrap: wrap;
222 | justify-content: center;
223 | }
224 |
225 | .movie, .tvshow {
226 | width: 300px;
227 | margin: 1rem;
228 | background-color: var(--secondary-color);
229 | box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2);
230 | position: relative;
231 | overflow: hidden;
232 | border-radius: 3px;
233 |
234 | }
235 | .movie:hover, .tvshow:hover{
236 | cursor: pointer;
237 | box-shadow: 0 8px 18px rgba(255, 255, 255, 0.5), 0 0 32px rgba(0, 0, 0, 0.3);
238 | transform: translateY(-20px);
239 | z-index: 2;
240 | transition: all 0.4s ease-in-out;
241 | }
242 |
243 | .tvshow {
244 | width: 300px;
245 | margin: 1rem;
246 | background-color: var(--secondary-color);
247 | box-shadow: 0 4px 5px rgba(0, 0, 0, 0.2);
248 | position: relative;
249 | overflow: hidden;
250 | border-radius: 3px;
251 | }
252 |
253 |
254 | .movie img {
255 | width: 100%;
256 | transition: all 0.3s ease-in;
257 | }
258 |
259 | .tvshow img {
260 | width: 100%;
261 | transition: all 0.3s ease-in;
262 | }
263 |
264 | .movie-info {
265 | color: #eee;
266 | display: flex;
267 | align-items: center;
268 | justify-content: space-between;
269 | gap:0.2rem;
270 | padding: 0.5rem 1rem 1rem;
271 | letter-spacing: 0.5px;
272 | }
273 |
274 | .movie-info h3 {
275 | margin-top: 0;
276 | }
277 |
278 | .movie-info span {
279 | background-color: var(--primary-color);
280 | padding: 0.25rem 0.5rem;
281 | border-radius: 3px;
282 | font-weight: bold;
283 | }
284 |
285 | .movie-info span.green {
286 | color: lightgreen;
287 | }
288 |
289 | .movie-info span.orange {
290 | color: orange;
291 | }
292 |
293 | .movie-info span.red {
294 | color: red;
295 | }
296 |
297 | .releaseDate{
298 | position: absolute;
299 | top: 4px;
300 | left: 4px;
301 | color: white;
302 | font-weight: bold;
303 | font-family: inherit;
304 | padding: 0.25rem 0.5rem;
305 | background-color: rgba(0, 0, 0, 0.63);
306 | border-radius: 3px;
307 | z-index: 0.9;
308 | }
309 |
310 | .overview {
311 | background-color: #fff;
312 | padding: 2rem;
313 | position: absolute;
314 | left: 0;
315 | bottom: 0;
316 | right: 0;
317 | max-height: 100%;
318 | transform: translateY(101%);
319 | overflow-y: auto;
320 | transition: transform 0.7s ease-in;
321 | }
322 | .overview::-webkit-scrollbar{
323 | display: none;
324 | }
325 |
326 | .overview .overview-content {
327 | overflow: hidden;
328 | display: -webkit-box;
329 | -webkit-line-clamp: 10;
330 | line-clamp: 10;
331 | -webkit-box-orient: vertical;
332 | }
333 |
334 | .movie:hover img, .tvshow:hover img {
335 | filter: brightness(0.5);
336 | }
337 |
338 | .movie:hover .overview {
339 | transform: translateY(0);
340 | }
341 |
342 | .tvshow:hover .overview {
343 | transform: translateY(0);
344 | }
345 |
346 |
347 |
348 |
349 | .pagination{
350 | display: flex;
351 | justify-content: center;
352 | margin: 10px 20px;
353 | align-items: center;
354 | color: white;
355 |
356 | }
357 |
358 | .page{
359 | padding: 10px;
360 | cursor: pointer;
361 | font-family: inherit;
362 | font-size: 1rem;
363 | }
364 | .page:hover{
365 | background-color: var(--secondary-color);
366 | border-radius: 20px;
367 | }
368 |
369 | .disabled{
370 | cursor: not-allowed;
371 | color: grey;
372 | }
373 |
374 | .knowmore{
375 | color: white;
376 | font-weight: bold;
377 | font-size: 14px;
378 | background-color: var(--secondary-color);
379 | border-radius: 50px;
380 | border: none;
381 | margin: 5px;
382 | padding: 15px 20px;
383 | display: inline-block;
384 | cursor: pointer;
385 | }
386 |
387 | .knowmore:hover{
388 | background-color: var(--primary-color);
389 | }
390 |
391 | /* The Overlay (background) */
392 | .overlay {
393 | /* Height & width depends on how you want to reveal the overlay (see JS below) */
394 | height: 100%;
395 | width: 0;
396 | position: fixed; /* Stay in place */
397 | z-index: 1; /* Sit on top */
398 | left: 0;
399 | top: 0;
400 | background-color: rgb(0,0,0); /* Black fallback color */
401 | background-color: rgba(0,0,0, 0.9); /* Black w/opacity */
402 | overflow-x: hidden; /* Disable horizontal scroll */
403 | transition: 0.5s; /* 0.5 second transition effect to slide in or slide down the overlay (height or width, depending on reveal) */
404 | }
405 |
406 | /* Position the content inside the overlay */
407 | .overlay-content {
408 | position: relative;
409 | top: 15%; /* 25% from the top */
410 | width: auto !important; /* 100% width */
411 | height: auto !important;
412 | text-align: center; /* Centered text/links */
413 | max-width: 1080px;
414 | margin: 0 auto; /* centered the wraper */
415 | margin-top: 30px; /* 30px top margin to avoid conflict with the close button on smaller screens */
416 | }
417 |
418 | /* The navigation links inside the overlay */
419 | .overlay a {
420 | padding: 8px;
421 | text-decoration: none;
422 | font-size: 36px;
423 | color: #818181;
424 | display: block; /* Display block instead of inline */
425 | transition: 0.3s; /* Transition effects on hover (color) */
426 | }
427 |
428 | /* When you mouse over the navigation links, change their color */
429 | .overlay a:hover, .overlay a:focus {
430 | color: #f1f1f1;
431 | }
432 |
433 | /* Position the close button (top right corner) */
434 | .overlay .closebtn {
435 | position: absolute;
436 | top: 20px;
437 | right: 45px;
438 | font-size: 60px;
439 | }
440 |
441 | /* When the height of the screen is less than 450 pixels, change the font-size of the links and position the close button again, so they don't overlap */
442 | @media screen and (max-height: 450px) {
443 | .overlay a {font-size: 20px}
444 | .overlay .closebtn {
445 | font-size: 40px;
446 | top: 15px;
447 | right: 35px;
448 | }
449 | }
450 |
451 |
452 | .embed.hide{
453 | display: none;
454 | }
455 |
456 | .embed.show{
457 | display: inline-block;
458 | }
459 |
460 | .video-container {
461 | position: relative;
462 | padding-bottom: 56.25%; /* 16:9 */
463 | height: 0;
464 | }
465 | .video-container iframe {
466 | position: absolute;
467 | top: 0;
468 | left: 0;
469 | width: 100%;
470 | height: 100%;
471 | }
472 |
473 | .scrollable-tabs-container:hover{
474 | cursor: pointer;
475 | }
476 |
477 |
478 |
479 |
480 |
481 |
482 | .scrollable-tabs-container{
483 | max-width: 100%;
484 | margin: 16px auto;
485 | border-radius: 5px;
486 | overflow: hidden;
487 | position: relative;
488 |
489 | }
490 |
491 | .scrollable-tabs-container svg{
492 | width: 40px;
493 | height: 40px;
494 | padding: 8px;
495 | cursor: pointer;
496 | color: white;
497 | border-radius: 50%;
498 | pointer-events: auto;
499 |
500 | }
501 |
502 | #tags{
503 | display: flex;
504 | gap: 16px;
505 | padding: 12px 24px;
506 | margin: 0;
507 | list-style: none;
508 | overflow-x: scroll;
509 | -ms-overflow-style: none;
510 | scrollbar-width: none;
511 | scroll-behavior: smooth;
512 | }
513 | /* Genres - Animation on hover */
514 | #tags div{
515 | transition: 0.3s all;
516 | }
517 |
518 | #tags div:hover{
519 | background-color: white;
520 | color: #231557;
521 | transform: scale(1.1);
522 | transition: 0.3s all;
523 | }
524 |
525 | #tags.dragging{
526 | scroll-behavior: auto;
527 | }
528 | /* .scrollable-tabs-container ul.dragging a{
529 | pointer-events: none;
530 | } */
531 |
532 | #tags::-webkit-scrollbar{
533 | display: none;
534 | }
535 |
536 | .scrollable-tabs-container .tag {
537 | color: white;
538 | text-decoration: none;
539 | background: var(--secondary-color);
540 | padding: 4px 24px;
541 | display: inline-block;
542 | border-radius: 4px;
543 | user-select: none;
544 | white-space: nowrap;
545 | cursor: pointer;
546 | }
547 |
548 | .scrollable-tabs-container .tag.active{
549 | background-color: rgba(255, 255, 255, 0.508);
550 | font-weight: bold;
551 | color: rgba(0, 0, 0, 0.757);
552 | }
553 |
554 | .scrollable-tabs-container .right-arrow,
555 | .scrollable-tabs-container .left-arrow{
556 | position: absolute;
557 | height: 100%;
558 | width: 100px;
559 | top: 0;
560 | display: none;
561 | align-items: center;
562 | padding: 0 10px;
563 | pointer-events: none;
564 |
565 | }
566 | .scrollable-tabs-container .right-arrow.active,
567 | .scrollable-tabs-container .left-arrow.active{
568 | display: flex;
569 | }
570 |
571 | .scrollable-tabs-container .right-arrow{
572 | right: 0;
573 | justify-content: flex-end;
574 | background: linear-gradient(to left, #22254b 50%, transparent);
575 | }
576 |
577 | .scrollable-tabs-container .left-arrow{
578 | background: linear-gradient(to right, #22254b 50%, transparent);
579 | }
580 |
581 |
582 | .scrollable-tabs-container svg:hover{
583 | background: var(--secondary-color);
584 | }
585 |
586 | /* Reset some default styles */
587 | body {
588 | margin: 0;
589 | padding: 0;
590 | }
591 |
592 | /* Footer styles */
593 | .footer {
594 | background-color:#333;
595 | color: #fff;
596 | text-align: center;
597 | padding: 15px 0 15px 0;
598 | }
599 |
600 | .contact-text {
601 | margin:0;
602 | padding-top: 15px;
603 | font-size: 10px 15px;
604 | color: rgba(255, 255, 255, 0.5);
605 | text-align: center;
606 | margin: 0;
607 | }
608 |
609 | .copy{
610 | margin:0;
611 | padding-top: 15px;
612 | font-size: 10px 15px;
613 | color: rgba(255, 255, 255, 0.5);
614 | }
615 |
616 | .footer-content {
617 | justify-content: center;
618 | align-items: center;
619 | gap: 20px;
620 | }
621 |
622 | .icon {
623 | margin: 0;
624 | padding: 10px;
625 | }
626 |
627 | .icon:hover {
628 | transform: scale(1.1);
629 | }
630 |
631 | svg {
632 | color: #fff;
633 | cursor: pointer;
634 | width: 30px;
635 | height: 30px;
636 | transition: transform 0.3s ease-in-out;
637 | }
638 |
639 | .all{
640 | margin-top: 10px;
641 | align-items: center;
642 | }
643 |
644 | .social-top {
645 | margin: 0 auto;
646 | width: 90%;
647 | justify-content: space-between;
648 | align-items: center;
649 | }
650 |
651 | .social p {
652 | font-size: 20px;
653 | padding: 10px;
654 | }
655 |
656 | .social {
657 | justify-items: center;
658 | align-items: center;
659 | }
660 |
661 | .social a svg {
662 | text-decoration: none;
663 | }
664 |
665 | #topBtn p {
666 | font-size: 20px;
667 | padding: 10px 15px;
668 | cursor: pointer;
669 | }
670 |
671 | #topBtn {
672 | margin:0;
673 | display: flex;
674 | justify-items: center;
675 | align-items: center;
676 | background: none;
677 | border: none;
678 | border-radius: 100%;
679 | background-color: rgba(255, 255, 255, 0.5);
680 | padding: 5px;
681 | cursor: pointer;
682 | position: fixed;
683 | right: 2.5rem;
684 | bottom: 2rem;
685 | transition: all;
686 | transition-duration: 300ms;
687 | }
688 |
689 | .top-icon{
690 | margin: 0;
691 | padding: 0;
692 | }
693 |
694 | .top-icon svg{
695 | color: #373b69;
696 | }
697 |
698 | .top-icon:hover {
699 | transform: scale(1.1);
700 | transition: all;
701 | transition-duration: 300ms;
702 | }
703 |
704 | hr {
705 | border-color: rgba(255, 255, 255, 0.5);
706 | width: 90%;
707 | margin-left: auto;
708 | margin-right: auto;
709 | display: table;
710 | }
711 | .switch:hover + .page-name {
712 | opacity: 1;
713 | transform: translateX(10px);
714 | transition: opacity 0.3s ease, transform 0.3s ease;
715 | }
716 |
717 | .page-name {
718 | opacity: 0;
719 | transition: opacity 0.3s ease, transform 0.3s ease;
720 | margin-left: 10px;
721 | display: inline-block;
722 | color: white;
723 | }
724 |
725 | .switch-button-container {
726 | display: justify-content;
727 | flex-direction: column;
728 | align-items: center;
729 | text-align: center;
730 | }
731 |
732 | .logo {
733 | width: 50px;
734 | height: 50px;
735 | transition: transform 0.3s ease-in-out;
736 | }
737 |
738 | .logo:hover {
739 | transform: scale(1.2) rotate(360deg);
740 | }
741 |
742 | .text-effect {
743 | transition: transform 0.3s ease-in-out, color 0.3s ease-in-out;
744 | }
745 |
746 | .text-effect:hover {
747 | transform: scale(1.2);
748 | color: #ff5722;
749 | }
750 |
751 | .icon a:hover svg path {
752 | fill:#CBD5E1;
753 | }
754 |
755 |
--------------------------------------------------------------------------------
/script_main.js:
--------------------------------------------------------------------------------
1 | //All the url used to fetch movies and tvshows from TMDB api.
2 | const API_key = 'api_key=4b153b123319df27bb67fcbfe219537d';
3 | const BASE_url = 'https://api.themoviedb.org/3';
4 | const API_url = BASE_url + '/discover/movie?sort_by=popularity.desc&' + API_key;
5 | const IMG_url = 'https://image.tmdb.org/t/p/w500'
6 | const SEARCH_url = 'https://api.themoviedb.org/3/search/movie?api_key=4b153b123319df27bb67fcbfe219537d&query='
7 | const TV_url = BASE_url + '/tv/popular?' + API_key + '&vote_count.gte=100';
8 | const TV_Search_url = 'https://api.themoviedb.org/3/search/tv?' + API_key + '&query='
9 |
10 |
11 | //Array of all the genres of movies.
12 | const genres = [
13 | {
14 | "id": 28,
15 | "name": "Action"
16 | },
17 | {
18 | "id": 12,
19 | "name": "Adventure"
20 | },
21 | {
22 | "id": 16,
23 | "name": "Animation"
24 | },
25 | {
26 | "id": 35,
27 | "name": "Comedy"
28 | },
29 | {
30 | "id": 80,
31 | "name": "Crime"
32 | },
33 | {
34 | "id": 99,
35 | "name": "Documentary"
36 | },
37 | {
38 | "id": 18,
39 | "name": "Drama"
40 | },
41 | {
42 | "id": 10751,
43 | "name": "Family"
44 | },
45 | {
46 | "id": 14,
47 | "name": "Fantasy"
48 | },
49 | {
50 | "id": 36,
51 | "name": "History"
52 | },
53 | {
54 | "id": 27,
55 | "name": "Horror"
56 | },
57 | {
58 | "id": 10402,
59 | "name": "Music"
60 | },
61 | {
62 | "id": 9648,
63 | "name": "Mystery"
64 | },
65 | {
66 | "id": 10749,
67 | "name": "Romance"
68 | },
69 | {
70 | "id": 878,
71 | "name": "Science Fiction"
72 | },
73 | {
74 | "id": 10770,
75 | "name": "TV Movie"
76 | },
77 | {
78 | "id": 53,
79 | "name": "Thriller"
80 | },
81 | {
82 | "id": 10752,
83 | "name": "War"
84 | },
85 | {
86 | "id": 37,
87 | "name": "Western"
88 | }
89 | ]
90 |
91 | // run after loading page
92 | window.addEventListener("DOMContentLoaded", (ev)=>{
93 | // console.log("page loaded");
94 | let main = document.querySelector('#main');
95 |
96 | // set the genre categories
97 | setGenres();
98 |
99 | // set arrow movement for categories
100 | const rightArrow = document.querySelector(".scrollable-tabs-container .right-arrow svg");
101 | const leftArrow = document.querySelector(".scrollable-tabs-container .left-arrow svg");
102 | const tagsEl = document.getElementById('tags');
103 |
104 | rightArrow.addEventListener("click", ()=>{
105 | tagsEl.scrollLeft += 500;
106 | manageIcons();
107 | });
108 | leftArrow.addEventListener("click", ()=>{
109 | tagsEl.scrollLeft -= 500;
110 | manageIcons();
111 | });
112 |
113 |
114 | let onPage=null;
115 | let whichPage = localStorage.getItem('page');
116 | if(whichPage == null){
117 | localStorage.setItem("page", "movie");
118 | onPage = "movie";
119 | }
120 | else{
121 | onPage = whichPage;
122 | }
123 |
124 |
125 | // change page variable from localstorage
126 | let pgChange = document.querySelector('.pageChange');
127 | pgChange.addEventListener('click', ()=>{
128 | let whichPage = localStorage.getItem('page');
129 | if(whichPage == 'movie'){
130 | localStorage.setItem('page', 'tv');
131 | let tv_svg = `
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | `;
142 | pgChange.innerHTML = tv_svg;
143 | LoadDataAndDisplay();
144 | }
145 | else if (whichPage == 'tv'){
146 | localStorage.setItem('page', 'movie');
147 | let movie_svg = `
148 |
149 |
150 |
151 |
152 |
153 | `;
154 | pgChange.innerHTML = movie_svg;
155 | LoadDataAndDisplay();
156 | }
157 | })
158 |
159 | // Load data and display function wrapper which fetches data asynchronously and displays it
160 | LoadDataAndDisplay();
161 |
162 |
163 | const prev = document.getElementById("prev")
164 | const current = document.getElementById("current")
165 | const next = document.getElementById("next")
166 |
167 | prev.addEventListener('click', () =>{
168 | if(prevPage > 0){
169 | pageCall(prevPage);
170 | main.scrollIntoView({behavior : 'smooth'});
171 | }
172 | })
173 |
174 | next.addEventListener('click', () =>{
175 | if(nextPage <= totalPages){
176 | pageCall(nextPage);
177 | main.scrollIntoView({behavior : 'smooth'});
178 | }
179 | })
180 |
181 |
182 | let searchBar = document.querySelector('.search');
183 | searchBar.addEventListener('input', searchStart);
184 |
185 |
186 | let copyRightYear = document.getElementById("copyright-year");
187 | let currentDate = new Date();
188 | let currentYear = currentDate.getFullYear();
189 | copyRightYear.innerText = currentYear;
190 |
191 | })
192 |
193 | function topFunction() {
194 | document.body.scrollTop = 0; // For Safari
195 | document.documentElement.scrollTop = 0; // For Chrome, Firefox, IE and Opera
196 | }
197 |
198 | // set all genres on the page
199 | let selectedGenre=[]
200 | function setGenres(){
201 | let tags_el = document.querySelector('#tags');
202 | // console.log(tags_el);
203 |
204 | genres.forEach(genre =>{
205 | const t = document.createElement('div');
206 | t.classList.add('tag');
207 | t.id = genre.id;
208 | t.innerText = genre.name;
209 |
210 | t.addEventListener('click', () => {
211 | if(selectedGenre.length == 0){
212 | selectedGenre.push(genre.id);
213 | }else{
214 | if(selectedGenre.includes(genre.id)){
215 | selectedGenre.forEach((id, idx) =>{
216 | if(id == genre.id){
217 | selectedGenre.splice(idx, 1);
218 | }
219 | })
220 | }else{
221 | selectedGenre.push(genre.id);
222 | }
223 | }
224 | // console.log(selectedGenre)
225 |
226 | let newurl = API_url + '&with_genres=' + encodeURI(selectedGenre.join(','));
227 | let whichPage = localStorage.getItem('page');
228 | LoadMovieOrTv(whichPage, newurl)
229 | highlightSelection();
230 |
231 | })
232 |
233 | tags_el.append(t);
234 | })
235 | }
236 |
237 | // manange the left and right arrows for genre categories
238 | const manageIcons = ()=>{
239 | const tagsEl = document.getElementById('tags');
240 | const leftArrowContainer = document.querySelector(".scrollable-tabs-container .left-arrow")
241 | const rightArrowContainer = document.querySelector(".scrollable-tabs-container .right-arrow")
242 |
243 | if(tagsEl.scrollLeft >= 20){
244 | leftArrowContainer.classList.add("active")
245 | }else{
246 | leftArrowContainer.classList.remove("active")
247 | }
248 | let maxScrollValue = tagsEl.scrollWidth - tagsEl.clientWidth - 20;
249 | // console.log(tagsEl.scrollWidth);
250 | // console.log(tagsEl.clientWidth);
251 |
252 | if(tagsEl.scrollLeft >= maxScrollValue){
253 | rightArrowContainer.classList.remove("active")
254 |
255 | }else{
256 | rightArrowContainer.classList.add("active");
257 | }
258 | }
259 |
260 | //highlighting the selected genre.
261 | function highlightSelection(){
262 | const tags = document.querySelectorAll('.tag');
263 | tags.forEach(tag =>{
264 | tag.classList.remove('active')
265 | })
266 | //calling clearBtn function which shows a button to clear all the selected genre when clicking.
267 | // clearBtn()
268 | if(selectedGenre.length != 0){
269 | selectedGenre.forEach(id =>{
270 | const highlightedTag = document.getElementById(id);
271 | highlightedTag.classList.add('active');
272 | })
273 | }
274 | }
275 |
276 |
277 | var currentPage = 1;
278 | var nextPage = 2;
279 | var prevPage = 3;
280 | var lastUrl = '';
281 | var totalPages = 100;
282 | // change page number
283 | function pageCall(page){
284 |
285 | let urlSplit = lastUrl.split('?');
286 | let queryParameter = urlSplit[1].split('&');
287 | let key = queryParameter[queryParameter.length - 1].split('=');
288 | if(key[0] != 'page'){
289 | let url = lastUrl + '&page=' + page;
290 | let whichPage = localStorage.getItem('page');
291 | LoadMovieOrTv(whichPage, url);
292 | }
293 | else{
294 | key[1] = page.toString();
295 | let a = key.join('=');
296 | queryParameter[queryParameter.length - 1] = a;
297 | let b = queryParameter.join('&');
298 | let url = urlSplit[0] + '?' + b
299 | let whichPage = localStorage.getItem('page');
300 | LoadMovieOrTv(whichPage, url);
301 | }
302 |
303 | }
304 |
305 | // load and display wrapper
306 | function LoadDataAndDisplay(){
307 | let whichPage = localStorage.getItem('page');
308 | let main = document.querySelector('#main');
309 | main.innerHTML=' ';
310 |
311 | if(whichPage == 'movie'){
312 | LoadMovieOrTv(whichPage, API_url)
313 | }
314 | else if (whichPage == 'tv'){
315 | LoadMovieOrTv(whichPage, TV_url)
316 | }
317 | }
318 |
319 | // Asynchronous function which loads data from API
320 | async function LoadMovieOrTv(whichPage, url){
321 | lastUrl = url;
322 | let main = document.querySelector('#main');
323 | let res = await fetch(url);
324 | let data = await res.json();
325 |
326 | if(data.results.length !== 0){
327 | if(whichPage == 'movie'){
328 | showMovies(data.results);
329 | }
330 | else if (whichPage == 'tv'){
331 | showTvShows(data.results);
332 | }
333 | currentPage = data.page;
334 | nextPage = currentPage + 1;
335 | prevPage = currentPage - 1;
336 | totalPages = data.total_pages;
337 | current.innerText = currentPage;
338 |
339 | if(currentPage <= 1){
340 | prev.classList.add('disabled')
341 | next.classList.remove('disabled')
342 | }
343 | else if(currentPage >= totalPages){
344 | prev.classList.remove('disabled')
345 | next.classList.add('disabled')
346 | }
347 | else{
348 | prev.classList.remove('disabled')
349 | next.classList.remove('disabled')
350 | }
351 |
352 | }
353 | else{
354 | main.innerHTML = `
355 | WOW! SUCH EMPTY 🙂
356 | `
357 | }
358 | }
359 |
360 |
361 | //dynamically loading the movie data in form of Cards consisting of [Title, Poster, Rating, Overview and Release Date].
362 | function showMovies(data){
363 | let main = document.querySelector('#main');
364 |
365 | main.innerHTML=' ';
366 |
367 | data.forEach( movie => {
368 | const {title, poster_path, vote_average, overview, release_date, id} = movie;
369 | const movieEl = document.createElement('div');
370 | movieEl.classList.add('movie');
371 |
372 | movieEl.innerHTML = `
373 |
374 |
${release_date}
375 |
376 |
377 |
378 |
379 |
${title}
380 | ${vote_average}
381 |
382 |
383 |
384 | ${title}
385 |
386 | ${overview}
387 |
388 |
389 | Know More
390 |
391 |
392 | `
393 | main.appendChild(movieEl)
394 |
395 | document.getElementById(id).addEventListener('click', ()=>{
396 | // console.log(id);
397 | openNav(movie);
398 | })
399 | })
400 | }
401 | // display Tv shows
402 | function showTvShows(data){
403 | let main = document.querySelector('#main');
404 | main.innerHTML=' ';
405 |
406 | data.forEach(tvshow => {
407 | const {name,overview,poster_path,vote_average,first_air_date,id} = tvshow;
408 | const tvEl = document.createElement('div');
409 | tvEl.classList.add('tvshow');
410 |
411 | tvEl.innerHTML = `
412 |
413 |
${first_air_date}
414 |
415 |
416 |
417 |
418 |
${name}
419 | ${vote_average}
420 |
421 |
422 |
${name}
423 |
424 | ${overview}
425 |
426 |
427 | Know More
428 |
429 |
430 | `
431 | main.appendChild(tvEl)
432 |
433 | document.getElementById(id).addEventListener('click', ()=>{
434 | console.log(id);
435 | openNav(tvshow);
436 | })
437 | })
438 | }
439 | //change the class of vote_average based on the rating to show different colors for different ratings.
440 | function getColor(vote){
441 | if(vote >= 7){
442 | return 'green'
443 | }
444 | else if(vote >= 5){
445 | return 'orange'
446 | }
447 | else{
448 | return 'red'
449 | }
450 | }
451 |
452 | // search functionality for searching the results
453 | function searchResultsAndDisplayWrapper(ev){
454 | let whichPage = localStorage.getItem('page');
455 |
456 | if(ev.target.value == ''){
457 | // when the search field is empty for TV or Movie
458 | if(whichPage == 'movie'){
459 | LoadMovieOrTv(whichPage, API_url);
460 | }
461 | else if (whichPage == 'tv'){
462 | LoadMovieOrTv(whichPage, TV_url);
463 |
464 | }
465 | }
466 | else{
467 | // when the search field is NOT empty for TV or Movie
468 | if(whichPage == 'movie'){
469 | let url_search = SEARCH_url + ev.target.value;
470 | LoadMovieOrTv(whichPage, url_search);
471 | }
472 | else if (whichPage == 'tv'){
473 | let url_search = TV_Search_url + ev.target.value;
474 | LoadMovieOrTv(whichPage, url_search);
475 | }
476 |
477 | }
478 | }
479 | function searchAndDisplay(func, delay){
480 | let timer;
481 |
482 | return function (){
483 | let context = this,
484 | arg = arguments;
485 |
486 | clearTimeout(timer);
487 |
488 | timer = setTimeout(()=>{
489 | func.apply(context, arguments);
490 |
491 | }, delay)
492 | }
493 | }
494 | const searchStart = searchAndDisplay(searchResultsAndDisplayWrapper, 900);
495 |
496 |
497 |
498 | function showVideos(){
499 | let embedClass = document.querySelectorAll('.embed');
500 | embedClass.forEach((embedTag, idx)=>{
501 | if(activeSlide == idx){
502 | embedTag.classList.add('show');
503 | embedTag.classList.remove('hide');
504 | }else{
505 | embedTag.classList.add('hide');
506 | embedTag.classList.remove('show');
507 | }
508 | })
509 | }
510 |
511 | /* Open when someone clicks on the span element */
512 | function openNav(tvOrMovie) {
513 | let id=tvOrMovie.id;
514 | let whichPage = localStorage.getItem('page');
515 | let _url;
516 | if (whichPage == 'movie'){
517 | _url = BASE_url+ '/movie/'+ id + '/videos?' + API_key;
518 | }
519 | else if (whichPage == 'tv'){
520 | _url = BASE_url+ '/tv/'+ id + '/videos?' + API_key;
521 | }
522 | getVideo(_url);
523 | }
524 |
525 | async function getVideo(url){
526 | const overlayContent = document.getElementById('overlay-content');
527 |
528 | let res = await fetch(url);
529 | let videoData = await res.json();
530 |
531 | if(videoData){
532 | console.log(videoData);
533 | document.getElementById("myNav").style.width = "100%";
534 | if(videoData.results.length > 0){
535 | var embed = [];
536 | videoData.results.forEach(video => {
537 | let{name,key,site,type} = video;
538 |
539 | if(site == 'YouTube' && type == 'Trailer'){
540 | embed.push(`
541 |
542 | VIDEO
543 | `)
544 | }
545 | })
546 |
547 | overlayContent.innerHTML = embed.join('');
548 | activeSlide=0;
549 | showVideos();
550 | }
551 | else{
552 | overlayContent.innerHTML = `
553 | WOW! SUCH EMPTY 🙂 `
554 | }
555 | }
556 | }
557 |
558 | function closeNav() {
559 | const overlay = document.getElementById("myNav");
560 | overlay.style.width = "0%";
561 | const embedClass = document.querySelectorAll('.embed');
562 | embedClass.forEach(embedTag => {
563 | embedTag.src = '';
564 | embedTag.parentNode.removeChild(embedTag);
565 | });
566 | activeSlide = 0;
567 | }
568 |
569 |
--------------------------------------------------------------------------------