Hemann commited on
Commit
c062c49
·
verified ·
1 Parent(s): 083d37e

Update templates/unseen_videos.html

Browse files
Files changed (1) hide show
  1. templates/unseen_videos.html +75 -196
templates/unseen_videos.html CHANGED
@@ -6,7 +6,6 @@
6
  <title>UPSC Preparation: Video Content</title>
7
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
9
- <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval';">
10
  <style>
11
  :root {
12
  --primary-color: #3498db;
@@ -15,7 +14,7 @@
15
  --text-color: #333;
16
  --card-background: #fff;
17
  --button-hover: #1abc9c;
18
- --dark-mode-bg: #333;
19
  --dark-mode-text: #f5f5f5;
20
  }
21
  body {
@@ -32,17 +31,12 @@
32
  margin: 0 auto;
33
  padding: 20px;
34
  }
35
- h1 {
36
- color: var(--primary-color);
37
- text-align: center;
38
- margin-bottom: 30px;
39
- font-weight: 600;
40
- }
41
- h2 {
42
- color: var(--secondary-color);
43
- margin-bottom: 20px;
44
- font-weight: 600;
45
  }
 
46
  .quote-box {
47
  background-color: var(--card-background);
48
  border-left: 5px solid var(--primary-color);
@@ -51,39 +45,12 @@
51
  margin-bottom: 30px;
52
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
53
  }
54
- .quote-text {
55
- font-style: italic;
56
- margin-bottom: 10px;
57
- }
58
- .quote-author {
59
- font-weight: 600;
60
- text-align: right;
61
- }
62
- .video-list {
63
- list-style-type: none;
64
- padding: 0;
65
- }
66
  .video-item {
67
  background-color: var(--card-background);
68
  border-radius: 8px;
69
  margin-bottom: 20px;
70
  padding: 20px;
71
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
72
- transition: transform 0.3s ease;
73
- }
74
- .video-item:hover {
75
- transform: translateY(-5px);
76
- }
77
- .video-title {
78
- font-size: 18px;
79
- font-weight: 600;
80
- margin-bottom: 10px;
81
- color: var(--primary-color);
82
- }
83
- .video-date {
84
- font-size: 14px;
85
- color: #777;
86
- margin-bottom: 15px;
87
  }
88
  .btn {
89
  display: inline-block;
@@ -92,152 +59,94 @@
92
  color: #fff;
93
  text-decoration: none;
94
  border-radius: 5px;
95
- transition: background-color 0.3s ease;
96
  border: none;
97
  cursor: pointer;
98
- font-size: 16px;
99
- }
100
- .btn:hover {
101
- background-color: var(--button-hover);
102
- }
103
- .watch-btn {
104
- background-color: var(--secondary-color);
105
- }
106
- .watch-btn:hover {
107
- background-color: #27ae60;
108
- }
109
- .checkbox-wrapper {
110
- display: flex;
111
- align-items: center;
112
- margin-bottom: 10px;
113
- }
114
- .checkbox-wrapper input[type="checkbox"] {
115
- margin-right: 10px;
116
- }
117
- .submit-btn {
118
- display: block;
119
- width: 100%;
120
- padding: 15px;
121
- background-color: var(--primary-color);
122
- color: #fff;
123
- border: none;
124
- border-radius: 5px;
125
- font-size: 18px;
126
- cursor: pointer;
127
- transition: background-color 0.3s ease;
128
- margin-top: 20px;
129
- }
130
- .submit-btn:hover {
131
- background-color: #2980b9;
132
  }
 
133
  .modal {
134
  display: none;
135
  position: fixed;
136
- z-index: 1;
137
- left: 0;
138
- top: 0;
139
- width: 100%;
140
- height: 100%;
141
- overflow: auto;
142
- background-color: rgba(0,0,0,0.8);
143
  }
144
  .modal-content {
145
- background-color: var(--card-background);
146
  margin: 5% auto;
147
- padding: 20px;
148
- border: 1px solid #888;
149
- width: 80%;
150
  max-width: 800px;
151
  border-radius: 8px;
 
152
  }
153
  .close {
154
- color: #aaa;
155
- float: right;
156
- font-size: 28px;
157
- font-weight: bold;
 
158
  cursor: pointer;
159
  }
