From 372c75c36d5f30a9a4aebc926cae739a50ab8698 Mon Sep 17 00:00:00 2001 From: Nishant Karandikar Date: Mon, 17 Apr 2017 16:49:10 -0700 Subject: [PATCH 1/5] Fix in-video quiz question misalignment when video isn't first component If a video isn't the first component in the unit, the in-video-quiz questions appear incorrectly positioned on the page. We reposition the questions to properly cover the video while it's paused. --- invideoquiz/public/js/src/invideoquiz.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/invideoquiz/public/js/src/invideoquiz.js b/invideoquiz/public/js/src/invideoquiz.js index 68f1443..c8bc74b 100644 --- a/invideoquiz/public/js/src/invideoquiz.js +++ b/invideoquiz/public/js/src/invideoquiz.js @@ -61,6 +61,13 @@ function InVideoQuizXBlock(runtime, element) { } }); } + + function resizeInVideoProblem(currentProblem, currentVideo) { + var videoPosition = $('.tc-wrapper', currentVideo).position().top; + var videoHeight = $('.tc-wrapper', currentVideo).css('height'); + var videoWidth = $('.tc-wrapper', currentVideo).css('width'); + currentProblem.css({top: videoPosition, height: videoHeight, width: videoWidth}); + } // Bind In Video Quiz display to video time, as well as play and pause buttons function bindVideoEvents() { @@ -87,6 +94,7 @@ function InVideoQuizXBlock(runtime, element) { if (isProblemToDisplay) { problemToDisplay = $('.xblock-student_view', this) videoState.videoPlayer.pause(); + resizeInVideoProblem(problemToDisplay, video); problemToDisplay.show(); canDisplayProblem = false; } From 477af42a44e23819a0f093e9aaa1eddd65ea8a38 Mon Sep 17 00:00:00 2001 From: Nishant Karandikar Date: Mon, 1 May 2017 15:36:44 -0700 Subject: [PATCH 2/5] Fix issue with in-video quiz problem display css property Previously, questions would sometimes fail to display in the in-video quiz xblocks. This was likely due to the "display" css property not changing from "none" to "block" for the problem component. This would also trigger issues with the videoState variable as well. --- invideoquiz/public/js/src/invideoquiz.js | 1 + 1 file changed, 1 insertion(+) diff --git a/invideoquiz/public/js/src/invideoquiz.js b/invideoquiz/public/js/src/invideoquiz.js index c8bc74b..eb6348f 100644 --- a/invideoquiz/public/js/src/invideoquiz.js +++ b/invideoquiz/public/js/src/invideoquiz.js @@ -96,6 +96,7 @@ function InVideoQuizXBlock(runtime, element) { videoState.videoPlayer.pause(); resizeInVideoProblem(problemToDisplay, video); problemToDisplay.show(); + problemToDisplay.css({display: 'block'}); canDisplayProblem = false; } }); From 1fbb911e7afe3e2e492818dad98fe69e600f869d Mon Sep 17 00:00:00 2001 From: Nishant Karandikar Date: Tue, 2 May 2017 11:49:24 -0700 Subject: [PATCH 3/5] Fix in-video-quiz questions not resizing when video is resized Previously, if the video transitioned from fullscreen to regular size with a question open, or if the window was resized with a question open, the question would not resize properly (the position, height, and/or width would be incorrect). This commit checks for changes to the video dimensions every 100ms when a question is open, and resizes the question if a change is detected. --- invideoquiz/public/js/src/invideoquiz.js | 53 +++++++++++++++++++++--- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/invideoquiz/public/js/src/invideoquiz.js b/invideoquiz/public/js/src/invideoquiz.js index eb6348f..4c181ac 100644 --- a/invideoquiz/public/js/src/invideoquiz.js +++ b/invideoquiz/public/js/src/invideoquiz.js @@ -11,6 +11,12 @@ function InVideoQuizXBlock(runtime, element) { var video; var videoState; + var knownVideoDimensions; + + // Interval at which to check if video size has changed size + // and the displayed problems needs to do the same + var resizeIntervalTime = 100; + // Interval at which to check for problems to display // Checking every 0.5 seconds to make sure we check at least once per actual second of video var intervalTime = 500; @@ -31,6 +37,7 @@ function InVideoQuizXBlock(runtime, element) { }); if (studentMode) { + knownVideoDimensions = getVideoDimensions(); bindVideoEvents(); } }); @@ -50,6 +57,25 @@ function InVideoQuizXBlock(runtime, element) { } } + function getVideoDimensions() { + videoPosition = $('.tc-wrapper', video).position().top; + videoHeight = $('.tc-wrapper', video).css('height'); + videoWidth = $('.tc-wrapper', video).css('width'); + return [videoPosition, videoHeight, videoWidth]; + } + + function videoDimensionsDiffer(newMeasurement, oldMeasurement) { + if (newMeasurement.length !== oldMeasurement.length) { + return true; + } + for (var i = 0; i < oldMeasurement.length; i++) { + if (oldMeasurement[i] !== newMeasurement[i]) { + return true; + } + } + return false; + } + function showProblemTimesToInstructor(component) { $.each(problemTimesMap, function (time, componentId) { var isInVideoComponent = component.data('id').indexOf(componentId) !== -1; @@ -62,20 +88,24 @@ function InVideoQuizXBlock(runtime, element) { }); } - function resizeInVideoProblem(currentProblem, currentVideo) { - var videoPosition = $('.tc-wrapper', currentVideo).position().top; - var videoHeight = $('.tc-wrapper', currentVideo).css('height'); - var videoWidth = $('.tc-wrapper', currentVideo).css('width'); - currentProblem.css({top: videoPosition, height: videoHeight, width: videoWidth}); + function resizeInVideoProblem(currentProblem, videoDimensions) { + currentProblem.css({ + top: videoDimensions[0], + height: videoDimensions[1], + width: videoDimensions[2] + }); } // Bind In Video Quiz display to video time, as well as play and pause buttons function bindVideoEvents() { var canDisplayProblem = true; var intervalObject; + var resizeIntervalObject; var problemToDisplay; video.on('play', function () { + clearInterval(resizeIntervalObject); + if (problemToDisplay) { window.setTimeout(function () { canDisplayProblem = true; @@ -94,7 +124,7 @@ function InVideoQuizXBlock(runtime, element) { if (isProblemToDisplay) { problemToDisplay = $('.xblock-student_view', this) videoState.videoPlayer.pause(); - resizeInVideoProblem(problemToDisplay, video); + resizeInVideoProblem(problemToDisplay, getVideoDimensions()); problemToDisplay.show(); problemToDisplay.css({display: 'block'}); canDisplayProblem = false; @@ -107,6 +137,17 @@ function InVideoQuizXBlock(runtime, element) { video.on('pause', function () { clearInterval(intervalObject); if (problemToDisplay) { + resizeIntervalObject = setInterval(function () { + + // check if the size has changed from the previous state; if so, update + // both our known size measurements and the size of the problem + currentVideoDimensions = getVideoDimensions(); + + if (videoDimensionsDiffer(currentVideoDimensions, knownVideoDimensions)) { + resizeInVideoProblem(problemToDisplay, currentVideoDimensions); + knownVideoDimensions = currentVideoDimensions; + } + }, resizeIntervalTime); $('.in-video-continue', problemToDisplay).on('click', function () { $('.wrapper-downloads, .video-controls', video).show(); videoState.videoPlayer.play(); From 8abbbd6bb6a89f8bc8839716ea290ddfee56593c Mon Sep 17 00:00:00 2001 From: Nishant Karandikar Date: Fri, 12 May 2017 16:42:59 -0700 Subject: [PATCH 4/5] Fix stylistic issues with javascript - Rename ambiguous interval and timeout variables - Rename functions to reduce verbosity - Switch data structure for video dimension to be dictionary instead of list - Remove unnecessary comment --- invideoquiz/public/js/src/invideoquiz.js | 61 +++++++++++------------- 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/invideoquiz/public/js/src/invideoquiz.js b/invideoquiz/public/js/src/invideoquiz.js index 4c181ac..9bf6461 100644 --- a/invideoquiz/public/js/src/invideoquiz.js +++ b/invideoquiz/public/js/src/invideoquiz.js @@ -11,7 +11,7 @@ function InVideoQuizXBlock(runtime, element) { var video; var videoState; - var knownVideoDimensions; + var knownDimensions; // Interval at which to check if video size has changed size // and the displayed problems needs to do the same @@ -19,11 +19,11 @@ function InVideoQuizXBlock(runtime, element) { // Interval at which to check for problems to display // Checking every 0.5 seconds to make sure we check at least once per actual second of video - var intervalTime = 500; + var displayIntervalTime = 500; // Timeout to wait before checking for problems again after "play" is clicked // Waiting 1.5 seconds to make sure we are moved to the next second and we don't get a double firing - var intervalTimeout = 1500; + var displayIntervalTimeout = 1500; $(function () { $('#seq_content .vert-mod .vert').each(function () { @@ -37,7 +37,7 @@ function InVideoQuizXBlock(runtime, element) { }); if (studentMode) { - knownVideoDimensions = getVideoDimensions(); + knownDimensions = getDimensions(); bindVideoEvents(); } }); @@ -57,20 +57,23 @@ function InVideoQuizXBlock(runtime, element) { } } - function getVideoDimensions() { - videoPosition = $('.tc-wrapper', video).position().top; - videoHeight = $('.tc-wrapper', video).css('height'); - videoWidth = $('.tc-wrapper', video).css('width'); - return [videoPosition, videoHeight, videoWidth]; + function getDimensions() { + var position = $('.tc-wrapper', video).position().top; + var height = $('.tc-wrapper', video).css('height'); + var width = $('.tc-wrapper', video).css('width'); + return { + 'top': position, + 'height': height, + 'width': width + }; } - function videoDimensionsDiffer(newMeasurement, oldMeasurement) { - if (newMeasurement.length !== oldMeasurement.length) { - return true; - } - for (var i = 0; i < oldMeasurement.length; i++) { - if (oldMeasurement[i] !== newMeasurement[i]) { - return true; + function dimensionsHaveChanged(newDimensions) { + for (var key in knownDimensions) { + if (newDimensions.hasOwnProperty(key)) { + if (knownDimensions[key] !== newDimensions[key]) { + return true; + } } } return false; @@ -88,12 +91,8 @@ function InVideoQuizXBlock(runtime, element) { }); } - function resizeInVideoProblem(currentProblem, videoDimensions) { - currentProblem.css({ - top: videoDimensions[0], - height: videoDimensions[1], - width: videoDimensions[2] - }); + function resizeInVideoProblem(currentProblem, dimensions) { + currentProblem.css(dimensions); } // Bind In Video Quiz display to video time, as well as play and pause buttons @@ -109,7 +108,7 @@ function InVideoQuizXBlock(runtime, element) { if (problemToDisplay) { window.setTimeout(function () { canDisplayProblem = true; - }, intervalTimeout); + }, displayIntervalTimeout); problemToDisplay.hide(); problemToDisplay = null; } @@ -124,28 +123,24 @@ function InVideoQuizXBlock(runtime, element) { if (isProblemToDisplay) { problemToDisplay = $('.xblock-student_view', this) videoState.videoPlayer.pause(); - resizeInVideoProblem(problemToDisplay, getVideoDimensions()); + resizeInVideoProblem(problemToDisplay, getDimensions()); problemToDisplay.show(); problemToDisplay.css({display: 'block'}); canDisplayProblem = false; } }); } - }, intervalTime); + }, displayIntervalTime); }); video.on('pause', function () { clearInterval(intervalObject); if (problemToDisplay) { resizeIntervalObject = setInterval(function () { - - // check if the size has changed from the previous state; if so, update - // both our known size measurements and the size of the problem - currentVideoDimensions = getVideoDimensions(); - - if (videoDimensionsDiffer(currentVideoDimensions, knownVideoDimensions)) { - resizeInVideoProblem(problemToDisplay, currentVideoDimensions); - knownVideoDimensions = currentVideoDimensions; + var currentDimensions = getDimensions(); + if (dimensionsHaveChanged(currentDimensions)) { + resizeInVideoProblem(problemToDisplay, currentDimensions); + knownDimensions = currentDimensions; } }, resizeIntervalTime); $('.in-video-continue', problemToDisplay).on('click', function () { From 20d2a26888eed3314a4bedc55807f0c07529c7f4 Mon Sep 17 00:00:00 2001 From: Nishant Karandikar Date: Tue, 16 May 2017 12:26:52 -0700 Subject: [PATCH 5/5] Bump release patch version from 0.1.4 to 0.1.5 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index e40d2fa..e223404 100644 --- a/setup.py +++ b/setup.py @@ -45,7 +45,7 @@ def run_tests(self): setup( name='invideoquiz-xblock', - version='0.1.4', + version='0.1.5', description='Helper XBlock to locate CAPA problems within videos.', license='AGPL v3', packages=[