From: Vincent Vanwaelscappel Date: Thu, 26 Jun 2025 12:55:17 +0000 (+0200) Subject: wip #7600 @1.5 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=757d57bd213c2251e4c12c340fc071dd5a9ae2d8;p=fluidbook-toolbox.git wip #7600 @1.5 --- diff --git a/app/Models/ELearningMedia.php b/app/Models/ELearningMedia.php index d2adf93cc..0fdf3b962 100644 --- a/app/Models/ELearningMedia.php +++ b/app/Models/ELearningMedia.php @@ -79,8 +79,6 @@ class ELearningMedia extends ToolboxModel $this->addField('', FormSeparator::class); $this->addField('complete_button', Checkbox::class, __('Marquer terminer après un clic sur un bouton'), ['default' => false, 'when' => ['type' => 'pdf']]); $this->addField('complete_pct', Percent::class, __('Marquer terminé quand ce pourcentage est lu'), ['default' => 75, 'when' => ['complete_button' => 0, 'type' => ['logical_operator' => 'OR', 'values' => ['video', 'audio']]]]); - - } public function preSave() @@ -109,7 +107,7 @@ class ELearningMedia extends ToolboxModel /** @var Media $file */ $file = $this->getMediaInField('file')->first()->getPath(); - self::compileFromFile($file, $dest, $this->title, $organization, 'MEDIA_' . $this->id, $this->scorm_version, 75); + self::compileFromFile($file, $dest, $this->title, $organization, 'MEDIA_' . $this->id, $this->scorm_version, $this->type === 'pdf' && $this->complete_button ? "'button'" : $this->complete_pct); } /** @@ -118,7 +116,7 @@ class ELearningMedia extends ToolboxModel * @param $title string * @param $organization string * @param $reference string - * @param $complete_pct int + * @param $complete_pct int|string * @return string * @throws \Exception */ @@ -151,7 +149,7 @@ class ELearningMedia extends ToolboxModel $vdir->file_put_contents('pdfjs/web/viewer.css', $css); } $vdir->copy($file, 'media.' . $ext); - $vdir->file_put_contents('index.html', view('elearningmedia.index', ['complete_pct' => $complete_pct, 'title' => $title, 'type' => $type])); + $vdir->file_put_contents('index.html', view('elearningmedia.index', ['complete_pct' => $complete_pct,'title' => $title, 'type' => $type])); $vdir->sync(true); return $title; } diff --git a/app/Models/ElearningTranslate.php b/app/Models/ElearningTranslate.php index c37debb30..6022cb974 100644 --- a/app/Models/ElearningTranslate.php +++ b/app/Models/ElearningTranslate.php @@ -34,6 +34,7 @@ class ElearningTranslate extends ToolboxContentTranslate public function getPaths() { $res = parent::getPaths(); + $res['Elearning Media'] = 'resources/view/elearningmedia'; $res['OpenBadges'] = 'resources/badge/translate'; return $res; } diff --git a/resources/elearningmedia/js/app.js b/resources/elearningmedia/js/app.js index 6fd66aa87..8d6717636 100644 --- a/resources/elearningmedia/js/app.js +++ b/resources/elearningmedia/js/app.js @@ -7,6 +7,14 @@ window.cubeSCORM = new CubeSCORM(); window.$ = window.jQuery = $; window.openTime = Date.now(); +window.playerIframe = document.getElementById('player'); +window.playerWindow = playerIframe.contentWindow; + + +window.addEventListener("resize", function () { + resize(); +}); + document.addEventListener("DOMContentLoaded", function () { var media = document.getElementById('player'); if (media.tagName.toLowerCase() === 'audio') { @@ -31,7 +39,10 @@ document.addEventListener("DOMContentLoaded", function () { cubeSCORM.initScorm(); - var pc = (parseInt(window.progressComplete) / 100); + var pc = window.progressComplete; + if (pc !== 'button') { + pc = (parseInt(window.progressComplete) / 100); + } var interval; if (window.type === 'audio' || window.type === 'video') { interval = setInterval(function () { @@ -40,34 +51,60 @@ document.addEventListener("DOMContentLoaded", function () { } }, 1000); } else if (window.type === 'pdf') { - var playerIframe = document.getElementById('player'); + playerIframe.addEventListener('load', function () { - var playerWindow = playerIframe.contentWindow; + var interval; + if (pc === 'button') { + interval = setInterval(function () { + try { + var app = playerWindow.PDFViewerApplication; + if (app === undefined || app === null) { + return; + } + var pdfViewer = app.pdfViewer; + if (pdfViewer === undefined || pdfViewer === null) { + return; + } - var interval = setInterval(function () { - console.log('Check pdf progress'); - try { - var app = playerWindow.PDFViewerApplication; - if (app === undefined || app === null) { - return; - } - var pdfViewer = app.pdfViewer; - if (pdfViewer === undefined || pdfViewer === null) { - return; + let container = pdfViewer.container; + container.addEventListener('scroll', function () { + if (container.scrollTop / (container.scrollHeight - container.offsetHeight) > 0.95) { + resize(); + showCompleteButton(); + } + }); + clearInterval(interval); + } catch (e) { + console.error('Error while updating pdf course status'); + console.error(e); } + }, 200); + } else { + interval = setInterval(function () { + console.log('Check pdf progress'); + try { + var app = playerWindow.PDFViewerApplication; + if (app === undefined || app === null) { + return; + } + var pdfViewer = app.pdfViewer; + if (pdfViewer === undefined || pdfViewer === null) { + return; + } - var total = pdfViewer.pagesCount; - var current = pdfViewer._currentPageNumber; - if (total > 0 && current / total >= pc) { - markComplete(interval); - } + var total = pdfViewer.pagesCount; + var current = pdfViewer._currentPageNumber; + if (total > 0 && current / total >= pc) { + markComplete(interval); + } - } catch (e) { - console.error('Error while updating pdf course status'); - console.error(e); - } - }, 1000); + } catch (e) { + console.error('Error while updating pdf course status'); + console.error(e); + } + }, 1000); + } }); } @@ -76,7 +113,16 @@ document.addEventListener("DOMContentLoaded", function () { }); }); +function showCompleteButton() { + document.getElementById('completeButton').classList.add('visible') +} + function markComplete(interval) { cubeSCORM.scormMarkAsComplete(); clearInterval(interval); } + +function resize() { + let v = (playerWindow.innerWidth - playerWindow.document.querySelector('.page').getBoundingClientRect().width) / 2 + 30; + document.getElementById("completeButton").style.right = v + 'px'; +} diff --git a/resources/elearningmedia/sass/app.sass b/resources/elearningmedia/sass/app.sass index 0b1213172..d7adc616e 100644 --- a/resources/elearningmedia/sass/app.sass +++ b/resources/elearningmedia/sass/app.sass @@ -22,6 +22,30 @@ video, audio, iframe #audiobigplay display: block +#completeButton + opacity: 0 + pointer-events: none + position: absolute + display: flex + right: 30px + bottom: 30px + width: 130px + height: 130px + padding: 10px 10px 40px 10px + transition: opacity 600ms + background-image: url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iTGF5ZXJfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2ZXJzaW9uPSIxLjEiIHZpZXdCb3g9IjAgMCAxMDQgMTA0Ij4KICA8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMjkuNi4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogMi4xLjEgQnVpbGQgMjA3KSAgLS0+CiAgPGRlZnM+CiAgICA8c3R5bGU+CiAgICAgIC5zdDAgewogICAgICAgIGZpbGw6ICM3MTJjZmQ7CiAgICAgIH0KCiAgICAgIC5zdDEgewogICAgICAgIGZpbGw6ICNlNGZmMTk7CiAgICAgIH0KCiAgICAgIC5zdDIgewogICAgICAgIGZpbGw6ICMyNTBjNjY7CiAgICAgIH0KCiAgICAgIC5zdDMgewogICAgICAgIGZpbGw6ICMzMzM7CiAgICAgIH0KICAgIDwvc3R5bGU+CiAgPC9kZWZzPgogIDxjaXJjbGUgY2xhc3M9InN0MCIgY3g9IjUyIiBjeT0iNTEuOSIgcj0iNDUiLz4KICA8cGF0aCBjbGFzcz0ic3QyIiBkPSJNNTIsMTAyLjRDMjQuMiwxMDIuNCwxLjUsNzkuNywxLjUsNTEuOVMyNC4yLDEuNCw1MiwxLjRzNTAuNSwyMi42LDUwLjUsNTAuNS0yMi42LDUwLjUtNTAuNSw1MC41Wk01MiwzQzI1LDMsMy4xLDI0LjksMy4xLDUxLjlzMjEuOSw0OC45LDQ4LjksNDguOSw0OC45LTIxLjksNDguOS00OC45Uzc5LDMsNTIsM1oiLz4KICA8Zz4KICAgIDxnPgogICAgICA8cGF0aCBjbGFzcz0ic3QxIiBkPSJNODEuMyw5NS44YzAsMy44LTMsNi44LTYuOCw2LjhzLTYuOC0zLTYuOC02LjgsMy02LjgsNi44LTYuOCw2LjgsMyw2LjgsNi44Ii8+CiAgICAgIDxwYXRoIGNsYXNzPSJzdDMiIGQ9Ik03Ni44LDk5LjNoLTMuNGMwLDAtLjEsMC0uMiwwLS42LS44LTEuOS0zLjQtMi0zLjUtLjItLjMtLjItLjYsMC0uOC4yLS4yLjYtLjMuOSwwbC42LjZ2LTMuOGMwLS40LjQtLjguOC0uOHMuOC40LjguOHYxLjNoLjVjLjMsMCwuNS4xLjYuM2guNmMuMywwLC41LjIuNi40aC4zYy40LDAsMSwuNCwxLC44djEuM2MwLC40LDAsLjctLjIsMS4xbC0uOCwyLjNjMCwwLS4xLjEtLjIuMVpNNzMuNCw5OC45aDMuMmwuNy0yLjFjMC0uMy4xLS43LjEtMXYtMS4zYzAtLjItLjMtLjQtLjUtLjRoLS40Yy0uMSwwLS4yLDAtLjItLjJzLS4xLS4yLS4yLS4yaC0uN2MtLjEsMC0uMiwwLS4yLS4ycy0uMSwwLS4yLDBoLS43Yy0uMSwwLS4yLDAtLjItLjJ2LTEuNWMwLS4yLS4yLS40LS40LS40cy0uNC4yLS40LjR2NC4zYzAsMCwwLC4yLS4xLjIsMCwwLS4yLDAtLjIsMGwtLjktLjljMCwwLS4yLDAtLjMsMCwwLDAsMCwuMiwwLC4zLDAsMCwxLjMsMi41LDEuOSwzLjRaIi8+CiAgICA8L2c+CiAgICA8cGF0aCBjbGFzcz0ic3QzIiBkPSJNNzYuNSw5NC45Yy0uMSwwLS4yLDAtLjItLjJ2LS44YzAtLjEsMC0uMi4yLS4ycy4yLDAsLjIuMnYuOGMwLC4xLDAsLjItLjIuMlpNNzUuMyw5NC41Yy0uMSwwLS4yLDAtLjItLjJ2LS45YzAtLjEsMC0uMi4yLS4ycy4yLDAsLjIuMnYuOWMwLC4xLDAsLjItLjIuMlpNNzQuMSw5NC41Yy0uMSwwLS4yLDAtLjItLjJ2LTEuM2MwLS4xLDAtLjIuMi0uMnMuMiwwLC4yLjJ2MS4zYzAsLjEsMCwuMi0uMi4yWiIvPgogIDwvZz4KICA8Zz4KICAgIDxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01Ni4yLDc4LjNjLTEuNiwxLjgtMy4yLDMuNy00LjgsNS41LS4yLjItLjQuNC0uNS42LTEtLjktMi0xLjctMy0yLjYtLjItLjItLjYuMS0uNC40LDEuMS45LDIuMSwxLjgsMy4yLDIuOCwwLDAsLjMuMS40LDAsMS42LTEuOCwzLjItMy43LDQuOC01LjUuMi0uMy41LS41LjctLjguMi0uMi0uMS0uNi0uNC0uNFoiLz4KICAgIDxwYXRoIGNsYXNzPSJzdDEiIGQ9Ik01NS4zLDcyLjhjLTMuNy0xLjQtOC0uMi0xMC42LDIuOS0yLjUsMy4xLTIuOCw3LjUtLjgsMTAuOSwyLDMuNCw2LjEsNS4xLDkuOSw0LjQsMy44LS44LDYuOS0zLjksNy41LTcuOCwwLS41LjEtMSwuMS0xLjUsMC0zLjktMi41LTcuNS02LjItOC45Wk01NSw5MGMtMy41LDEuMy03LjUuMi05LjktMi43LTIuNC0yLjktMi43LTcuMS0uOC0xMC4zLDEuOS0zLjIsNS44LTQuOSw5LjQtNC4yLDMuNi43LDYuNSwzLjcsNy4xLDcuNCwwLC41LjEuOS4xLDEuNCwwLDMuNy0yLjQsNy4xLTUuOSw4LjRaIi8+CiAgPC9nPgo8L3N2Zz4=") + background-size: cover + color: #fff + text-decoration: none + align-items: center + justify-content: center + + &.visible + transition: opacity 600ms + opacity: 1 + pointer-events: all + + .plyr position: absolute top: 0 diff --git a/resources/views/elearningmedia/index.blade.php b/resources/views/elearningmedia/index.blade.php index 27e725996..22a63b83a 100644 --- a/resources/views/elearningmedia/index.blade.php +++ b/resources/views/elearningmedia/index.blade.php @@ -7,12 +7,14 @@ {{$title}} @if($type==='pdf') + {{ __('Click here once you have completed your learning session') }} @elseif($type==='audio')