160
- .close:hover,
161
- .close:focus {
162
- color: #000;
163
- text-decoration: none;
164
- }
165
  .video-container {
166
  position: relative;
167
  padding-bottom: 56.25%;
168
  height: 0;
169
- overflow: hidden;
170
  }
171
  .video-container iframe {
172
  position: absolute;
173
- top: 0;
174
- left: 0;
175
- width: 100%;
176
- height: 100%;
177
  }
178
  .dark-mode {
179
  background-color: var(--dark-mode-bg);
180
  color: var(--dark-mode-text);
181
  }
182
- .dark-mode .btn {
183
- background-color: #555;
184
- }
185
- @media (max-width: 768px) {
186
- .video-item {
187
- padding: 15px;
188
- }
189
- .video-title {
190
- font-size: 16px;
191
- }
192
- .btn {
193
- padding: 8px 16px;
194
- }
195
  }
196
  </style>
197
  </head>
198
  <body>
199
  <div class="container">
200
- <h1>UPSC Preparation: Unseen Videos</h1>
 
 
 
201
 
202
  <div class="quote-section">
203
- <h2>Selected Quotes</h2>
204
  <div class="quote-box">
205
- <p class="quote-text" id="quote-text"></p>
206
  <p class="quote-author" id="quote-author"></p>
207
  </div>
208
  </div>
209
 
210
- <h2>Videos</h2>
211
  {% if videos %}
212
  <form action="{{ url_for('mark_watched') }}" method="POST">
213
- <ul class="video-list">
214
  {% for video in videos %}
215
  <li class="video-item">
216
- <div class="checkbox-wrapper">
217
- <input type="checkbox" name="video_ids" value="{{ video.videoId }}" id="video-{{ video.videoId }}">
218
- <label for="video-{{ video.videoId }}" class="video-title">{{ video.title }}</label>
219
  </div>
220
- <p class="video-date"><i class="far fa-calendar-alt"></i> Published on: {{ video.publishedAt.strftime('%Y-%m-%d') }}</p>
221
- <button type="button" class="btn watch-btn" data-video-id="{{ video.videoId }}"><i class="fas fa-play"></i> Watch Video</button>
 
222
  </li>
223
  {% endfor %}
224
  </ul>
225
- <button type="submit" class="submit-btn">Mark Selected as Watched</button>
226
  </form>
227
  {% else %}
228
  <p>No unseen videos found!</p>
229
  {% endif %}
230
- <br>
231
- <p><a href="https://www.youtube.com/playlist?list={{playlist_id}}" target="_blank" class="btn"><i class="fab fa-youtube"></i> Go to Channel</a></p>
232
- <hr>
233
- <a href="{{ url_for('index') }}" class="btn"><i class="fas fa-home"></i> Back to Home</a>
234
  </div>
235
 
236
  <div id="videoModal" class="modal">
237
  <div class="modal-content">
238
  <span class="close">&times;</span>
239
  <div class="video-container">
240
- <iframe id="modalIframe" src="" frameborder="0" allowfullscreen></iframe>
241
  </div>
242
  </div>
243
  </div>
@@ -245,89 +154,59 @@
245
  <script>
