From fff17f4fe7d0e1ed18f851599f00315b63c75b71 Mon Sep 17 00:00:00 2001 From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com> Date: Fri, 12 Jan 2024 20:28:02 -0500 Subject: [PATCH 1/4] potential janky solution --- src/controllers/lessons.js | 3 ++- src/views/lesson.pug | 12 +++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/controllers/lessons.js b/src/controllers/lessons.js index f37ab42..58dab40 100644 --- a/src/controllers/lessons.js +++ b/src/controllers/lessons.js @@ -122,6 +122,7 @@ export const getLessonProgress = async (userId, lesson) => { export const showLesson = async (req, res) => { try { + const timeStart = req.query.t || 0; let lesson = await Lesson.findOne({ permalink: req.params.permalink, }).lean(); @@ -148,7 +149,7 @@ export const showLesson = async (req, res) => { assigned = await getHwProgress(req.user.id, assigned); if (due.length) due = await getHwProgress(req.user.id, due); } - res.render("lesson", { lesson, next, prev, assigned, due }); + res.render("lesson", { lesson, next, prev, assigned, due, timeStart }); } catch (err) { console.log(err); res.redirect("/class/all"); diff --git a/src/views/lesson.pug b/src/views/lesson.pug index 25bb9bc..e3ccd67 100644 --- a/src/views/lesson.pug +++ b/src/views/lesson.pug @@ -8,6 +8,7 @@ block variables - active = "Classes" - const watched = lesson.watched ? "checked" : "" - const formattedDates = lesson.dates.map(date => date.toLocaleDateString('en-US', {day: "numeric", month: "short", year: "numeric"})).join(' / ') + //- - const timeStart = lesson && lesson.timeStart ? lesson.timeStart : 0 block content if !loggedIn @@ -84,24 +85,33 @@ block content .mb-6(class="shadow-[0_2px_10px_0_rgba(0,0,0,0.1)]") +homework(homework) + if timeStart + p#timeStart.hidden #{timeStart || 0} + append scripts if loggedIn script(src="/js/hwDone.js") script(src="/js/hwProgress.js") script(src="/js/lessonProgress.js") - if lesson.videoId && !lesson.twitchVideo + script. var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); var player; + const timeStart = document.getElementById('timeStart')?.innerText || 0; function onYouTubeIframeAPIReady() { player = new YT.Player('player', { videoId: '#{lesson.videoId}' === 'o3IIobN4xR0' ? 'YRemMgGfbKg' : '#{lesson.videoId}', + playerVars: { + start: timeStart + }, }); } + + //- function setCurrentTime(slideNum) { //- var object = [ 0, 320 ]; //- player.seekTo(object[slideNum]); From b0649b17bcab624e72ca25a83f43561c66ebec4d Mon Sep 17 00:00:00 2001 From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com> Date: Fri, 12 Jan 2024 21:10:37 -0500 Subject: [PATCH 2/4] Update lesson.pug --- src/views/lesson.pug | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/views/lesson.pug b/src/views/lesson.pug index e3ccd67..e74deec 100644 --- a/src/views/lesson.pug +++ b/src/views/lesson.pug @@ -106,12 +106,12 @@ append scripts player = new YT.Player('player', { videoId: '#{lesson.videoId}' === 'o3IIobN4xR0' ? 'YRemMgGfbKg' : '#{lesson.videoId}', playerVars: { + // this unfortunately doesn't work if the user is logged in and has 'youtube history' turned on start: timeStart }, + }); } - - //- function setCurrentTime(slideNum) { //- var object = [ 0, 320 ]; //- player.seekTo(object[slideNum]); From 5a59142bc1d31511e59dfde88978f6b83fd3261f Mon Sep 17 00:00:00 2001 From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com> Date: Fri, 12 Jan 2024 22:09:01 -0500 Subject: [PATCH 3/4] add copy link button --- src/assets/js/copyLink.js | 28 ++++++++++++++++++++++++++++ src/views/lesson.pug | 21 +++++++++++++++------ 2 files changed, 43 insertions(+), 6 deletions(-) create mode 100644 src/assets/js/copyLink.js diff --git a/src/assets/js/copyLink.js b/src/assets/js/copyLink.js new file mode 100644 index 0000000..8b3168e --- /dev/null +++ b/src/assets/js/copyLink.js @@ -0,0 +1,28 @@ +const copyBtn = document.getElementById("copyLink"); + +copyBtn.addEventListener("click", async () => { + try{ + + const timestamp = Math.floor(player.playerInfo.currentTime) || 0; + const url = window.location.href; + let link = url; + if (!url.includes("?")) { + link += `?t=${timestamp}`; + } else if (url.includes("t=")) { + link = url.replace(/t=\d+/, `t=${timestamp}`); + } else { + // this is for the case where there are other query strings + link += `&t=${timestamp}`; + } + await navigator.clipboard.writeText(link); + copyBtn.innerHTML = "Copied!"; + + // reset button text after 3 seconds + setTimeout(() => { + copyBtn.innerHTML = "Copy link at current time"; + }, 2000); + }catch(err){ + console.error('Failed to copy: ', err); + } + +}); diff --git a/src/views/lesson.pug b/src/views/lesson.pug index e74deec..be8a4b4 100644 --- a/src/views/lesson.pug +++ b/src/views/lesson.pug @@ -8,7 +8,6 @@ block variables - active = "Classes" - const watched = lesson.watched ? "checked" : "" - const formattedDates = lesson.dates.map(date => date.toLocaleDateString('en-US', {day: "numeric", month: "short", year: "numeric"})).join(' / ') - //- - const timeStart = lesson && lesson.timeStart ? lesson.timeStart : 0 block content if !loggedIn @@ -45,6 +44,9 @@ block content if next h3 a(href="/class/" + next) Next Class + button#copyLink.hidden.p-2.border.bg-pink-800.text-white.text-xs.font-medium.mt-4.rounded-md Copy link at current time + + #info if loggedIn if lesson.videoId @@ -89,6 +91,7 @@ block content p#timeStart.hidden #{timeStart || 0} append scripts + script(src="/js/copyLink.js") if loggedIn script(src="/js/hwDone.js") script(src="/js/hwProgress.js") @@ -107,15 +110,21 @@ append scripts videoId: '#{lesson.videoId}' === 'o3IIobN4xR0' ? 'YRemMgGfbKg' : '#{lesson.videoId}', playerVars: { // this unfortunately doesn't work if the user is logged in and has 'youtube history' turned on + // see https://stackoverflow.com/questions/77691282/youtube-iframe-api-start-time-not-working-when-youtube-history-is-enabled for possible workaround (not implemented yet) start: timeStart - }, + }, + events: { + 'onReady': onPlayerReady, + } }); + + + } + function onPlayerReady(event) { + // this will lazy load the button + document.getElementById('copyLink').classList.remove('hidden'); } - //- function setCurrentTime(slideNum) { - //- var object = [ 0, 320 ]; - //- player.seekTo(object[slideNum]); - //- } else if lesson.twitchVideo script(src="https://player.twitch.tv/js/embed/v1.js") From e2b59e8de4490af0f3d90849e380fbdf66da29f5 Mon Sep 17 00:00:00 2001 From: Mario Nikhil Pereira <45009203+nmpereira@users.noreply.github.com> Date: Fri, 12 Jan 2024 23:40:11 -0500 Subject: [PATCH 4/4] fixed issue with variable scoping --- src/views/lesson.pug | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/views/lesson.pug b/src/views/lesson.pug index be8a4b4..f291015 100644 --- a/src/views/lesson.pug +++ b/src/views/lesson.pug @@ -87,8 +87,7 @@ block content .mb-6(class="shadow-[0_2px_10px_0_rgba(0,0,0,0.1)]") +homework(homework) - if timeStart - p#timeStart.hidden #{timeStart || 0} + append scripts script(src="/js/copyLink.js") @@ -96,6 +95,9 @@ append scripts script(src="/js/hwDone.js") script(src="/js/hwProgress.js") script(src="/js/lessonProgress.js") + + script. + const timeStart = #{timeStart} || 0; if lesson.videoId && !lesson.twitchVideo script. @@ -104,7 +106,6 @@ append scripts var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); var player; - const timeStart = document.getElementById('timeStart')?.innerText || 0; function onYouTubeIframeAPIReady() { player = new YT.Player('player', { videoId: '#{lesson.videoId}' === 'o3IIobN4xR0' ? 'YRemMgGfbKg' : '#{lesson.videoId}',