Initial styling of production lessons.

This commit is contained in:
2018-09-13 18:10:02 +02:00
parent a40eb5d6e4
commit 9fd233a8dc
2 changed files with 93 additions and 71 deletions

View File

@@ -6,103 +6,119 @@
const LOAD_INITIAL_COUNT = 5; const LOAD_INITIAL_COUNT = 5;
const LOAD_NEXT_COUNT = 3; const LOAD_NEXT_COUNT = 3;
/* Renders a node as a <li> element, returns a jQuery object. */ /* Renders a node as an asset card, returns a jQuery object. */
function renderAsset(node) { function renderAsset(node) {
let li = $('<li>').addClass('js-tagged-asset'); let card = $('<a class="card asset card-image-fade pr-0 mx-0 mb-2">')
let link = $('<a>') .addClass('js-tagged-asset')
.attr('href', '/nodes/' + node._id + '/redir') .attr('href', '/nodes/' + node._id + '/redir')
.appendTo(li); .attr('title', node.name);
let thumbnail_container = $('<div class="embed-responsive embed-responsive-16by9">');
function warnNoPicture() { function warnNoPicture() {
li.addClass('warning'); let card_icon = $('<div class="card-img-top card-icon embed-responsive-item">');
link.text('no picture for node ' + node._id); card_icon.html('<i class="pi-' + node.node_type + '">');
thumbnail_container.append(card_icon);
} }
if (!node.picture) { if (!node.picture) {
warnNoPicture(); warnNoPicture();
return li; } else {
// TODO: show 'loading' thingy
$.get('/api/files/' + node.picture)
.fail(function(error) {
let msg = xhrErrorResponseMessage(error);
console.log(msg);
})
.done(function(resp) {
// Render the picture if it has the proper size.
var show_variation = null;
if (typeof resp.variations != 'undefined') {
for (variation of resp.variations) {
if (variation.size != 'm') continue;
show_variation = variation;
break;
}
}
if (show_variation == null) {
warnNoPicture();
return;
}
let img = $('<img class="card-img-top embed-responsive-item">')
.attr('alt', node.name)
.attr('src', variation.link)
.attr('width', variation.width)
.attr('height', variation.height);
thumbnail_container.append(img);
});
} }
// TODO: show 'loading' thingy card.append(thumbnail_container);
$.get('/api/files/' + node.picture)
.fail(function(error) {
let msg = xhrErrorResponseMessage(error);
li.addClass('error').text(msg);
})
.done(function(resp) {
// Render the picture if it has the proper size.
var show_variation = null;
if (typeof resp.variations != 'undefined') {
for (variation of resp.variations) {
if (variation.size != 'm') continue;
show_variation = variation;
break;
}
}
if (show_variation == null) { /* Card body for title and meta info. */
warnNoPicture(); let card_body = $('<div class="card-body py-2 d-flex flex-column">');
return; let card_title = $('<div class="card-title mb-1 font-weight-bold">');
} card_title.text(node.name);
card_body.append(card_title);
let img = $('<img>') card.append(card_body);
.attr('alt', node.name)
.attr('src', variation.link)
.attr('width', variation.width)
.attr('height', variation.height);
link.append(img);
});
return li; /* 'Free' ribbon for public assets. */
if (node.permissions && node.permissions.world){
card.addClass('free');
}
return card;
} }
function loadNext(ul_element) { function loadNext(card_deck_element) {
let $ul = $(ul_element); let $card_deck = $(card_deck_element);
let tagged_assets = ul_element.tagged_assets; // Stored here by loadTaggedAssets(). let tagged_assets = card_deck_element.tagged_assets; // Stored here by loadTaggedAssets().
let already_loaded = $ul.find('li.js-tagged-asset').length; let already_loaded = $card_deck.find('a.js-tagged-asset').length;
let load_next = $ul.find('li.js-load-next'); let load_next = $card_deck.find('a.js-load-next');
let nodes_to_load = tagged_assets.slice(already_loaded, already_loaded + LOAD_NEXT_COUNT); let nodes_to_load = tagged_assets.slice(already_loaded, already_loaded + LOAD_NEXT_COUNT);
for (node of nodes_to_load) { for (node of nodes_to_load) {
let li = renderAsset(node); let link = renderAsset(node);
load_next.before(li); load_next.before(link);
} }
if (already_loaded + LOAD_NEXT_COUNT >= tagged_assets.length) if (already_loaded + LOAD_NEXT_COUNT >= tagged_assets.length)
load_next.remove(); load_next.remove();
} }
$.fn.loadTaggedAssets = function(api_base_url) { $.fn.loadTaggedAssets = function() {
this.each(function(index, ul_element) { this.each(function(index, card_deck_element) {
// TODO(Sybren): show a 'loading' animation. // TODO(Sybren): show a 'loading' animation.
$.get('/api/nodes/tagged/' + ul_element.dataset.assetTag) $.get('/api/nodes/tagged/' + card_deck_element.dataset.assetTag)
.fail(function(error) { .fail(function(error) {
let msg = xhrErrorResponseMessage(error); let msg = xhrErrorResponseMessage(error);
$('<li>').addClass('error').text(msg).appendTo(ul_element); $('<a>').addClass('bg-danger').text(msg).appendTo(card_deck_element);
}) })
.done(function(resp) { .done(function(resp) {
// 'resp' is a list of node documents. // 'resp' is a list of node documents.
// Store the response on the DOM <ul>-element so that we can later render more. // Store the response on the DOM card_deck_element so that we can later render more.
ul_element.tagged_assets = resp; card_deck_element.tagged_assets = resp;
// Here render the first N. // Here render the first N.
for (node of resp.slice(0, LOAD_INITIAL_COUNT)) { for (node of resp.slice(0, LOAD_INITIAL_COUNT)) {
let li = renderAsset(node); let li = renderAsset(node);
li.appendTo(ul_element); li.appendTo(card_deck_element);
} }
// Don't bother with a 'load next' link if there is no more. // Don't bother with a 'load next' link if there is no more.
if (resp.length <= LOAD_INITIAL_COUNT) return; if (resp.length <= LOAD_INITIAL_COUNT) return;
// Construct the 'load next' link. // Construct the 'load next' link.
let load_next = $('<li>').addClass('js-load-next');
let link = $('<a>') let link = $('<a>')
.addClass('js-load-next')
.attr('href', 'javascript:void(0);') .attr('href', 'javascript:void(0);')
.click(function() { loadNext(ul_element); return false; }) .click(function() { loadNext(card_deck_element); return false; })
.text('Load next') .text('Load next');
.appendTo(load_next); link.appendTo(card_deck_element);
load_next.appendTo(ul_element);
}); });
}); });
}; };