246
  const quotes = [
247
  { text: "Education is the most powerful weapon which you can use to change the world.", author: "Nelson Mandela" },
248
- { text: "In matters of style, swim with the current; in matters of principle, stand like a rock.", author: "Thomas Jefferson" },
249
- { text: "The weak can never forgive. Forgiveness is the attribute of the strong.", author: "Mahatma Gandhi" },
250
- { text: "Education is the most powerful weapon which you can use to change the world.", author: "Nelson Mandela" },
251
- { text: "In matters of style, swim with the current; in matters of principle, stand like a rock.", author: "Thomas Jefferson" },
252
- { text: "The weak can never forgive. Forgiveness is the attribute of the strong.", author: "Mahatma Gandhi" },
253
- { text: "Democracy is the government of the people, by the people, for the people.", author: "Abraham Lincoln" },
254
- { text: "The best way to find yourself is to lose yourself in the service of others.", author: "Mahatma Gandhi" },
255
- { text: "An ounce of practice is worth more than tons of preaching.", author: "Mahatma Gandhi" },
256
- { text: "Power tends to corrupt, and absolute power corrupts absolutely.", author: "Lord Acton" },
257
- { text: "Be the change that you wish to see in the world.", author: "Mahatma Gandhi" },
258
- { text: "Injustice anywhere is a threat to justice everywhere.", author: "Martin Luther King Jr." },
259
- { text: "A nation's culture resides in the hearts and in the soul of its people.", author: "Mahatma Gandhi" },
260
- { text: "The true test of a civilization is not the census, nor the size of the cities, nor the crops—but the kind of man that the country turns out.", author: "Ralph Waldo Emerson" },
261
- { text: "Good governance is less about structure and rules than being focused on the right values.", author: "Ratan Tata" },
262
- { text: "The measure of a man is what he does with power.", author: "Plato" },
263
- { text: "Justice delayed is justice denied.", author: "William E. Gladstone" },
264
- { text: "Ethics is knowing the difference between what you have a right to do and what is right to do.", author: "Potter Stewart" },
265
- { text: "You must be the guardian of your own democracy.", author: "Kofi Annan" },
266
- { text: "It is not the strongest of the species that survive, nor the most intelligent, but the one most responsive to change.", author: "Charles Darwin" },
267
- { text: "True public welfare lies in the happiness of the masses, not in a handful of millionaires.", author: "Jawaharlal Nehru" },
268
- { text: "The roots of education are bitter, but the fruit is sweet.", author: "Aristotle" },
269
- { text: "Freedom is never voluntarily given by the oppressor; it must be demanded by the oppressed.", author: "Martin Luther King Jr." },
270
- { text: "Our greatest glory is not in never falling, but in rising every time we fall.", author: "Confucius" },
271
- { text: "The future depends on what we do in the present.", author: "Mahatma Gandhi" },
272
- { text: "To sin by silence when they should protest makes cowards of men.", author: "Abraham Lincoln" },
273
- { text: "Poverty is the worst form of violence.", author: "Mahatma Gandhi" },
274
- { text: "Leadership is not about being in charge. It’s about taking care of those in your charge.", author: "Simon Sinek" },
275
- { text: "The more corrupt the state, the more numerous the laws.", author: "Tacitus" },
276
- { text: "If we want real peace in the world, we should start educating children.", author: "Mahatma Gandhi" },
277
- { text: "The price of greatness is responsibility.", author: "Winston Churchill" },
278
- { text: "The greatness of a nation can be judged by how it treats its weakest members.", author: "Mahatma Gandhi" },
279
- { text: "There is no higher religion than human service. To work for the common good is the greatest creed.", author: "Woodrow Wilson" },
280
- { text: "A leader is one who knows the way, goes the way, and shows the way.", author: "John C. Maxwell" },
281
- { text: "A society grows great when old men plant trees whose shade they know they shall never sit in.", author: "Greek Proverb" },
282
- { text: "True democracy is not the rule of the majority but the protection of the minority.", author: "Albert Camus" },
283
- { text: "A country’s greatness lies in its undying ideals of love and sacrifice that inspire the mothers of the race.", author: "Sarojini Naidu" },
284
- { text: "The highest education is that which does not merely give us information but makes our life in harmony with all existence.", author: "Rabindranath Tagore" },
285
- { text: "Liberty cannot be preserved without general knowledge among the people.", author: "John Adams" },
286
- { text: "There is no limit to what a man can do or where he can go if he does not mind who gets the credit.", author: "Ronald Reagan" },
287
- { text: "Integrity is the ability to stand by an idea.", author: "Ayn Rand" },
288
- { text: "We do not inherit the earth from our ancestors; we borrow it from our children.", author: "Native American Proverb" },
289
- { text: "Development is about transforming the lives of people, not just transforming economies.", author: "Joseph E. Stiglitz" }
290
-
291
  ];
292
 
 
293
  function showRandomQuote() {
294
- const randomQuote = quotes[Math.floor(Math.random() * quotes.length)];
295
- document.getElementById('quote-text').innerText = randomQuote.text;
296
- document.getElementById('quote-author').innerText = randomQuote.author;
297
  }
298
-
299
  showRandomQuote();
 
 
