coursewatcher 1.0.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,112 +6,155 @@
6
6
  <%- include('../partials/header') %>
7
7
 
8
8
  <main class="container player-container">
9
- <!-- Video Player Section -->
10
- <section class="player-section">
11
- <div class="video-wrapper">
12
- <video id="videoPlayer" class="video-player" controls preload="metadata"
13
- data-video-id="<%= video.id %>" data-saved-position="<%= video.position %>">
14
- <source src="/api/videos/<%= video.id %>/stream" type="video/mp4">
15
- Your browser does not support the video tag.
16
- </video>
17
- </div>
9
+ <div class="player-layout">
10
+ <!-- Main Player Section -->
11
+ <div class="player-main">
12
+ <!-- Video Player Section -->
13
+ <section class="player-section">
14
+ <h1 class="video-title">
15
+ <%= video.title %>
16
+ </h1>
17
+ <div class="video-wrapper">
18
+ <video id="videoPlayer" class="plyr" playsinline controls
19
+ data-video-id="<%= video.id %>" data-saved-position="<%= video.position %>"
20
+ data-next-video-url="<%= adjacent.next ? '/video/' + adjacent.next : '' %>">
21
+ <source src="/api/videos/<%= video.id %>/stream" type="video/mp4">
22
+ Your browser does not support the video tag.
23
+ </video>
18
24
 
19
- <!-- Navigation -->
20
- <div class="player-nav">
21
- <% if (adjacent.prev) { %>
22
- <a href="/video/<%= adjacent.prev %>" class="nav-button prev">
23
- Previous
24
- </a>
25
- <% } else { %>
26
- <span class="nav-button disabled">← Previous</span>
27
- <% } %>
25
+ <!-- Auto-play Countdown Overlay -->
26
+ <div id="autoplayOverlay" class="autoplay-overlay hidden">
27
+ <div class="autoplay-content">
28
+ <button id="skipToNext" class="autoplay-countdown-ring"
29
+ title="Click to play now">
30
+ <svg viewBox="0 0 100 100">
31
+ <circle cx="50" cy="50" r="45" class="countdown-bg" />
32
+ <circle cx="50" cy="50" r="45" class="countdown-progress"
33
+ id="countdownProgress" />
34
+ </svg>
35
+ <span id="countdownNumber" class="countdown-number">5</span>
36
+ </button>
37
+ <p class="autoplay-text">Up Next</p>
38
+ <p id="nextVideoTitle" class="autoplay-next-title"></p>
39
+ <button id="cancelAutoplay" class="btn autoplay-cancel">Cancel</button>
40
+ </div>
41
+ </div>
42
+ </div>
28
43
 
29
- <a href="/" class="nav-button home">📚 Back to Course</a>
44
+ <!-- Navigation -->
45
+ <div class="player-nav">
46
+ <% if (adjacent.prev) { %>
47
+ <a href="/video/<%= adjacent.prev %>" class="nav-button prev">
48
+ ← Previous
49
+ </a>
50
+ <% } else { %>
51
+ <span class="nav-button disabled">← Previous</span>
52
+ <% } %>
30
53
 
31
- <% if (adjacent.next) { %>
32
- <a href="/video/<%= adjacent.next %>" class="nav-button next">
33
- Next →
34
- </a>
35
- <% } else { %>
36
- <span class="nav-button disabled">Next →</span>
37
- <% } %>
38
- </div>
39
- </section>
54
+ <a href="/" class="nav-button home">📚 Back to Course</a>
40
55
 
41
- <!-- Video Info Section -->
42
- <section class="video-info-section">
43
- <h1 class="video-title">
44
- <%= video.title %>
45
- </h1>
56
+ <% if (adjacent.next) { %>
57
+ <a href="/video/<%= adjacent.next %>" class="nav-button next">
58
+ Next
59
+ </a>
60
+ <% } else { %>
61
+ <span class="nav-button disabled">Next →</span>
62
+ <% } %>
63
+ </div>
64
+ </section>
46
65
 
47
- <!-- Status Controls -->
48
- <div class="status-controls">
49
- <span class="status-label">Status:</span>
50
- <div class="status-buttons">
51
- <button class="status-btn <%= video.status === 'unwatched' ? 'active' : '' %>"
52
- data-status="unwatched">
53
- ○ Unwatched
54
- </button>
55
- <button class="status-btn <%= video.status === 'in-progress' ? 'active' : '' %>"
56
- data-status="in-progress">
57
- ▶ In Progress
58
- </button>
59
- <button class="status-btn <%= video.status === 'completed' ? 'active' : '' %>"
60
- data-status="completed">
61
- ✓ Completed
62
- </button>
63
- </div>
64
- </div>
66
+ <!-- Video Info Section -->
67
+ <section class="video-info-section">
65
68
 
66
- <!-- Playback Controls -->
67
- <div class="playback-controls">
68
- <div class="control-group">
69
- <span class="control-label">Speed</span>
70
- <button class="control-btn" id="speedDown" title="Decrease speed (W)">W ◀</button>
71
- <span class="control-value" id="speedDisplay">1.0x</span>
72
- <button class="control-btn" id="speedUp" title="Increase speed (E)">▶ E</button>
73
- </div>
69
+ <!-- Status Controls -->
70
+ <div class="status-controls">
71
+ <span class="status-label">Status:</span>
72
+ <div class="status-buttons">
73
+ <button class="status-btn <%= video.status === 'unwatched' ? 'active' : '' %>"
74
+ data-status="unwatched">
75
+ Unwatched
76
+ </button>
77
+ <button class="status-btn <%= video.status === 'in-progress' ? 'active' : '' %>"
78
+ data-status="in-progress">
79
+ ▶ In Progress
80
+ </button>
81
+ <button class="status-btn <%= video.status === 'completed' ? 'active' : '' %>"
82
+ data-status="completed">
83
+ ✓ Completed
84
+ </button>
85
+ </div>
86
+ </div>
74
87
 
