Skip to content

Commit

Permalink
Merge pull request #24 from ao5357/8_YouTube
Browse files Browse the repository at this point in the history
Closes #8 by adding a YouTube component and support structure
  • Loading branch information
ao5357 authored Dec 21, 2020
2 parents c2c6f3f + 33b93ce commit 82fa108
Show file tree
Hide file tree
Showing 18 changed files with 295 additions and 2 deletions.
41 changes: 41 additions & 0 deletions .scripts/youtube-thumbnails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @file
* Load local versions of YouTube thumbnails for performance.
*/

'use strict';

const fs = require('fs');
const request = require('request');

/**
* Download a file and save it to a filesystem path.
*
* @param url
* @param path
* @param callback
*/
const download = (url, path, callback) => {
request.head(url, (err, res, body) => {
request(url)
.pipe(fs.createWriteStream(path))
.on('close', callback);
});
};

/* Get the data feed containing cached lists of videos. */
let rawdata = fs.readFileSync('_data/youtube.json');
let videos = JSON.parse(rawdata);

console.log(videos);

/* Go through each video and save down a thumbnail. */
Array.prototype.forEach.call(videos, (video) => {
const ytimg = 'https://i3.ytimg.com/vi/' + video.id + '/0.jpg';
const path = 'assets/images/youtube/' + video.id + '.jpg';
const cback = () => { console.log('Another thumbnail saved.'); };

if (!fs.existsSync(path)) {
download(ytimg, path, cback);
}
});
12 changes: 12 additions & 0 deletions _data/image-metadata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,15 @@ images:
- path: 'undraw_welcome_3gvl.png'
height: 891
width: 1108
- path: 'youtube/jNQXAC9IVRw.jpg.webp'
height: 360
width: 480
- path: 'youtube/wM3MnO3H8jE.jpg'
height: 360
width: 480
- path: 'youtube/wM3MnO3H8jE.jpg.webp'
height: 360
width: 480
- path: 'youtube/jNQXAC9IVRw.jpg'
height: 360
width: 480
10 changes: 10 additions & 0 deletions _data/youtube.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"id": "jNQXAC9IVRw",
"title": "Me at the zoo"
},
{
"id": "wM3MnO3H8jE",
"title": "Opening Mandarin Orange Cup w/ Minimal Spillage"
}
]
94 changes: 94 additions & 0 deletions _includes/molecules/youtube.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{% capture component %}
{% assign meta = site.data.youtube | where: "id", include.id | first %}
<figure class="figure figure--youtube js--youtube include include--molecule include--molecule--youtube
{% if include.classes %}{{ include.classes }}{% endif %}"
data-youtube="{{ include.id }}" {% if meta %}data-title="{{ meta.title }}"{% endif %}
>
<a href="https://www.youtube.com/watch?v={{ include.id }}">
<picture class="picture picture--lazy-load layout--hide--no-javascript" itemprop="image">
{% comment %}<!-- Get image information and metadata. -->{% endcomment %}
{% capture jpg_path %}/assets/images/youtube/{{ include.id }}.jpg{% endcapture %}
{% capture src %}youtube/{{ include.id }}.jpg{% endcapture %}
{% assign jpg_version = site.static_files | where: "path", jpg_path | first %}
{% assign height = site.data.image-metadata.images | where: "path", src | first %}

{% comment %}<!-- Set alt text for the video. -->{% endcomment %}
{% assign jpg_version = site.static_files | where: "path", jpg_path | first %}
{% assign alt = "YouTube video thumbnail" %}
{% if meta %}
{% capture alt %}{{ meta.title }}{% endcapture %}
{% endif %}

{% comment %}<!-- Pick a local or remote thumbnail image for default. -->{% endcomment %}
{% capture img_src %}https://i3.ytimg.com/vi/{{ include.id }}/0.jpg{% endcapture %}
{% if jpg_version %}
{% capture img_src %}{{ site.subpath }}/assets/images/{{ src }}{% endcapture %}
{% endif %}

{% comment %}<!-- Support webp if available. -->{% endcomment %}
{% capture webp_path %}/assets/images/youtube/{{ include.id }}.jpg.webp{% endcapture %}
{% assign webp_version = site.static_files | where: "path", webp_path | first %}
{% if webp_version %}
<source srcset="{{ site.subpath }}/assets/images/required/s.webp"
data-srcset="{{ webp_version.path | relative_url }}" type="image/webp" />
{% endif %}

<img src="{{ site.subpath }}/assets/images/required/s.gif"
data-src="{{ img_src }}" alt="{{ alt }}" loading="lazy"
{%if height %}height="{{ height.height }}"{% endif %}
{%if height %}width="{{ height.width }}"{% endif %}
/>
</picture>
<noscript>
<img src="{{ img_src }}" alt="{{ alt }}" loading="lazy" />
</noscript>
</a>
{% if include.caption %}
<figcaption class="figcaption figure--youtube--figcaption position--relative z-index--1">{{ include.caption }}</figcaption>
{% endif %}
</figure>
{% endcapture %}

