PrometheusGroup commited on
Commit
5f4cbfa
·
verified ·
1 Parent(s): 0df20ca

ok, give me a straight forward design brief for this product, using separate html and python server, draggable mini-player, with play/pause next/previous random shuffle icon, video "x of y", main page has a title header, search bar, under the search bar is a flex-grid (variable zoom upto 8x8 cards - use "+" and "-" buttons) displaying search results using CSS cards, video thumbnail, duration, video title, video author or channel name, green background signifying it is downloaded, each card will have a remove "X" circle button on the lower right corner, when user enters text and clicks search a modal opens and displays the results in a search grid (this search grid is to be the same format as the playlist flex-grid - css cards will have a red background for 'not downloaded', a remove "x" circle button to remove it from the search results list, user can click a card to add it to the playlist when selected a card in the search results display gets a green glowing border. Search modal needs a 'back' button, returning the user to the playlist, where they can press 'download new' to start the downloads. Theuser must be able to acess the search AND playlist while a video is playing.

Browse files
Files changed (4) hide show
  1. design_brief.md +82 -0
  2. player.html +12 -9
  3. script.js +11 -3
  4. style.css +2 -3
design_brief.md ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```markdown
2
+ # VoidScape Media Player Design Brief
3
+
4
+ ## Core Features
5
+ 1. **Dual Interface System**:
6
+ - Main Playlist View
7
+ - Search Modal View
8
+
9
+ 2. **Player Components**:
10
+ - Draggable mini-player (fixed position)
11
+ - Play/Pause, Next/Previous, Shuffle controls
12
+ - Progress bar with time indicators
13
+ - Current track display (X of Y)
14
+
15
+ 3. **Playlist View**:
16
+ - Title header with gradient text
17
+ - Search bar with search button
18
+ - Variable zoom flex-grid (2x2 to 8x8)
19
+ - Card components showing:
20
+ - Video thumbnail
21
+ - Duration badge
22
+ - Video title
23
+ - Channel/author name
24
+ - Green background (downloaded)
25
+ - Remove "X" button (lower right)
26
+
27
+ 4. **Search Modal**:
28
+ - Full-screen overlay with blurred background
29
+ - Same card format as playlist but with:
30
+ - Red background (not downloaded)
31
+ - Remove "X" button
32
+ - Green glowing border on selection
33
+ - "Back to Playlist" button
34
+
35
+ 5. **Interaction Flow**:
36
+ - User enters search term → clicks search → modal opens
37
+ - Clicking cards in search adds to playlist
38
+ - "Download New" button initiates downloads
39
+ - All functions accessible while playing media
40
+
41
+ ## Technical Requirements
42
+ 1. **Frontend**:
43
+ - HTML5, CSS3, JavaScript (ES6+)
44
+ - Web Components for reusable UI
45
+ - Responsive flex-grid layout
46
+ - Smooth animations/transitions
47
+ - Dark theme with accent colors
48
+
49
+ 2. **Backend**:
50
+ - Python Flask server
51
+ - REST API endpoints for:
52
+ - Playlist management
53
+ - Search functionality
54
+ - Player controls
55
+
56
+ 3. **State Management**:
57
+ - Current playlist
58
+ - Search results
59
+ - Player status (playing/paused)
60
+ - Current track position
61
+
62
+ ## Visual Design
63
+ - Color Scheme:
64
+ - Primary: Dark background (#111827)
65
+ - Secondary: Gradient accents (blue-purple)
66
+ - Status Indicators:
67
+ - Green: Downloaded (#14532d)
68
+ - Red: Not downloaded (#7f1d1d)
69
+
70
+ - Typography:
71
+ - Main font: Inter (clean, modern)
72
+ - Headers: Bold with gradient text
73
+ - Body: Medium weight, high contrast
74
+
75
+ ## User Flow
76
+ 1. Landing on playlist view
77
+ 2. Searching for content
78
+ 3. Adding to playlist
79
+ 4. Managing downloads
80
+ 5. Controlling playback
81
+ 6. Accessing all features during playback
82
+ ```
player.html CHANGED
@@ -59,20 +59,23 @@
59
  Search
60
  </button>
61
  </div>
62
-
63
  <div class="flex justify-between items-center mb-6">
64
  <h2 class="text-2xl font-semibold">Your Playlist</h2>
65
- <div class="flex gap-2">
66
- <button id="zoom-out" class="p-2 bg-gray-800 rounded-lg hover:bg-gray-700">
67
- <i data-feather="minus"></i>
68
- </button>
69
- <button id="zoom-in" class="p-2 bg-gray-800 rounded-lg hover:bg-gray-700">
70
- <i data-feather="plus"></i>
71
  </button>
 
 
 
 
 
 
 
 
72
  </div>
73
  </div>
74
-
75
- <div id="playlist-grid" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
76
  <!-- Playlist items will be inserted here -->
77
  </div>
78
  </div>
 
59
  Search
60
  </button>
61
  </div>
 
62
  <div class="flex justify-between items-center mb-6">
63
  <h2 class="text-2xl font-semibold">Your Playlist</h2>
64
+ <div class="flex gap-4">
65
+ <button id="download-all" class="px-4 py-2 bg-green-600 hover:bg-green-700 rounded-lg font-medium">
66
+ Download New
 
 
 
67
  </button>
68
+ <div class="flex gap-2">
69
+ <button id="zoom-out" class="p-2 bg-gray-800 rounded-lg hover:bg-gray-700">
70
+ <i data-feather="minus"></i>
71
+ </button>
72
+ <button id="zoom-in" class="p-2 bg-gray-800 rounded-lg hover:bg-gray-700">
73
+ <i data-feather="plus"></i>
74
+ </button>
75
+ </div>
76
  </div>
77
  </div>
78
+ <div id="playlist-grid" class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4">
 
79
  <!-- Playlist items will be inserted here -->
80
  </div>
81
  </div>
script.js CHANGED
@@ -81,7 +81,6 @@ function renderSearchResults(songs) {
81
  grid.appendChild(card);
82
  });
