ChandimaPrabath commited on
Commit
fa9497f
1 Parent(s): 2a108da

0.0.0.5 Alpha

Browse files
frontend/package-lock.json CHANGED
@@ -17,8 +17,10 @@
17
  "@fortawesome/react-fontawesome": "^0.2.2",
18
  "@mui/material": "^6.1.1",
19
  "axios": "^1.7.4",
 
20
  "next": "14.2.5",
21
  "react": "^18",
 
22
  "react-dom": "^18",
23
  "sharp": "^0.33.5",
24
  "styled-components": "^6.1.13",
@@ -1426,6 +1428,59 @@
1426
  "url": "https://opencollective.com/popperjs"
1427
  }
1428
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1429
  "node_modules/@rushstack/eslint-patch": {
1430
  "version": "1.10.4",
1431
  "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz",
@@ -1484,6 +1539,11 @@
1484
  "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
1485
  "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw=="
1486
  },
 
 
 
 
 
1487
  "node_modules/@typescript-eslint/parser": {
1488
  "version": "7.2.0",
1489
  "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz",
@@ -2066,6 +2126,24 @@
2066
  "url": "https://github.com/sponsors/sindresorhus"
2067
  }
2068
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2069
  "node_modules/brace-expansion": {
2070
  "version": "1.1.11",
2071
  "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -2214,6 +2292,11 @@
2214
  "node": ">= 6"
2215
  }
2216
  },
 
 
 
 
 
2217
  "node_modules/client-only": {
2218
  "version": "0.0.1",
2219
  "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
@@ -2520,6 +2603,14 @@
2520
  "node": ">=0.4.0"
2521
  }
2522
  },
 
 
 
 
 
 
 
 
2523
  "node_modules/detect-libc": {
2524
  "version": "2.0.3",
2525
  "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
@@ -3790,6 +3881,14 @@
3790
  "node": ">= 0.4"
3791
  }
3792
  },
 
 
 
 
 
 
 
 
3793
  "node_modules/is-arguments": {
3794
  "version": "1.1.1",
3795
  "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
@@ -5174,6 +5273,18 @@
5174
  "react-is": "^16.13.1"
5175
  }
5176
  },
 
 
 
 
 
 
 
 
 
 
 
 
5177
  "node_modules/proxy-from-env": {
5178
  "version": "1.1.0",
5179
  "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
@@ -5219,6 +5330,35 @@
5219
  "node": ">=0.10.0"
5220
  }
5221
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5222
  "node_modules/react-dom": {
5223
  "version": "18.3.1",
5224
  "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
@@ -5236,6 +5376,11 @@
5236
  "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
5237
  "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
5238
  },
 
 
 
 
 
5239
  "node_modules/react-transition-group": {
5240
  "version": "4.4.5",
5241
  "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
@@ -6243,6 +6388,20 @@
6243
  "url": "https://github.com/sponsors/ljharb"
6244
  }
6245
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6246
  "node_modules/uri-js": {
6247
  "version": "4.4.1",
6248
  "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -6310,6 +6469,14 @@
6310
  "global": "^4.3.1"
6311
  }
6312
  },
 
 
 
 
 
 
 
 
6313
  "node_modules/which": {
6314
  "version": "2.0.2",
6315
  "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
 
17
  "@fortawesome/react-fontawesome": "^0.2.2",
18
  "@mui/material": "^6.1.1",
19
  "axios": "^1.7.4",
20
+ "bootstrap": "^5.3.3",
21
  "next": "14.2.5",
22
  "react": "^18",
23
+ "react-bootstrap": "^2.10.4",
24
  "react-dom": "^18",
25
  "sharp": "^0.33.5",
26
  "styled-components": "^6.1.13",
 
1428
  "url": "https://opencollective.com/popperjs"
1429
  }
1430
  },