75
- <div class="control-group">
76
- <span class="control-label">Seek</span>
77
- <button class="control-btn" id="seekBack5" title="Back 5s (J)">◀◀ 5s</button>
78
- <button class="control-btn" id="seekForward5" title="Forward 5s (K)">5s ▶▶</button>
79
- <button class="control-btn" id="seekForward10" title="Forward 10s (L)">10s ▶▶</button>
80
- </div>
88
+ <!-- Keyboard Shortcuts Help -->
89
+ <details class="shortcuts-help">
90
+ <summary>⌨️ Keyboard Shortcuts</summary>
91
+ <div class="shortcuts-grid">
92
+ <div class="shortcut"><kbd>Space</kbd> / <kbd>K</kbd> Play/Pause</div>
93
+ <div class="shortcut"><kbd>M</kbd> Mute/Unmute</div>
94
+ <div class="shortcut"><kbd>F</kbd> Fullscreen</div>
95
+ <div class="shortcut"><kbd>←</kbd> Back 10s</div>
96
+ <div class="shortcut"><kbd>→</kbd> Forward 10s</div>
97
+ <div class="shortcut"><kbd>↑</kbd> Volume Up</div>
98
+ <div class="shortcut"><kbd>↓</kbd> Volume Down</div>
99
+ <div class="shortcut"><kbd>C</kbd> Captions</div>
100
+ </div>
101
+ </details>
102
+ </section>
103
+
104
+ <!-- Notes Section -->
105
+ <section class="notes-section">
106
+ <h2 class="section-title">📝 Notes</h2>
107
+ <textarea id="notesEditor" class="notes-editor"
108
+ placeholder="Take notes for this video... (Markdown supported)"><%= notes.content || '' %></textarea>
109
+ <div class="notes-actions">
110
+ <button id="saveNotes" class="btn btn-primary">Save Notes</button>
111
+ <span id="notesSaveStatus" class="save-status"></span>
112
+ </div>
113
+ </section>
81
114
  </div>
82
115
 
83
- <!-- Keyboard Shortcuts Help -->
84
- <details class="shortcuts-help">
85
- <summary>⌨️ Keyboard Shortcuts</summary>
86
- <div class="shortcuts-grid">
87
- <div class="shortcut"><kbd>Space</kbd> Play/Pause</div>
88
- <div class="shortcut"><kbd>W</kbd> Slower</div>
89
- <div class="shortcut"><kbd>E</kbd> Faster</div>
90
- <div class="shortcut"><kbd>J</kbd> Back 5s</div>
91
- <div class="shortcut"><kbd>K</kbd> Forward 5s</div>
92
- <div class="shortcut"><kbd>L</kbd> Forward 10s</div>
93
- <div class="shortcut"><kbd>Shift+J</kbd> Back 30s</div>
94
- <div class="shortcut"><kbd>Shift+L</kbd> Forward 30s</div>
95
- <div class="shortcut"><kbd>←</kbd> Back 5s</div>
96
- <div class="shortcut"><kbd>→</kbd> Forward 5s</div>
116
+ <!-- Queue Panel -->
117
+ <aside class="queue-panel">
118
+ <div class="queue-header">
119
+ <h2 class="queue-title">📋 Queue</h2>
120
+ <span class="queue-module-name">
121
+ <%= queue.moduleName %>
122
+ </span>
97
123
  </div>
98
- </details>
99
- </section>
100
-
101
- <!-- Notes Section -->
102
- <section class="notes-section">
103
- <h2 class="section-title">📝 Notes</h2>
104
- <textarea id="notesEditor" class="notes-editor"
105
- placeholder="Take notes for this video... (Markdown supported)"><%= notes.content || '' %></textarea>
106
- <div class="notes-actions">
107
- <button id="saveNotes" class="btn btn-primary">Save Notes</button>
108
- <span id="notesSaveStatus" class="save-status"></span>
109
- </div>
110
- </section>
124
+ <div class="queue-list">
125
+ <% queue.videos.forEach((qVideo, index)=> { %>
126
+ <a href="/video/<%= qVideo.id %>"
127
+ class="queue-item <%= qVideo.id === queue.currentId ? 'active' : '' %>"
128
+ data-video-id="<%= qVideo.id %>" data-video-title="<%= qVideo.title %>">
129
+ <span class="queue-item-number">
130
+ <%= index + 1 %>
131
+ </span>
132
+ <div class="queue-item-content">
133
+ <span class="queue-item-title">
134
+ <%= qVideo.title %>
135
+ </span>
136
+ <div class="queue-item-meta">
137
+ <span class="queue-item-status status-<%= qVideo.status %>">
138
+ <% if (qVideo.status==='completed' ) { %>✓
139
+ <% } else if (qVideo.status==='in-progress' ) { %>▶
140
+ <% } else { %>○<% } %>
141
+ </span>
142
+ <% if (qVideo.id===queue.currentId) { %>
143
+ <span class="queue-item-playing">Now Playing</span>
144
+ <% } %>
145
+ </div>
146
+ </div>
147
+ </a>
148
+ <% }); %>
149
+ </div>
150
+ </aside>
151
+ </div>
111
152
  </main>
112
153
 
113
154
  <%- include('../partials/footer') %>
114
155
 
156
+ <link rel="stylesheet" href="/lib/plyr/plyr.css" />
157
+ <script src="/lib/plyr/plyr.js"></script>
115
158
  <script src="/static/js/player.js"></script>
116
159
  </body>
117
160