ChandimaPrabath commited on
Commit
96b94b7
·
1 Parent(s): 11c56f5
frontend/src/app/category/[category]/CategoryPage.css CHANGED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ .music-card-section {
2
+ display: flex;
3
+ flex-wrap: wrap;
4
+ gap: 10px;
5
+ justify-content: center;
6
+ overflow-y: auto;
7
+ height: 100%;
8
+ width: 100%;
9
+ }
frontend/src/app/category/[category]/page.js CHANGED
@@ -15,7 +15,7 @@ export default function CategoryPage({ params }) {
15
  useEffect(() => {
16
  const fetchMusicByCategory = async () => {
17
  try {
18
- const response = await fetch(`/api/get/category/${category}?page=${page}&limit=10`);
19
  if (!response.ok) {
20
  throw new Error("Failed to fetch music");
21
  }
@@ -58,7 +58,7 @@ export default function CategoryPage({ params }) {
58
  return (
59
  <div className="category-page font-[family-name:var(--font-geist-sans)]">
60
  <h1>{category.charAt(0).toUpperCase() + category.slice(1)} Music</h1>
61
- <div className="card-section">
62
  {musicItems.map((file, index) => (
63
  <Card
64
  key={`${file}-${page}`} // Ensure unique key by appending page number
 
15
  useEffect(() => {
16
  const fetchMusicByCategory = async () => {
17
  try {
18
+ const response = await fetch(`/api/get/category/${category}?page=${page}&limit=20`);
19
  if (!response.ok) {
20
  throw new Error("Failed to fetch music");
21
  }
 
58
  return (
59
  <div className="category-page font-[family-name:var(--font-geist-sans)]">
60
  <h1>{category.charAt(0).toUpperCase() + category.slice(1)} Music</h1>
61
+ <div className="music-card-section">
62
  {musicItems.map((file, index) => (
63
  <Card
64
  key={`${file}-${page}`} // Ensure unique key by appending page number
frontend/src/app/globals.css CHANGED
@@ -8,12 +8,19 @@
8
  --background-secondary: #110652;
9
  --foreground-secondary: #1d85b9;
10
  --background-2: #332a77;
 
11
  }
12
 
13
  body {
14
  color: var(--foreground);
15
  background: var(--background);
16
  font-family: Arial, Helvetica, sans-serif;
 
 
 
 
 
 
17
  }
18
 
19
  footer {
@@ -21,6 +28,7 @@ footer {
21
  }
22
 
23
  .app-container{
24
- overflow: hidden;
25
- max-width: 100vw;
 
26
  }
 
8
  --background-secondary: #110652;
9
  --foreground-secondary: #1d85b9;
10
  --background-2: #332a77;
11
+ --foreground-2: #0b32a9;
12
  }
13
 
14
  body {
15
  color: var(--foreground);
16
  background: var(--background);
17
  font-family: Arial, Helvetica, sans-serif;
18
+ max-width: 100vw;
19
+ min-height: 100vh;
20
+ max-height: 100vh;
21
+ display: flex;
22
+ flex-direction: column;
23
+ justify-content: space-between;
24
  }
25
 
26
  footer {
 
28
  }
29
 
30
  .app-container{
31
+ margin-left: 10px;
32
+ margin-right: 10px;
33
+ height: 85vh;
34
  }
frontend/src/app/layout.js CHANGED
@@ -26,7 +26,7 @@ export default function RootLayout({ children }) {
26
  className={`${geistSans.variable} ${geistMono.variable} antialiased max-h-screen overflow-hidden`}
27
  >
28
  <div className="app-container">{children}</div>
29
- <footer className="absolute bottom-0 flex items-center w-full">
30
  <MusicPlayer/>
31
  </footer>
32
  </body>
 
26
  className={`${geistSans.variable} ${geistMono.variable} antialiased max-h-screen overflow-hidden`}
27
  >
28
  <div className="app-container">{children}</div>
29
+ <footer className="bottom-0 flex items-center w-full">
30
  <MusicPlayer/>
31
  </footer>
32
  </body>
frontend/src/components/Card.css CHANGED
@@ -1,21 +1,23 @@
1
  .music-card {
2
- width: 180px;
3
  height: 40;
4
- background-color: var(--background-2);
5
- border-radius: 50px;
 
 
 
6
  display: flex;
7
  align-items: center;
 
8
  }
9
 
10
  .card-title {
11
  display: -webkit-box;
12
- -webkit-line-clamp: 1;
13
  -webkit-box-orient: vertical;
14
  overflow: hidden;
15
  text-overflow: ellipsis;
16
  white-space: normal;
17
- line-height: 1.2em;
18
- max-height: 1.2em;
19
  font-size: 0.8rem;
20
  cursor: pointer;
21
  }
 
1
  .music-card {
2
+ width: 200px;
3
  height: 40;
4
+ background-image: linear-gradient(var(--background-2), var(--foreground-2));
5
+ border-top-left-radius: 20px;
6
+ border-bottom-left-radius: 20px;
7
+ border-top-right-radius: 5px;
8
+ border-bottom-right-radius: 20px;
9
  display: flex;
10
  align-items: center;
11
+ gap: 10px;
12
  }
13
 
14
  .card-title {
15
  display: -webkit-box;
16
+ -webkit-line-clamp: 2;
17
  -webkit-box-orient: vertical;
18
  overflow: hidden;
19
  text-overflow: ellipsis;
20
  white-space: normal;
 
 
21
  font-size: 0.8rem;
22
  cursor: pointer;
23
  }
frontend/src/components/CategoriesSection.css CHANGED
@@ -10,7 +10,7 @@
10
  width: 120px;
11
  height: 60px;
12
  padding: 10px;
13
- background-color: var(--foreground-secondary);
14
  border-radius: 5px;
15
  display: flex;
16
  justify-content: center;
 
10
  width: 120px;
11
  height: 60px;
12
  padding: 10px;
13
+ background-image: linear-gradient(var(--foreground-secondary), var(--foreground-2));
14
  border-radius: 5px;
15
  display: flex;
16
  justify-content: center;
frontend/src/components/MusicPlayer.css CHANGED
@@ -5,6 +5,8 @@
5
 
6
  .player-minimized video {
7
  height: 10vh;
 
 
8
  }
9
 
10
  .music-title {
@@ -121,12 +123,14 @@
121
  width: 100%;
122
  display: flex;
123
  justify-content: left;
 
124
  }
125
 
126
  .player-controls-right {
127
  width: 100%;
128
  display: flex;
129
  justify-content: right;
 
130
  }
131
 
132
 
@@ -168,7 +172,8 @@
168
  }
169
 
170
  .player-controls-mini {
171
-
 
172
  }
173
 
174
  .player-mini-control-top {
 
5
 
6
  .player-minimized video {
7
  height: 10vh;
8
+ width: 25vh;
9
+ background-color: black;
10
  }
11
 
12
  .music-title {
 
123
  width: 100%;
124
  display: flex;
125
  justify-content: left;
126
+ gap: 10px;
127
  }
128
 
129
  .player-controls-right {
130
  width: 100%;
131
  display: flex;
132
  justify-content: right;
133
+ gap: 10px;
134
  }
135
 
136
 
 
172
  }
173
 
174
  .player-controls-mini {
175
+ background-image: linear-gradient(var(--background-2), var(--background-secondary));
176
+ width: 100%;
177
  }
178
 
179
  .player-mini-control-top {
frontend/src/components/MusicPlayer.js CHANGED
@@ -344,6 +344,21 @@ export default function MusicPlayer() {
344
  <button className="player-min-button" onClick={destroyPlayer}>
345
  <TbPlayerStop />
346
  </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
  </div>
348
  </div>
349
  )}
 
344
  <button className="player-min-button" onClick={destroyPlayer}>
345
  <TbPlayerStop />
346
  </button>
347
+ <button
348
+ onClick={toggleMute}
349
+ className="player-min-button volumn-btn"
350
+ >
351
+ {isMuted ? <TbVolumeOff /> : <TbVolume />}
352
+ </button>
353
+ <input
354
+ type="range"
355
+ className="volume-control"
356
+ min="0"
357
+ max="1"
358
+ step="0.01"
359
+ value={volume}
360
+ onChange={handleVolumeChange}
361
+ />
362
  </div>
363
  </div>
364
  )}
frontend/src/context/MusicPlayerContext.js CHANGED
@@ -13,7 +13,6 @@ export const MusicPlayerProvider = ({ children }) => {
13
  const [loadingProgress, setLoadingProgress] = useState(null); // New state for loading progress
14
 
15
  const initializePlayer = async (source) => {
16
- // Extract the file name from the source path
17
  const extractedFileName = source.split('/').pop();
18
  setFileName(extractedFileName); // Set the file name state
19
 
@@ -51,18 +50,26 @@ export const MusicPlayerProvider = ({ children }) => {
51
  } catch (error) {
52
  console.error("Error fetching progress:", error);
53
  }
54
- }, 2000); // Check progress every 2 seconds
55
  };
56
 
57
- const fetchFinalUrl = async (fileName) => {
58
  try {
59
  const response = await fetch(`/api/get/music/${encodeURIComponent(fileName)}`);
60
  const data = await response.json();
61
 
62
- // Start the player with the final URL
63
- startPlayer(data.url);
 
 
 
 
 
 
64
  } catch (error) {
65
  console.error("Error fetching final URL:", error);
 
 
66
  }
67
  };
68
 
 
13
  const [loadingProgress, setLoadingProgress] = useState(null); // New state for loading progress
14
 
15
  const initializePlayer = async (source) => {
 
16
  const extractedFileName = source.split('/').pop();
17
  setFileName(extractedFileName); // Set the file name state
18
 
 
50
  } catch (error) {
51
  console.error("Error fetching progress:", error);
52
  }
53
+ }, 1000); // Check progress every second
54
  };
55
 
56
+ const fetchFinalUrl = async (fileName, attempt = 1) => {
57
  try {
58
  const response = await fetch(`/api/get/music/${encodeURIComponent(fileName)}`);
59
  const data = await response.json();
60
 
61
+ if (data.url) {
62
+ // Start the player with the final URL if available
63
+ startPlayer(data.url);
64
+ } else {
65
+ // If URL is not yet available, retry with exponential backoff
66
+ const retryDelay = Math.min(2000 * attempt, 10000); // Increase delay with each attempt, maxing at 10 seconds
67
+ setTimeout(() => fetchFinalUrl(fileName, attempt + 1), retryDelay);
68
+ }
69
  } catch (error) {
70
  console.error("Error fetching final URL:", error);
71
+ const retryDelay = Math.min(2000 * attempt, 10000); // Retry after delay in case of error
72
+ setTimeout(() => fetchFinalUrl(fileName, attempt + 1), retryDelay);
73
  }
74
  };
75