optimized getModule, enabled modules from different YouTube UIDs

This commit is contained in:
2020-10-04 16:17:03 +02:00
parent ee48486b38
commit 95c5205303
5 changed files with 170 additions and 22 deletions

View File

@@ -1,33 +1,37 @@
<script> <script>
import Youtube from '@sveltecasts/svelte-youtube'
import { onMount } from 'svelte'; import { onMount } from 'svelte';
import Modules from './Modules.svelte' import Modules from './Modules.svelte'
import YouTube from './YouTube.svelte'
import { position, currentModule } from './stores' import { position, currentModule } from './stores'
import { getModule } from './utils' import { getModule } from './utils'
import { kedro_modules } from './data' import { modules } from './data'
let video; let interval; let timeout; let video; let interval; let timeout; let uid = modules[0].uid;
$: _currentModule = $currentModule || kedro_modules[0]
$: if ($currentModule) uid = $currentModule.uid
const positionUpdater = () => { const positionUpdater = () => {
interval = setInterval(() => { interval = setInterval(() => {
const pos = video.position() const pos = video.position()
const newModule = getModule(pos) const newModule = getModule(pos, $currentModule)
position.update(() => pos) position.update(() => pos)
if ((newModule && !$currentModule) || (newModule && $currentModule && newModule.index !== if ((newModule && !$currentModule) || (newModule && $currentModule && newModule.id !==
$currentModule.index)) { $currentModule.id)) {
currentModule.update(() => newModule) currentModule.update(() => newModule)
uid = newModule.uid
} }
}, 100) }, 100)
} }
const onSelectModule = event => { const onSelectModule = event => {
const { module } = event.detail const { module } = event.detail
if (module && !$currentModule || module.index !== $currentModule.index) { if (module && !$currentModule || module.id !== $currentModule.id) {
clearTimeout(timeout) clearTimeout(timeout)
clearInterval(interval) clearInterval(interval)
currentModule.update(() => module) currentModule.update(() => module)
// TODO: make it change the uid successfully on the iframe!
// possibly it's simplest to create a new iframe whenever you switch modules
position.update(() => module.start) position.update(() => module.start)
video.jumpTo(module.start) video.jumpTo(module.start)
positionUpdater() positionUpdater()
@@ -82,11 +86,11 @@
const nextModule = () => { const nextModule = () => {
if (!$currentModule) { if (!$currentModule) {
return onSelectModule({detail: {module: kedro_modules[0]}}) return onSelectModule({detail: {module: modules[0]}})
} }
const idx = $currentModule.index const idx = $currentModule.index
if (idx < kedro_modules.length - 1) { if (idx < modules.length - 1) {
const mod = kedro_modules[idx + 1] const mod = modules[idx + 1]
onSelectModule({detail: {module: mod}}) onSelectModule({detail: {module: mod}})
} }
} }
@@ -95,7 +99,7 @@
if (!$currentModule) return if (!$currentModule) return
const idx = $currentModule.index || 1 const idx = $currentModule.index || 1
if (idx > 0) { if (idx > 0) {
const mod = kedro_modules[idx - 1] const mod = modules[idx - 1]
onSelectModule({detail: {module: mod}}) onSelectModule({detail: {module: mod}})
} }
} }
@@ -106,9 +110,14 @@
<svelte:window on:keydown={handleKeyDown} /> <svelte:window on:keydown={handleKeyDown} />
<main> <main>
<Youtube bind:this={video} videoId={_currentModule.uid} /> {#key uid}
<Modules on:repositionInModule={onRepositionInModule} on:selectModule={onSelectModule} <YouTube bind:this={video} videoId={uid} />
modules={kedro_modules} /> {/key}
<Modules
on:repositionInModule={onRepositionInModule}
on:selectModule={onSelectModule}
modules={modules}
/>
</main> </main>
<style> <style>

View File

@@ -10,7 +10,7 @@
let selected; let progress; let klass; let progressBar let selected; let progress; let klass; let progressBar
$: selected = $currentModule && $currentModule.index === module.index $: selected = $currentModule && $currentModule.id === module.id
$: if (selected) { $: if (selected) {
progress = getProgress($position) progress = getProgress($position)
klass = "current" klass = "current"

View File

@@ -0,0 +1,81 @@
<script context="module">
let YouTubeIframeAPIReady = false
</script>
<script>
import { onMount, createEventDispatcher } from "svelte"
const dispatch = createEventDispatcher()
let divId = `player_${parseInt(Math.random() * 100000).toString()}`
export let videoId; export let height = "390"; export let width = "640"
let player;
onMount(() => {
const ytTagUrl = "https://www.youtube.com/iframe_api";
if (!isMyScriptLoaded(ytTagUrl)) {
// 2. This code loads the IFrame Player API code asynchronously.
const tag = document.createElement("script");
tag.src = ytTagUrl;
var firstScriptTag = document.getElementsByTagName("script")[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}
window.onYouTubeIframeAPIReady = function() {
//console.log('hello')
window.dispatchEvent(new Event("YouTubeIframeAPIReady"));
};
window.addEventListener("YouTubeIframeAPIReady", function() {
if (YouTubeIframeAPIReady == false) {
// first load of an YT Video on this project
YouTubeIframeAPIReady = true; // now the Player can be created
createPlayer();
}
});
function onPlayerStateChange({ data }) {
dispatch("StateChange", data);
}
function createPlayer() {
player = new YT.Player(divId, {
height,
width,
videoId,
events: {
//'onReady': onPlayerReady,
onStateChange: onPlayerStateChange
}
});
}
if (YouTubeIframeAPIReady) {
createPlayer(); // if the YT Script is ready, we can create our player
}
});
function isMyScriptLoaded(url = "") {
var scripts = document.getElementsByTagName("script");
for (var i = scripts.length; i--; ) {
if (scripts[i].src == url) return true;
}
return false;
}
export function position() { return player.getCurrentTime() }
export function play() { player.playVideo() }
export function jumpTo(seconds) { player.seekTo(seconds) }
export function pause() { player.pauseVideo() }
export function paused() { return [5, 2, -1].includes(player.getPlayerState()) }
export function buffering() { return player.getPlayerState() === 3 }
export function state() { return player.getPlayerState() }
</script>
<span class="yt-component" style="float: left">
<div id={divId} />
</span>
<style>
.yt-component {
box-shadow: 15px 15px #111;
}
</style>

View File

@@ -1,6 +1,17 @@
const enrichObjects = (platform, uid, objects) => objects.map((object, index) => ({...{index, duration: object.end - object.start, uid, platform}, ...object})) const enrichObjects = (platform, uid, objects, startingIndex = 0) => objects.map((object, index) => (
{...{
index: index + startingIndex,
duration: object.end - object.start,
uid,
platform,
id: `${uid}-${object.start}`,
isLast: index === objects.length - 1
},
...object}
)
)
export const kedro_modules = enrichObjects( const kedro_modules = enrichObjects(
'YouTube', 'YouTube',
'ZPxuohy5SoU', 'ZPxuohy5SoU',
[ [
@@ -56,3 +67,38 @@ export const kedro_modules = enrichObjects(
}, },
] ]
) )
const airflow_modules = enrichObjects(
'YouTube',
'AHMm1wfGuHE',
[
{
start: 0,
end: 17,
outcome: 'skip this part',
},
{
start: 17,
end: 388,
outcome: 'know what Airflow is',
},
{
start: 388,
end: 674,
outcome: 'see a demo of Airflow',
},
{
start: 674,
end: 852,
outcome: 'know what makes Airflow great',
},
{
start: 852,
end: 983,
outcome: 'know where Airflow fits into the hierarchy of data science',
},
],
kedro_modules.length,
)
export const modules = kedro_modules.concat(airflow_modules)

View File

@@ -1,9 +1,21 @@
import { kedro_modules } from './data' import { modules } from './data'
export const getModule = (position, currentModule) => {
if (position < currentModule.end) {
return currentModule
}
for (const module of modules) {
if (module.index < currentModule.index) {
continue
}
if (currentModule.index - module.index > 1) {
continue
}
export const getModule = position => {
for (const module of kedro_modules) {
if (position > module.start && position < module.end) { if (position > module.start && position < module.end) {
return module return module
} }
} }
} }