diff options
author | Andinus <andinus@nand.sh> | 2022-06-11 11:58:29 +0530 |
---|---|---|
committer | Andinus <andinus@nand.sh> | 2022-06-11 11:58:29 +0530 |
commit | 89c60aee5a602ed5bfd73a9d5bcbbf9945aac44f (patch) | |
tree | c734a88fc77c56faa6b68edfde3484f8859e9b73 | |
parent | bef200b4669f058ce43ec9c0a3583de7fac558e3 (diff) | |
download | crater-89c60aee5a602ed5bfd73a9d5bcbbf9945aac44f.tar.gz |
Scope css, improve image error handling, show progress bar
- Errors are shown if some images fail to load. - Progress bar is shown while images are loading. - .pack is called after all images have been loaded.
-rw-r--r-- | resources/css/style.css | 12 | ||||
-rw-r--r-- | resources/js/gallery.js | 96 | ||||
-rw-r--r-- | templates/gallery.crotmp | 8 | ||||
-rw-r--r-- | templates/login.crotmp | 2 |
4 files changed, 81 insertions, 37 deletions
diff --git a/resources/css/style.css b/resources/css/style.css index a380707..76af98e 100644 --- a/resources/css/style.css +++ b/resources/css/style.css @@ -47,7 +47,7 @@ img { var(--fg-inactive) 0px 0px 0px 1px inset; } -input, .alert { +#login-form input, .alert { color: var(--fg-main); background-color: var(--bg-main); border: 1px var(--bg-active) solid; @@ -109,3 +109,13 @@ img, .text { width: 400px; } .alert { background-color: var(--red-subtle-bg); } +#loading-progress, #loading-error { margin-bottom: 2em; } +#loading-error { display: none; } +#loading-error button { + float: right; + color: var(--fg-main); + background-color: var(--bg-main); + border: 1px var(--bg-active) solid; + padding: 0.25em 1em; +} +#loading-progress { width: 100%; } diff --git a/resources/js/gallery.js b/resources/js/gallery.js index bab4d1d..2a608f5 100644 --- a/resources/js/gallery.js +++ b/resources/js/gallery.js @@ -1,68 +1,94 @@ 'use strict'; +const round = Math.round; + // image width. const imgW = 400; // Gallery using bricks.js //////////////////////////////////////////////////// -// mq - the minimum viewport width (String CSS unit: em, px, rem) -// columns - the number of vertical columns -// gutter - the space (in px) between the columns and grid items const sizes = [ { columns: 1, gutter: 30 }, - { mq: Math.round((imgW * 2.2) + 40) + "px", columns: 2, gutter: 35 }, - { mq: Math.round((imgW * 3.5) + 50) + "px", columns: 3, gutter: 50 }, - { mq: Math.round((imgW * 4.4) + 50) + "px", columns: 4, gutter: 50 }, + { mq: round((imgW * 2.2) + 40) + "px", columns: 2, gutter: 35 }, + { mq: round((imgW * 3.5) + 50) + "px", columns: 3, gutter: 50 }, + { mq: round((imgW * 4.4) + 50) + "px", columns: 4, gutter: 50 }, ]; -const instance = Bricks({ +const bricks = Bricks({ container: '#gallery', packed: 'data-packed', sizes: sizes }); -instance +bricks .on('pack', () => console.log('ALL grid items packed.')) .on('update', () => console.log('NEW grid items packed.')) .on('resize', size => console.log( 'The grid has be re-packed to accommodate a new BREAKPOINT.', size )); -// start it up, when the DOM is ready. note that if images are in the -// grid, you may need to wait for document.readyState === 'complete'. document.addEventListener('DOMContentLoaded', event => { - instance.resize(true).pack(); // bind resize handler & pack initial items -}); -document.addEventListener('readystatechange', event => { - if (event.target.readyState === 'complete') { - instance.pack(); - } + bricks.resize(true); // bind resize handler }); -// Re-packing after loading images //////////////////////////////////////////// +// Packing after loading images //////////////////////////////////////////// + +const onImagesLoaded = (container, event) => { + const images = container.getElementsByTagName("img"); + const progressBar = document.getElementById("loading-progress"); + + // failed keeps track of images that failed to load. + let failed = 0; + let remaining = images.length; -function onImagesLoaded(container, event) { - let images = container.getElementsByTagName("img"); - let loaded = images.length; for (let i = 0; i < images.length; i++) { - if (images[i].complete) { - loaded--; - } + if (images[i].complete) + remaining--; else { + // Add listeners to images that have to be loaded. images[i].addEventListener("load", function () { - loaded--; - if (loaded == 0) { - event(); - } + remaining--; + progressBar.value = round( + ((images.length - remaining) / images.length) * 100 + ); + if (remaining === failed) + event(remaining, failed, progressBar); }); + + // If loading fails then we increment failed, an error + // will be shown later. + images[i].addEventListener("error", function () { + failed++; + if (remaining === failed) + event(remaining, failed, progressBar); + }); + } - if (loaded == 0) { - event(); - } + if (remaining == failed) + event(remaining, failed, progressBar); } -} +}; -const container = document.getElementById("gallery"); -onImagesLoaded(container, function () { - instance.pack(); -}); +const gallery = document.getElementById("gallery"); +const imagesLoaded = (remaining, failed, progressBar) => { + bricks.pack(); + + progressBar.value = 100; + document.getElementById("loading").style.display = "none"; + + // Show error on failure. + const loadError = document.getElementById("loading-error"); + const loadErrorText = document.getElementById("loading-error-text"); + const loadErrorDismiss = document.getElementById("loading-error-dismiss"); + if (failed !== 0) { + loadError.style.display = "block"; + const t = failed === 1 ? "image" : "images"; + loadErrorText.innerHTML = `${failed} ${t} failed to load.`; + + loadErrorDismiss.addEventListener('click', function(){ + loadError.style.display = "none"; + }); + } +}; + +onImagesLoaded(gallery, imagesLoaded); diff --git a/templates/gallery.crotmp b/templates/gallery.crotmp index 6afef0a..6aead73 100644 --- a/templates/gallery.crotmp +++ b/templates/gallery.crotmp @@ -1,5 +1,13 @@ <:use 'templates/base.crotmp'> <|page(.title)> + <div id="loading"> + <label for="loading-progress">Loading Images:</label> + <progress id="loading-progress" max="100" value="0"></progress> + </div> + <div id="loading-error" class="alert" role="alert"> + <span id="loading-error-text"></span> + <button id="loading-error-dismiss">Dismiss</button> + </div> <div id="gallery"> <@gallery : $i> <?{ $i.<type> eq 'img' }> diff --git a/templates/login.crotmp b/templates/login.crotmp index 343f768..9a7acd4 100644 --- a/templates/login.crotmp +++ b/templates/login.crotmp @@ -1,6 +1,6 @@ <:use 'templates/base.crotmp'> <|page('Log In')> - <form method="post" action="/login"> + <form id="login-form" method="post" action="/login"> <?.error> <div class="alert" role="alert"> <.error> |