1431
+ "node_modules/@react-aria/ssr": {
1432
+ "version": "3.9.5",
1433
+ "resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.5.tgz",
1434
+ "integrity": "sha512-xEwGKoysu+oXulibNUSkXf8itW0npHHTa6c4AyYeZIJyRoegeteYuFpZUBPtIDE8RfHdNsSmE1ssOkxRnwbkuQ==",
1435
+ "dependencies": {
1436
+ "@swc/helpers": "^0.5.0"
1437
+ },
1438
+ "engines": {
1439
+ "node": ">= 12"
1440
+ },
1441
+ "peerDependencies": {
1442
+ "react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
1443
+ }
1444
+ },
1445
+ "node_modules/@restart/hooks": {
1446
+ "version": "0.4.16",
1447
+ "resolved": "https://registry.npmjs.org/@restart/hooks/-/hooks-0.4.16.tgz",
1448
+ "integrity": "sha512-f7aCv7c+nU/3mF7NWLtVVr0Ra80RqsO89hO72r+Y/nvQr5+q0UFGkocElTH6MJApvReVh6JHUFYn2cw1WdHF3w==",
1449
+ "dependencies": {
1450
+ "dequal": "^2.0.3"
1451
+ },
1452
+ "peerDependencies": {
1453
+ "react": ">=16.8.0"
1454
+ }
1455
+ },
1456
+ "node_modules/@restart/ui": {
1457
+ "version": "1.8.0",
1458
+ "resolved": "https://registry.npmjs.org/@restart/ui/-/ui-1.8.0.tgz",
1459
+ "integrity": "sha512-xJEOXUOTmT4FngTmhdjKFRrVVF0hwCLNPdatLCHkyS4dkiSK12cEu1Y0fjxktjJrdst9jJIc5J6ihMJCoWEN/g==",
1460
+ "dependencies": {
1461
+ "@babel/runtime": "^7.21.0",
1462
+ "@popperjs/core": "^2.11.6",
1463
+ "@react-aria/ssr": "^3.5.0",
1464
+ "@restart/hooks": "^0.4.9",
1465
+ "@types/warning": "^3.0.0",
1466
+ "dequal": "^2.0.3",
1467
+ "dom-helpers": "^5.2.0",
1468
+ "uncontrollable": "^8.0.1",
1469
+ "warning": "^4.0.3"
1470
+ },
1471
+ "peerDependencies": {
1472
+ "react": ">=16.14.0",
1473
+ "react-dom": ">=16.14.0"
1474
+ }
1475
+ },
1476
+ "node_modules/@restart/ui/node_modules/uncontrollable": {
1477
+ "version": "8.0.4",
1478
+ "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-8.0.4.tgz",
1479
+ "integrity": "sha512-ulRWYWHvscPFc0QQXvyJjY6LIXU56f0h8pQFvhxiKk5V1fcI8gp9Ht9leVAhrVjzqMw0BgjspBINx9r6oyJUvQ==",
1480
+ "peerDependencies": {
1481
+ "react": ">=16.14.0"
1482
+ }
1483
+ },
1484
  "node_modules/@rushstack/eslint-patch": {
1485
  "version": "1.10.4",
1486
  "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.4.tgz",
 
1539
  "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
1540
  "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw=="
1541
  },
1542
+ "node_modules/@types/warning": {
1543
+ "version": "3.0.3",
1544
+ "resolved": "https://registry.npmjs.org/@types/warning/-/warning-3.0.3.tgz",
1545
+ "integrity": "sha512-D1XC7WK8K+zZEveUPY+cf4+kgauk8N4eHr/XIHXGlGYkHLud6hK9lYfZk1ry1TNh798cZUCgb6MqGEG8DkJt6Q=="
1546
+ },
1547
  "node_modules/@typescript-eslint/parser": {
1548
  "version": "7.2.0",
1549
  "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.2.0.tgz",
 
2126
  "url": "https://github.com/sponsors/sindresorhus"
2127
  }
2128
  },
2129
+ "node_modules/bootstrap": {
2130
+ "version": "5.3.3",
2131
+ "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.3.tgz",
2132
+ "integrity": "sha512-8HLCdWgyoMguSO9o+aH+iuZ+aht+mzW0u3HIMzVu7Srrpv7EBBxTnrFlSCskwdY1+EOFQSm7uMJhNQHkdPcmjg==",
2133
+ "funding": [
2134
+ {
2135
+ "type": "github",
2136
+ "url": "https://github.com/sponsors/twbs"
2137
+ },
2138
+ {
2139
+ "type": "opencollective",
2140
+ "url": "https://opencollective.com/bootstrap"
2141
+ }
2142
+ ],
2143
+ "peerDependencies": {
2144
+ "@popperjs/core": "^2.11.8"
2145
+ }
2146
+ },
2147
  "node_modules/brace-expansion": {
2148
  "version": "1.1.11",
2149
  "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
 
2292
  "node": ">= 6"
2293
  }
2294
  },
2295
+ "node_modules/classnames": {
2296
+ "version": "2.5.1",
2297
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
2298
+ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="
2299
+ },
2300
  "node_modules/client-only": {
2301
  "version": "0.0.1",
2302
  "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz",
 
2603
  "node": ">=0.4.0"
2604
  }