300
  document.getElementById('toggle-dark-mode').addEventListener('click', () => {
301
  document.body.classList.toggle('dark-mode');
302
  });
 
 
303
  const modal = document.getElementById("videoModal");
304
- const closeModal = document.getElementsByClassName("close")[0];
 
305
 
306
- closeModal.onclick = function() {
 
 
 
 
 
 
 
 
 
307
  modal.style.display = "none";
308
- document.getElementById("modalIframe").src = "";
309
- }
310
 
311
- window.onclick = function(event) {
312
  if (event.target == modal) {
313
  modal.style.display = "none";
314
- document.getElementById("modalIframe").src = "";
315
  }
316
- }
317
 
318
- document.querySelectorAll('.watch-btn').forEach(button => {
319
- button.addEventListener('click', function {
320
- const videoId = this.getAttribute('data-video-id');
321
- const iframeSrc = `https://www.youtube.com/embed/${videoId}`;
322
- document.getElementById('modalIframe').src = iframeSrc;
323
- modal.style.display = "block";
324
- });
325
- const iframe = document.getElementById('modalIframe');
326
- iframe.onload = function() {
327
- iframe.contentWindow.postMessage('{"event":"command","func":"setPlaybackRate","args":[2]}', '*');
328
- s};
329
-
330
- });
331
  </script>
332
  </body>
333
- </html>
 
6
  <title>UPSC Preparation: Video Content</title>
7
  <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;600&display=swap" rel="stylesheet">
8
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css">
 
9
  <style>
10
  :root {
11
  --primary-color: #3498db;
 
14
  --text-color: #333;
15
  --card-background: #fff;
16
  --button-hover: #1abc9c;
17
+ --dark-mode-bg: #1a1a1a;
18
  --dark-mode-text: #f5f5f5;
19
  }
20
  body {
 
31
  margin: 0 auto;
32
  padding: 20px;
33
  }
34
+ .header-flex {
35
+ display: flex;
36
+ justify-content: space-between;
37
+ align-items: center;
 
 
 
 
 
 
38
  }
39
+ h1 { color: var(--primary-color); font-weight: 600; }
40
  .quote-box {
41
  background-color: var(--card-background);
42
  border-left: 5px solid var(--primary-color);
 
45
  margin-bottom: 30px;
46
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
47
  }
 
 
 
 
 
 
 
 
 
 
 
 
