optimized getModule, enabled modules from different YouTube UIDs
This commit is contained in:
@@ -1,33 +1,37 @@
|
||||
<script>
|
||||
import Youtube from '@sveltecasts/svelte-youtube'
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
import Modules from './Modules.svelte'
|
||||
import YouTube from './YouTube.svelte'
|
||||
import { position, currentModule } from './stores'
|
||||
import { getModule } from './utils'
|
||||
import { kedro_modules } from './data'
|
||||
import { modules } from './data'
|
||||
|
||||
let video; let interval; let timeout;
|
||||
$: _currentModule = $currentModule || kedro_modules[0]
|
||||
let video; let interval; let timeout; let uid = modules[0].uid;
|
||||
|
||||
$: if ($currentModule) uid = $currentModule.uid
|
||||
|
||||
const positionUpdater = () => {
|
||||
interval = setInterval(() => {
|
||||
const pos = video.position()
|
||||
const newModule = getModule(pos)
|
||||
const newModule = getModule(pos, $currentModule)
|
||||
position.update(() => pos)
|
||||
if ((newModule && !$currentModule) || (newModule && $currentModule && newModule.index !==
|
||||
$currentModule.index)) {
|
||||
if ((newModule && !$currentModule) || (newModule && $currentModule && newModule.id !==
|
||||
$currentModule.id)) {
|
||||
currentModule.update(() => newModule)
|
||||
uid = newModule.uid
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
|
||||
const onSelectModule = event => {
|
||||
const { module } = event.detail
|
||||
if (module && !$currentModule || module.index !== $currentModule.index) {
|
||||
if (module && !$currentModule || module.id !== $currentModule.id) {
|
||||
clearTimeout(timeout)
|
||||
clearInterval(interval)
|
||||
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)
|
||||
video.jumpTo(module.start)
|
||||
positionUpdater()
|
||||
@@ -82,11 +86,11 @@
|
||||
|
||||
const nextModule = () => {
|
||||
if (!$currentModule) {
|
||||
return onSelectModule({detail: {module: kedro_modules[0]}})
|
||||
return onSelectModule({detail: {module: modules[0]}})
|
||||
}
|
||||
const idx = $currentModule.index
|
||||
if (idx < kedro_modules.length - 1) {
|
||||
const mod = kedro_modules[idx + 1]
|
||||
if (idx < modules.length - 1) {
|
||||
const mod = modules[idx + 1]
|
||||
onSelectModule({detail: {module: mod}})
|
||||
}
|
||||
}
|
||||
@@ -95,7 +99,7 @@
|
||||
if (!$currentModule) return
|
||||
const idx = $currentModule.index || 1
|
||||
if (idx > 0) {
|
||||
const mod = kedro_modules[idx - 1]
|
||||
const mod = modules[idx - 1]
|
||||
onSelectModule({detail: {module: mod}})
|
||||
}
|
||||
}
|
||||
@@ -106,9 +110,14 @@
|
||||
<svelte:window on:keydown={handleKeyDown} />
|
||||
|
||||
<main>
|
||||
<Youtube bind:this={video} videoId={_currentModule.uid} />
|
||||
<Modules on:repositionInModule={onRepositionInModule} on:selectModule={onSelectModule}
|
||||
modules={kedro_modules} />
|
||||
{#key uid}
|
||||
<YouTube bind:this={video} videoId={uid} />
|
||||
{/key}
|
||||
<Modules
|
||||
on:repositionInModule={onRepositionInModule}
|
||||
on:selectModule={onSelectModule}
|
||||
modules={modules}
|
||||
/>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
let selected; let progress; let klass; let progressBar
|
||||
|
||||
$: selected = $currentModule && $currentModule.index === module.index
|
||||
$: selected = $currentModule && $currentModule.id === module.id
|
||||
$: if (selected) {
|
||||
progress = getProgress($position)
|
||||
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',
|
||||
'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) {
|
||||
return module
|
||||
return module
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user