2605
  },
2606
+ "node_modules/dequal": {
2607
+ "version": "2.0.3",
2608
+ "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz",
2609
+ "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==",
2610
+ "engines": {
2611
+ "node": ">=6"
2612
+ }
2613
+ },
2614
  "node_modules/detect-libc": {
2615
  "version": "2.0.3",
2616
  "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
 
3881
  "node": ">= 0.4"
3882
  }
3883
  },
3884
+ "node_modules/invariant": {
3885
+ "version": "2.2.4",
3886
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
3887
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
3888
+ "dependencies": {
3889
+ "loose-envify": "^1.0.0"
3890
+ }
3891
+ },
3892
  "node_modules/is-arguments": {
3893
  "version": "1.1.1",
3894
  "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz",
 
5273
  "react-is": "^16.13.1"
5274
  }
5275
  },
5276
+ "node_modules/prop-types-extra": {
5277
+ "version": "1.1.1",
5278
+ "resolved": "https://registry.npmjs.org/prop-types-extra/-/prop-types-extra-1.1.1.tgz",
5279
+ "integrity": "sha512-59+AHNnHYCdiC+vMwY52WmvP5dM3QLeoumYuEyceQDi9aEhtwN9zIQ2ZNo25sMyXnbh32h+P1ezDsUpUH3JAew==",
5280
+ "dependencies": {
5281
+ "react-is": "^16.3.2",
5282
+ "warning": "^4.0.0"
5283
+ },
5284
+ "peerDependencies": {
5285
+ "react": ">=0.14.0"
5286
+ }
5287
+ },
5288
  "node_modules/proxy-from-env": {
5289
  "version": "1.1.0",
5290
  "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
 
5330
  "node": ">=0.10.0"
5331
  }
5332
  },
5333
+ "node_modules/react-bootstrap": {
5334
+ "version": "2.10.4",
5335
+ "resolved": "https://registry.npmjs.org/react-bootstrap/-/react-bootstrap-2.10.4.tgz",
5336
+ "integrity": "sha512-W3398nBM2CBfmGP2evneEO3ZZwEMPtHs72q++eNw60uDGDAdiGn0f9yNys91eo7/y8CTF5Ke1C0QO8JFVPU40Q==",
5337
+ "dependencies": {
5338
+ "@babel/runtime": "^7.24.7",
5339
+ "@restart/hooks": "^0.4.9",
5340
+ "@restart/ui": "^1.6.9",
5341
+ "@types/react-transition-group": "^4.4.6",
5342
+ "classnames": "^2.3.2",
5343
+ "dom-helpers": "^5.2.1",
5344
+ "invariant": "^2.2.4",
5345
+ "prop-types": "^15.8.1",
5346
+ "prop-types-extra": "^1.1.0",
5347
+ "react-transition-group": "^4.4.5",
5348
+ "uncontrollable": "^7.2.1",
5349
+ "warning": "^4.0.3"
5350
+ },
5351
+ "peerDependencies": {
5352
+ "@types/react": ">=16.14.8",
5353
+ "react": ">=16.14.0",
5354
+ "react-dom": ">=16.14.0"
5355
+ },
5356
+ "peerDependenciesMeta": {
5357
+ "@types/react": {
5358
+ "optional": true
5359
+ }
5360
+ }
5361
+ },
5362
  "node_modules/react-dom": {
5363
  "version": "18.3.1",
5364
  "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
 
5376
  "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
5377
  "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
5378
  },
5379
+ "node_modules/react-lifecycles-compat": {
5380
+ "version": "3.0.4",
5381
+ "resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
5382
+ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
5383
+ },
5384
  "node_modules/react-transition-group": {
5385
  "version": "4.4.5",
5386
  "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
 
6388
  "url": "https://github.com/sponsors/ljharb"
6389
  }
6390
  },
6391
+ "node_modules/uncontrollable": {
6392
+ "version": "7.2.1",
6393
+ "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz",
6394
+ "integrity": "sha512-svtcfoTADIB0nT9nltgjujTi7BzVmwjZClOmskKu/E8FW9BXzg9os8OLr4f8Dlnk0rYWJIWr4wv9eKUXiQvQwQ==",
6395
+ "dependencies": {
6396
+ "@babel/runtime": "^7.6.3",
6397
+ "@types/react": ">=16.9.11",
6398
+ "invariant": "^2.2.4",
6399
+ "react-lifecycles-compat": "^3.0.4"
6400
+ },
6401
+ "peerDependencies": {
6402
+ "react": ">=15.0.0"
6403
+ }
6404
+ },
6405
  "node_modules/uri-js": {
6406
  "version": "4.4.1",
6407
  "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
 
6469
  "global": "^4.3.1"
6470
  }
