optimized getModule, enabled modules from different YouTube UIDs
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
81
modulearn/src/YouTube.svelte
Normal file
81
modulearn/src/YouTube.svelte
Normal 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>
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user