83
  }
84
-
85
  function createMusicCard(song, isPlaylist) {
86
  const card = document.createElement('div');
87
  card.className = `music-card ${song.downloaded ? 'downloaded' : 'not-downloaded'}`;
@@ -90,16 +89,25 @@ function createMusicCard(song, isPlaylist) {
90
  card.innerHTML = `
91
  <img src="${song.thumbnail}" class="thumbnail">
92
  <span class="duration">${song.duration}</span>
93
- ${isPlaylist ? '<div class="remove-btn"><i data-feather="x"></i></div>' : ''}
94
  <div class="info">
95
  <div class="title">${song.title}</div>
96
  <div class="artist">${song.artist}</div>
97
  </div>
98
  `;
99
 
 
 
 
 
 
 
 
 
 
 
100
  return card;
101
  }
102
-
103
  function addToPlaylist(id) {
104
  fetch('/api/add_to_playlist', {
105
  method: 'POST',
 
81
  grid.appendChild(card);
82
  });
83
  }
 
84
  function createMusicCard(song, isPlaylist) {
85
  const card = document.createElement('div');
86
  card.className = `music-card ${song.downloaded ? 'downloaded' : 'not-downloaded'}`;
 
89
  card.innerHTML = `
90
  <img src="${song.thumbnail}" class="thumbnail">
91
  <span class="duration">${song.duration}</span>
92
+ <div class="remove-btn"><i data-feather="x"></i></div>
93
  <div class="info">
94
  <div class="title">${song.title}</div>
95
  <div class="artist">${song.artist}</div>
96
  </div>
97
  `;
98
 
99
+ if (!isPlaylist) {
100
+ card.addEventListener('click', () => {
101
+ document.querySelectorAll('#search-grid .music-card').forEach(c => {
102
+ c.classList.remove('selected');
103
+ });
104
+ card.classList.add('selected');
105
+ addToPlaylist(song.id);
106
+ });
107
+ }
108
+
109
  return card;
110
  }
 
111
  function addToPlaylist(id) {
112
  fetch('/api/add_to_playlist', {
113
  method: 'POST',
style.css CHANGED
@@ -85,11 +85,10 @@ body {
85
  .music-card.not-downloaded {
86
  background: linear-gradient(to bottom right, #1e293b, #7f1d1d);
87
  }
88
-
89
  .music-card.selected {
90
- box-shadow: 0 0 0 2px #4ade80;
 
91
  }
92
-
93
  .music-card .thumbnail {
94
  width: 100%;
95
  aspect-ratio: 1;
 
85
  .music-card.not-downloaded {
86
  background: linear-gradient(to bottom right, #1e293b, #7f1d1d);
87
  }
 
88
  .music-card.selected {
89
+ box-shadow: 0 0 0 3px #4ade80, 0 0 20px rgba(74, 222, 128, 0.5);
90
+ transition: box-shadow 0.3s ease;
91
  }
 
92
  .music-card .thumbnail {
93
  width: 100%;
94
  aspect-ratio: 1;