6471
  },
6472
+ "node_modules/warning": {
6473
+ "version": "4.0.3",
6474
+ "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
6475
+ "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
6476
+ "dependencies": {
6477
+ "loose-envify": "^1.0.0"
6478
+ }
6479
+ },
6480
  "node_modules/which": {
6481
  "version": "2.0.2",
6482
  "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
frontend/package.json CHANGED
@@ -18,8 +18,10 @@
18
  "@fortawesome/react-fontawesome": "^0.2.2",
19
  "@mui/material": "^6.1.1",
20
  "axios": "^1.7.4",
 
21
  "next": "14.2.5",
22
  "react": "^18",
 
23
  "react-dom": "^18",
24
  "sharp": "^0.33.5",
25
  "styled-components": "^6.1.13",
 
18
  "@fortawesome/react-fontawesome": "^0.2.2",
19
  "@mui/material": "^6.1.1",
20
  "axios": "^1.7.4",
21
+ "bootstrap": "^5.3.3",
22
  "next": "14.2.5",
23
  "react": "^18",
24
+ "react-bootstrap": "^2.10.4",
25
  "react-dom": "^18",
26
  "sharp": "^0.33.5",
27
  "styled-components": "^6.1.13",
frontend/src/app/globals.css CHANGED
@@ -6,7 +6,7 @@
6
 
7
  body {
8
  font-family: 'Inter', 'Noto Sans', sans-serif;
9
- background-color: #0a0a10;
10
  -ms-overflow-style: none; /* IE and Edge */
11
  scrollbar-width: none; /* Firefox */
12
  scroll-behavior: smooth;
 
6
 
7
  body {
8
  font-family: 'Inter', 'Noto Sans', sans-serif;
9
+ background-color: #0a0a10 !important;
10
  -ms-overflow-style: none; /* IE and Edge */
11
  scrollbar-width: none; /* Firefox */
12
  scroll-behavior: smooth;
frontend/src/app/player/movie/[title]/MoviePlayerPage.css CHANGED
@@ -1,11 +1,32 @@
1
- .film-player-container{
2
- width: 100dvw;
3
- height: 100dvh;
4
- padding: 0 !important;
5
- margin: 0 !important;
 
6
  }
7
 
8
- .app-container{
9
- padding: 0;
10
- margin: 0;
11
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .film-player-container {
2
+ width: 100dvw;
3
+ height: 100dvh;
4
+ padding: 0;
5
+ margin: 0;
6
+ background-color: transparent;
7
  }
8
 
9
+ .app-container {
10
+ padding: 0;
11
+ margin: 0;
12
+ }
13
+
14
+ .loading {
15
+ position: fixed;
16
+ top: 50%;
17
+ left: 50%;
18
+ transform: translate(-50%, -50%);
19
+ justify-content: center;
20
+ align-items: center;
21
+ z-index: 100;
22
+ }
23
+ .text-white {
24
+ color: black;
25
+ }
26
+
27
+ .download-status {
28
+ display: flex;
29
+ justify-content: center;
30
+ align-items: center;
31
+ height: 100%;
32
+ }
frontend/src/app/player/movie/[title]/page.js CHANGED
@@ -2,7 +2,12 @@
2
  import apiClient from "@/api/apiClient";
3
  import { useEffect, useState } from "react";
4
  import MoviePlayer from "@/components/MoviePlayer";
5
- import './MoviePlayerPage.css';
 
 
 
 
 
6
 
7
  export default function FilmPlayer({ params }) {
8
  const title = decodeURIComponent(params.title);
@@ -14,142 +19,124 @@ export default function FilmPlayer({ params }) {
14
  const [metadata, setMetadata] = useState(null);
15
 
16
  useEffect(() => {
17
- const fetchMovieCard = async () => {
18
- try {
19
- const data = await apiClient.getMovieCard(title);
20
- if (data.title) {
21
- setMetadata(data);
22
- } else {
23
- setError("Movie card not found");
 
 
 
 
 
 
 
24
  setLoading(false);
25
  }
26
- } catch (err) {
27
- setError("Failed to fetch movie card");
28
- setLoading(false);
29
- }
30
- };
31
 
32
- fetchMovieCard();
 
33
  }, [title]);
34
 
35
  useEffect(() => {
36
  if (!metadata) return;
37
 
38
- const fetchVideoData = async () => {
39
- try {
40
- const data = await apiClient.getMovieByTitle(title);
41
-
42
- if (data.url) {
43
- setVideoUrl(data.url);
44
- setLoading(false);
45
- } else if (data.status === "Download started") {
46
- setDownloadProgressUrl(data.progress_url);
 
 
 
 
 
 
 
 
 
47
  setLoading(false);
48
  }
49
- } catch (err) {
50
- setError("Failed to fetch video data");
51
- setLoading(false);
52
- }
53
- };
54
 
55
- fetchVideoData();
 
56
  }, [title, metadata]);
57
 
58
  useEffect(() => {
59
  if (!downloadProgressUrl) return;
60
 
61
- const intervalId = setInterval(async () => {
62
- try {
63
- const response = await fetch(downloadProgressUrl);
64
- const progressData = await response.json();
65
-
66
- if (progressData.progress.status === "Completed") {
67
- clearInterval(intervalId);
68
- setDownloadProgressUrl(null);
69
- setDownloadProgress(null);
70
- setLoading(true);
71
- setTimeout(async () => {
72
- const data = await apiClient.getMovieByTitle(title);
73
- if (data.url) {
74
- setVideoUrl(data.url);
75
- setLoading(false);
76
- }
77
- }, 5000); // Wait 5 seconds before fetching the video URL again
78
- } else {
79
- setDownloadProgress(progressData.progress);
 
 
 
 
 
 
 
 
 
 
 
 
80
  }
81
- } catch (err) {
82
- setError("Failed to fetch download progress");
83
- }
84
- }, 5000);
85
 
86
- return () => clearInterval(intervalId);
 
87
  }, [downloadProgressUrl, title]);
88
 
89
  return (
90
  <div className="film-player-container">
91
- {loading && <p className="text-white">Loading...</p>}
92
- {error && <p className="text-red-500">{error}</p>}
93
- {/* {metadata && !error && (
94
- <div className="metadata">
95
- <p className="text-white">
96
- {metadata.title} ({metadata.year})
97
- </p>
98
- {metadata.image && (
99
- <img
100
- src={
101
- metadata.banner?.thumbnail
102
- ? metadata.banner.thumbnail
103
- : metadata.image
104
- }
105
- alt={`${metadata.title} banner`}
106
- />
107
- )}
108
  </div>
109
- )} */}
 
110
  {downloadProgressUrl && downloadProgress ? (
111
  <div className="download-status">
112
- <p className="text-yellow-500">
113
- {downloadProgress.status} - {downloadProgress.progress.toFixed(2)}%
114
- downloaded
115
- </p>
116
- <p className="text-yellow-500">
117
- ETA: {downloadProgress.eta.toFixed(2)} seconds
118
- </p>
119
  </div>
120
  ) : (
121
  videoUrl && (
122
- <MoviePlayer videoUrl={videoUrl} title={metadata.title}/>
 
 
 
123
  )
124
  )}
125
- <style jsx>{`
126
- .film-player-container {
127
- padding: 20px;
128
- }
129
- .text-white {
130
- color: white;
131
- }
132
- .text-red-500 {
133
- color: red;
134
- }
135
- .text-yellow-500 {
136
- color: yellow;
137
- }
138
- .metadata {
139
- margin-bottom: 20px;
140
- }
141
- .metadata img {
142
- max-width: 100%;
143
- margin-bottom: 10px;
144
- }
145
- .video-player {
146
- margin-top: 20px;
147
- }
148
- video {
149
- width: 100%;
150
- max-width: 800px;
151
- }
152
- `}</style>
153
  </div>
154
  );
155
  }
 
2
  import apiClient from "@/api/apiClient";
3
  import { useEffect, useState } from "react";
4
  import MoviePlayer from "@/components/MoviePlayer";
5
+ import "./MoviePlayerPage.css";
6
+ import { Spinner } from "@/components/Spinner";
7
+ import { ProgressBar, Container, Row, Col, Alert } from "react-bootstrap";
8
+ import "bootstrap/dist/css/bootstrap.min.css";
9
+
10
+ const DEBUG = false; // Set to true to enable debug mode
11
 
12
  export default function FilmPlayer({ params }) {
13
  const title = decodeURIComponent(params.title);
 
19
  const [metadata, setMetadata] = useState(null);
20
 
21
  useEffect(() => {
22
+ if (DEBUG) {
23
+ setMetadata({ title: "Debug Movie", year: "2024" });
24
+ } else {
25
+ const fetchMovieCard = async () => {
26
+ try {
27
+ const data = await apiClient.getMovieCard(title);
28
+ if (data.title) {
29
+ setMetadata(data);
30
+ } else {
31
+ setError("Movie card not found");
32
+ setLoading(false);
33
+ }
34
+ } catch (err) {
35
+ setError("Failed to fetch movie card");
36
  setLoading(false);
37
  }
38
+ };
 
 
 
 
39
 
40
+ fetchMovieCard();
41
+ }
42
  }, [title]);
43
 
44
  useEffect(() => {
45
  if (!metadata) return;
46
 
47
+ if (DEBUG) {
48
+ setTimeout(() => {
49
+ setDownloadProgressUrl("dummy_progress_url");
50
+ setLoading(false);
51
+ }, 1000);
52
+ } else {
53
+ const fetchVideoData = async () => {
54
+ try {
55
+ const data = await apiClient.getMovieByTitle(title);
56
+ if (data.url) {
57
+ setVideoUrl(data.url);
58
+ setLoading(false);
59
+ } else if (data.status === "Download started") {
60
+ setDownloadProgressUrl(data.progress_url);
61
+ setLoading(false);
62
+ }
63
+ } catch (err) {
64
+ setError("Failed to fetch video data");
65
  setLoading(false);
66
  }
67
+ };
 
 
 
 
68
 
69
+ fetchVideoData();
70
+ }
71
  }, [title, metadata]);
72
 
73
  useEffect(() => {
74
  if (!downloadProgressUrl) return;
75
 
76
+ if (DEBUG) {
77
+ const dummyProgressData = {
78
+ progress: {
79
+ status: "Downloading",
80
+ progress: 45.5,
81
+ eta: 120,
82
+ },
83
+ };
84
+ setDownloadProgress(dummyProgressData.progress);
85
+ } else {
86
+ const intervalId = setInterval(async () => {
87
+ try {
88
+ const response = await fetch(downloadProgressUrl);
89
+ const progressData = await response.json();
90
+ if (progressData.progress.status === "Completed") {
91
+ clearInterval(intervalId);
92
+ setDownloadProgressUrl(null);
93
+ setDownloadProgress(null);
94
+ setLoading(true);
95
+ setTimeout(async () => {
96
+ const data = await apiClient.getMovieByTitle(title);
97
+ if (data.url) {
98
+ setVideoUrl(data.url);
99
+ setLoading(false);
100
+ }
101
+ }, 5000); // Wait 5 seconds before fetching the video URL again
102
+ } else {
103
+ setDownloadProgress(progressData.progress);
104
+ }
105
+ } catch (err) {
106
+ setError("Failed to fetch download progress");
107
  }
108
+ }, 5000);
 
 
 
109
 
110
+ return () => clearInterval(intervalId);
111
+ }
112
  }, [downloadProgressUrl, title]);
113
 
114
  return (
115
  <div className="film-player-container">
116
+ {loading && (
117
+ <div className="loading">
118
+ <Spinner />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  </div>
120
+ )}
121
+ {error && <Alert variant="danger">{error}</Alert>}
122
  {downloadProgressUrl && downloadProgress ? (
123
  <div className="download-status">
124
+ <Alert variant="info">
125
+ <strong>{downloadProgress.status}</strong> -{" "}
126
+ {downloadProgress.progress.toFixed(2)}%{" "}
127
+ <p>
128
+ Wait for {downloadProgress.eta.toFixed(1)} Seconds
129
+ </p>
130
+ </Alert>
131
  </div>
132
  ) : (
133
  videoUrl && (
134
+ <MoviePlayer
135
+ videoUrl={videoUrl}
136
+ title={`${metadata.title} (${metadata.year})`}
137
+ />
138
  )
139
  )}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  </div>
141
  );
142
  }
frontend/src/lib/config.js CHANGED
@@ -1,7 +1,7 @@
1
  const config = {
2
  apiBaseUrl: 'https://hans-den-load-balancer.hf.space',
3
  searchUrl: 'https://unicone-studio-search.hf.space/api/search',
4
- version: "0.0.0.4 Alpha",
5
  };
6
 
7
  export default config;
 
1
  const config = {
2
  apiBaseUrl: 'https://hans-den-load-balancer.hf.space',
3
  searchUrl: 'https://unicone-studio-search.hf.space/api/search',
4
+ version: "0.0.0.5 Alpha",
5
  };
6
 
7
  export default config;