{% capture name %}YouTube{% endcapture %}

{% capture liquid %}{% raw %}
{% include molecules/youtube.html
classes=""
caption="The very first YouTube video"
id="jNQXAC9IVRw"
%}
{% endraw %}{% endcapture %}

{% capture usage %}
#### General guidance

YouTube videos can really slow down the page load, so using this component is a helper for performance. It loads only the
thumbnail image until you interact with it, and which point the whole video loads.
{% endcapture %}

{% capture accessibility %}
Just some sample text in the accessibility section for now.
{% endcapture %}

{% capture props %}
caption| optional text to describe the video| The very first YouTube video,
classes| css classes applied to parent| color--main-dark,
id| The string of letters and numbers in a YouTube URL after the v| jNQXAC9IVRw
{% endcapture %}

{% assign classes = "background-color--main-light, font-size--2em" | split: ", " %}

{% if include.mode == "docblock" %}
{% include molecules/docblock.html
accessibility=accessibility
classes=classes
html=component
liquid=liquid
name=name
props=props
source=include
usage=usage
%}
{% else %}
{{ component }}
{% endif %}
2 changes: 1 addition & 1 deletion assets/css/pre-commit-dependency.css

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions assets/css/theme/theme--classes.css
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,42 @@
text-decoration: none;
}

/**
* YouTube embeds, faked to look like iframes as much as possible.
*/
.include--molecule--youtube {
position: relative;
}
.include--molecule--youtube::before {
background-image: linear-gradient(rgba(0, 0, 0, 0.75) 0%, transparent 100%);
color: var(--color--white);
content: attr(data-title);
cursor: pointer;
display: block;
left: 0;
padding: calc(2 * var(--spacing--single));
position: absolute;
right: 0;
text-shadow: var(--text-shadow--default);
top: 0;
z-index: 2;
}
.include--molecule--youtube::after {
background-image: url("../images/in-css/youtube.svg");
background-repeat: no-repeat;
background-size: contain;
bottom: calc(50% - calc(3.4 * var(--spacing--single)));
content: "";
cursor: pointer;
display: block;
padding: calc(3.4 * var(--spacing--single));
position: absolute;
right: calc(50% - calc(3.4 * var(--spacing--single)));
}
.include--molecule--youtube:hover::after {
background-color: #f00;
}

/**
* Dismissible elements.
*/
Expand Down
1 change: 1 addition & 0 deletions assets/images/in-css/youtube.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/youtube/jNQXAC9IVRw.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/youtube/jNQXAC9IVRw.jpg.avif
Binary file not shown.
Binary file added assets/images/youtube/jNQXAC9IVRw.jpg.webp
Binary file not shown.
Binary file added assets/images/youtube/wM3MnO3H8jE.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added assets/images/youtube/wM3MnO3H8jE.jpg.avif
Binary file not shown.
Binary file added assets/images/youtube/wM3MnO3H8jE.jpg.webp
Binary file not shown.
1 change: 1 addition & 0 deletions assets/js/behavior.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ if ("serviceWorker" in navigator) {
{% include_relative partials/js--dismissible.js %}
{% include_relative partials/js--share-to-native.js %}
{% include_relative partials/js--toggle-below.js %}
{% include_relative partials/js--youtube.js %}
{% include_relative partials/twitter-tweet.js %}

/* Partials that might be source-order dependent. */
Expand Down
47 changes: 47 additions & 0 deletions assets/js/partials/js--youtube.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* @file
* Initialize and handle behaviors for YouTube molecule components.
*
* Uses the DOM initializer pattern in partials/utility--initializer.js
*/

var youtubeInitializationFunction = function (initType) {
console.log({
message: "YouTube video initialized",
element: this,
});
};
utilityInitializer("js--youtube", "youtubeInitializationFunction");

/**
* Convert a template string into HTML DOM nodes
* @param {String} str The template string
* @return {Node} The template HTML
*/
var stringToHTML = function (str) {
var parser = new DOMParser();
var doc = parser.parseFromString(str, "text/html");
return doc.body;
};

/* Use event delegation for any dynamically-added dismiss events. */
document.addEventListener(
"click",
function (event) {
if (event.target !== document && event.target.closest(".js--youtube")) {
event.preventDefault();
let thisVid = event.target.closest(".js--youtube");

/* The part where we replace the whole thing with an iframe is here. */
const vidId = thisVid.dataset["youtube"];
const vidIframe = `<iframe width="960" height="480"
src="https://www.youtube.com/embed/${vidId}" frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen=""></iframe>`;
const iframeNode = stringToHTML(vidIframe);

thisVid.parentNode.replaceChild(iframeNode, thisVid);
}
},
false
);
Loading

0 comments on commit 82fa108

Please sign in to comment.