48
  .video-item {
49
  background-color: var(--card-background);
50
  border-radius: 8px;
51
  margin-bottom: 20px;
52
  padding: 20px;
53
  box-shadow: 0 4px 6px rgba(0,0,0,0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  }
55
  .btn {
56
  display: inline-block;
 
59
  color: #fff;
60
  text-decoration: none;
61
  border-radius: 5px;
 
62
  border: none;
63
  cursor: pointer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  }
65
+ .watch-btn { background-color: var(--secondary-color); }
66
  .modal {
67
  display: none;
68
  position: fixed;
69
+ z-index: 100;
70
+ left: 0; top: 0; width: 100%; height: 100%;
71
+ background-color: rgba(0,0,0,0.9);
 
 
 
 
72
  }
73
  .modal-content {
74
+ background-color: #000;
75
  margin: 5% auto;
76
+ width: 90%;
 
 
77
  max-width: 800px;
78
  border-radius: 8px;
79
+ position: relative;
80
  }
81
  .close {
82
+ position: absolute;
83
+ right: -30px;
84
+ top: -30px;
85
+ color: #fff;
86
+ font-size: 30px;
87
  cursor: pointer;
88
  }
 
 
 
 
 
89
  .video-container {
90
  position: relative;
91
  padding-bottom: 56.25%;
92
  height: 0;
 
93
  }
94
  .video-container iframe {
95
  position: absolute;
96
+ top: 0; left: 0; width: 100%; height: 100%;
 
 
 
97
  }
98
  .dark-mode {
99
  background-color: var(--dark-mode-bg);
100
  color: var(--dark-mode-text);
101
  }
102
+ .dark-mode .video-item, .dark-mode .quote-box {
103
+ background-color: #2c2c2c;
104
+ color: white;
 
 
 
 
 
 
 
 
 
 
105
  }
106
  </style>
107
  </head>
108
  <body>
109
  <div class="container">
110
+ <div class="header-flex">
111
+ <h1>UPSC Preparation</h1>
112
+ <button id="toggle-dark-mode" class="btn"><i class="fas fa-moon"></i></button>
113
+ </div>
114
 
115
  <div class="quote-section">
 
116
  <div class="quote-box">
117
+ <p class="quote-text" id="quote-text">Loading inspiration...</p>
118
  <p class="quote-author" id="quote-author"></p>
119
  </div>
120
  </div>
121
 
122
+ <h2>Unseen Videos</h2>
123
  {% if videos %}
124
  <form action="{{ url_for('mark_watched') }}" method="POST">
125
+ <ul style="list-style:none; padding:0;">
126
  {% for video in videos %}
127
  <li class="video-item">
128
+ <div style="margin-bottom:10px;">
129
+ <input type="checkbox" name="video_ids" value="{{ video.videoId }}" id="v-{{ video.videoId }}">
130
+ <label for="v-{{ video.videoId }}" style="font-weight:600;">{{ video.title }}</label>
131
  </div>
132
+ <button type="button" class="btn watch-btn" data-video-id="{{ video.videoId }}">
133
+ <i class="fas fa-play"></i> Watch
134
+ </button>
135
  </li>
136
  {% endfor %}
137
  </ul>
138
+ <button type="submit" class="btn" style="width:100%; background:#e74c3c;">Mark Selected as Watched</button>
139
  </form>
140
  {% else %}
141
  <p>No unseen videos found!</p>
142
  {% endif %}
 
 
 
 
143
  </div>
144
 
145
  <div id="videoModal" class="modal">
146
  <div class="modal-content">
147
  <span class="close">&times;</span>
148
  <div class="video-container">
149
+ <iframe id="modalIframe" src="" frameborder="0" allow="autoplay; fullscreen" allowfullscreen></iframe>
150
  </div>
151
  </div>
152
  </div>
 
154
  <script>
155
  const quotes = [
156
  { text: "Education is the most powerful weapon which you can use to change the world.", author: "Nelson Mandela" },
157
+ { text: "Be the change that you wish to see in the world.", author: "Mahatma Gandhi" },
158
+ { text: "Justice delayed is justice denied.", author: "William E. Gladstone" },
159
+ { text: "The future depends on what we do in the present.", author: "Mahatma Gandhi" }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  ];
161
 
162
+ // Quote Logic
163
  function showRandomQuote() {
164
+ const q = quotes[Math.floor(Math.random() * quotes.length)];
165
+ document.getElementById('quote-text').innerText = q.text;
166
+ document.getElementById('quote-author').innerText = "- " + q.author;
167
  }
 
168
  showRandomQuote();
169
+
170
+ // Dark Mode
171
  document.getElementById('toggle-dark-mode').addEventListener('click', () => {
172
  document.body.classList.toggle('dark-mode');
173
  });
174
+
175
+ // Modal Logic
176
  const modal = document.getElementById("videoModal");
177
+ const iframe = document.getElementById("modalIframe");
178
+ const closeBtn = document.querySelector(".close");
179
 
180
+ document.querySelectorAll('.watch-btn').forEach(button => {
181
+ button.addEventListener('click', function() {
182
+ const videoId = this.getAttribute('data-video-id');
183
+ // Added enablejsapi=1 so you can control it via JS if needed
184
+ iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=1&enablejsapi=1`;
185
+ modal.style.display = "block";
186
+ });
187
+ });
188
+
189
+ closeBtn.onclick = () => {
190
  modal.style.display = "none";
191
+ iframe.src = "";
192
+ };
193
 
194
+ window.onclick = (event) => {
195
  if (event.target == modal) {
196
  modal.style.display = "none";
197
+ iframe.src = "";
198
  }
199
+ };
200
 
201
+ // Automatic 2x Speed Logic (Optional)
202
+ // Note: This only works if the YouTube API is loaded, but this is the safe way to do it
203
+ iframe.onload = function() {
204
+ iframe.contentWindow.postMessage(JSON.stringify({
205
+ "event": "command",
206
+ "func": "setPlaybackRate",
207
+ "args": [2]
208
+ }), '*');
209
+ };
 
 
 
 
210
  </script>
211
  </body>
212
+ </html>