View File

@@ -1,13 +1,13 @@
| {% extends 'layout.html' %} | {% extends 'layout.html' %}
| {% block page_title %}Production of Stuff{% endblock %} | {% block page_title %}Production Lessons{% endblock %}
| {% set page_header_text = "Here are our hand-selected assets 'bout stuff." %} | {% set page_header_text = "Tips and tricks by the Open Movie crew." %}
| {% block head %} | {% block head %}
script(src="{{ url_for('static_cloud', filename='assets/js/tagged_assets.min.js') }}") script(src="{{ url_for('static_cloud', filename='assets/js/tagged_assets.min.js') }}")
script. script.
$(function() { $(function() {
$('ul.js-asset-list').loadTaggedAssets(); $('.js-asset-list').loadTaggedAssets();
}) })
| {% endblock %} | {% endblock %}
| {% block body %} | {% block body %}
@@ -20,22 +20,28 @@ script.
hr.pb-2 hr.pb-2
h3 Animation section.py-3.my-3.border-bottom
ul.js-asset-list(data-asset-tag="animation") h3 Animation
.card-deck.card-padless.card-deck-responsive.list-unstyled(
class="js-asset-list",
data-asset-tag="animation")
h3 Modeling section.py-3.my-3.border-bottom
ul.js-asset-list(data-asset-tag="modelling") h3 Modeling
.card-deck.card-padless.card-deck-responsive.list-unstyled(
class="js-asset-list",
data-asset-tag="modelling")
h3 Rigging section.py-3.my-3.border-bottom
ul.js-asset-list(data-asset-tag="rigging") h3 Rigging
.card-deck.card-padless.card-deck-responsive.list-unstyled(
class="js-asset-list",
data-asset-tag="rigging")
h3 Pipeline section.py-3.my-3
ul.js-asset-list(data-asset-tag="pipeline") h3 Pipeline
.card-deck.card-padless.card-deck-responsive.list-unstyled(
h3 Look-dev class="js-asset-list",
ul.js-asset-list(data-asset-tag="lookdev") data-asset-tag="pipeline")
h3 Crazyspace
ul.js-asset-list(data-asset-tag="crazyspace")
| {% endblock body%} | {% endblock body%}