diff --git a/html/spotlight.css b/html/spotlight.css
new file mode 100644
index 00000000..19e746d5
--- /dev/null
+++ b/html/spotlight.css
@@ -0,0 +1,357 @@
+:root{
+ --primary-color:#ffffff;
+}
+#spotlight {
+ position: fixed;
+ top: -1px;
+ bottom: -1px;
+ width: 100%;
+ z-index: 99999;
+ color: #fff;
+ background-color: #000;
+ opacity: 0;
+ overflow: hidden;
+ user-select: none;
+ transition: opacity 0.2s ease-out;
+ font-family: Arial, sans-serif;
+ font-size: 16px;
+ font-weight: 400;
+ contain: strict;
+ touch-action: none;
+ pointer-events: none;
+}
+#spotlight.show {
+ opacity: 1;
+ transition: none;
+ pointer-events: auto;
+}
+#spotlight.white {
+ color: #212529;
+ background-color: #fff;
+}
+#spotlight.white .spl-spinner,
+#spotlight.white .spl-prev,
+#spotlight.white .spl-next,
+#spotlight.white .spl-page ~ * {
+ filter: invert(1);
+}
+#spotlight.white .spl-progress {
+ background-color: rgba(0, 0, 0, 0.35);
+}
+#spotlight.white .spl-header,
+#spotlight.white .spl-footer {
+ background-color: rgba(255, 255, 255, 0.65);
+}
+#spotlight.white .spl-button {
+ background: #212529;
+ color: #fff;
+}
+#spotlight .cover {
+ object-fit: cover;
+ height: 100%;
+ width: 100%;
+}
+#spotlight .contain {
+ object-fit: contain;
+ height: 100%;
+ width: 100%;
+}
+#spotlight .autofit {
+ object-fit: none;
+ width: auto;
+ height: auto;
+ max-height: none;
+ max-width: none;
+ transition: none;
+}
+.spl-track {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ contain: strict;
+}
+.spl-spinner {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 42px;
+ opacity: 0;
+}
+.spl-spinner.spin {
+ background-image: url("svg/spotlight/preloader.svg");
+ transition: opacity 0.2s linear 0.25s;
+ opacity: 1;
+}
+.spl-spinner.error {
+ background-image: url("svg/spotlight/error.svg");
+ background-size: 128px;
+ transition: none;
+ opacity: 0.5;
+}
+.spl-scene {
+ position: absolute;
+ width: 100%;
+ height: 100%;
+ transition: transform 0.65s cubic-bezier(0.1, 1, 0.1, 1);
+ contain: layout size;
+ will-change: transform;
+}
+.spl-pane > * {
+ position: absolute;
+ width: auto;
+ height: auto;
+ max-width: 100%;
+ max-height: 100%;
+ left: 50%;
+ top: 50%;
+ margin: 0;
+ padding: 0;
+ border: 0;
+ transform: translate(-50%, -50%) scale(1);
+ transition: transform 0.65s cubic-bezier(0.3, 1, 0.3, 1), opacity 0.65s ease;
+ contain: layout style;
+ will-change: transform, opacity;
+ visibility: hidden;
+}
+.spl-pane {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ transition: transform 0.65s cubic-bezier(0.3, 1, 0.3, 1);
+ contain: layout size;
+ will-change: transform, contents;
+}
+.spl-pane.hide img {
+ display:none !important;
+}
+.spl-header {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: 50px;
+ text-align: right;
+ background-color: rgba(0, 0, 0, 0.45);
+ transform: translateY(-100px);
+ transition: transform 0.35s ease;
+ overflow: hidden;
+ will-change: transform;
+}
+#spotlight.menu .spl-header,
+.spl-header:hover {
+ transform: translateY(0);
+}
+.spl-header div {
+ display: inline-block;
+ vertical-align: middle;
+ white-space: nowrap;
+ width: 50px;
+ height: 50px;
+ opacity: 0.5;
+}
+.spl-progress {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ height: 3px;
+ background-color: rgba(255, 255, 255, 0.45);
+ transform: translateX(-100%);
+ transition: transform linear;
+}
+.spl-footer {
+ position: absolute;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background-color: rgba(0, 0, 0, 0.45);
+ line-height: 20px;
+ padding: 20px 20px 0 20px;
+ padding-bottom: env(safe-area-inset-bottom, 0);
+ text-align: left;
+ font-size: 15px;
+ font-weight: 400;
+ transform: translateY(100%);
+ transition: transform 0.35s ease;
+ will-change: transform;
+}
+#spotlight.menu .spl-footer,
+.spl-footer:hover {
+ transform: translateY(0);
+}
+.spl-title {
+ font-size: 22px;
+ margin-bottom: 20px;
+}
+.spl-description {
+ margin-bottom: 20px;
+}
+.spl-button {
+ display: inline-block;
+ background: #fff;
+ color: #000;
+ border-radius: 5px;
+ padding: 10px 20px;
+ margin-bottom: 20px;
+ cursor: pointer;
+}
+.spl-page {
+ float: left;
+ width: auto;
+ line-height: 50px;
+}
+.spl-page ~ * {
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 21px;
+ float: right;
+}
+.spl-fullscreen {
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/fullscreen-line.svg") no-repeat 50% 50%;
+ mask: url("svg/fullscreen-line.svg") no-repeat 50% 50%;
+}
+.spl-fullscreen.on {
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/fullscreen-exit-line.svg") no-repeat 50% 50%;
+ mask: url("svg/fullscreen-exit-line.svg") no-repeat 50% 50%;
+}
+.spl-autofit {
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/aspect-ratio-line.svg") no-repeat 50% 50%;
+ mask: url("svg/aspect-ratio-line.svg") no-repeat 50% 50%;
+}
+.spl-zoom-out {
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/zoom-out-line.svg") no-repeat 50% 50%;
+ mask: url("svg/zoom-out-line.svg") no-repeat 50% 50%;
+ background-size: 22px;
+}
+.spl-zoom-in {
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/zoom-in-line.svg") no-repeat 50% 50%;
+ mask: url("svg/zoom-in-line.svg") no-repeat 50% 50%;
+ background-size: 22px;
+}
+.spl-download {
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/file-download-line.svg") no-repeat 50% 50%;
+ mask: url("svg/file-download-line.svg") no-repeat 50% 50%;
+ background-size: 20px;
+}
+.spl-theme {
+ background-image: url("svg/spotlight/theme.svg");
+}
+.spl-play {
+ background-image: url("svg/spotlight/play.svg");
+}
+.spl-play.on {
+ background-image: url("svg/spotlight/pause.svg");
+ animation: pulsate 1s ease infinite;
+}
+.spl-close {
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/close-line.svg") no-repeat 50% 50%;
+ mask: url("svg/close-line.svg") no-repeat 50% 50%;
+}
+.spl-like{
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/heart-line.svg") no-repeat 50% 50%;
+ mask: url("svg/heart-line.svg") no-repeat 50% 50%;
+ background-size: 22px;
+}
+.spl-like.on{
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/heart-fill.svg") no-repeat 50% 50%;
+ mask: url("svg/heart-fill.svg") no-repeat 50% 50%;
+}
+.spl-tile{
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/grid-line.svg") no-repeat 50% 50%;
+ mask: url("svg/grid-line.svg") no-repeat 50% 50%;
+ background-size: 22px;
+}
+.spl-tile.on{
+ background-color:var(--primary-color);
+ -webkit-mask: url("svg/grid-fill.svg") no-repeat 50% 50%;
+ mask: url("svg/grid-fill.svg") no-repeat 50% 50%;
+}
+
+.spl-prev,
+.spl-next {
+ position: absolute;
+ top: 50%;
+ left: 20px;
+ width: 50px;
+ height: 50px;
+ opacity: 0.65;
+ background-color: rgba(0, 0, 0, 0.45);
+ border-radius: 100%;
+ cursor: pointer;
+ margin-top: -25px;
+ transform: translateX(-100px);
+ transition: transform 0.35s ease;
+ background-image: url("svg/spotlight/arrow.svg");
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 30px;
+ will-change: transform;
+}
+.spl-next {
+ left: auto;
+ right: 20px;
+ transform: translateX(100px) scaleX(-1);
+}
+#spotlight.menu .spl-prev {
+ transform: translateX(0);
+}
+#spotlight.menu .spl-next {
+ transform: translateX(0) scaleX(-1);
+}
+@media (hover: hover) {
+ .spl-page ~ div {
+ cursor: pointer;
+ transition: opacity 0.2s ease;
+ }
+ .spl-page ~ div:hover,
+ .spl-prev:hover,
+ .spl-next:hover {
+ opacity: 1;
+ }
+}
+@media (max-width: 500px) {
+ .spl-header div {
+ width: 44px;
+ }
+ .spl-footer .spl-title {
+ font-size: 20px;
+ }
+ .spl-footer {
+ font-size: 14px;
+ }
+ .spl-prev,
+ .spl-next {
+ width: 35px;
+ height: 35px;
+ margin-top: -17.5px;
+ background-size: 15px 15px;
+ }
+ .spl-spinner {
+ background-size: 30px 30px;
+ }
+}
+.hide-scrollbars {
+ overflow: hidden !important;
+}
+@keyframes pulsate {
+ 0% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0.2;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
\ No newline at end of file
diff --git a/html/svg/aspect-ratio-line.svg b/html/svg/aspect-ratio-line.svg
new file mode 100644
index 00000000..855f9938
--- /dev/null
+++ b/html/svg/aspect-ratio-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/html/svg/download-line.svg b/html/svg/download-line.svg
new file mode 100644
index 00000000..1d40a4fd
--- /dev/null
+++ b/html/svg/download-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/html/svg/file-download-line.svg b/html/svg/file-download-line.svg
new file mode 100644
index 00000000..935f2ebe
--- /dev/null
+++ b/html/svg/file-download-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/html/svg/fullscreen-exit-line.svg b/html/svg/fullscreen-exit-line.svg
new file mode 100644
index 00000000..d3482777
--- /dev/null
+++ b/html/svg/fullscreen-exit-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/html/svg/fullscreen-line.svg b/html/svg/fullscreen-line.svg
new file mode 100644
index 00000000..573526cb
--- /dev/null
+++ b/html/svg/fullscreen-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/html/svg/grid-line.svg b/html/svg/grid-line.svg
new file mode 100644
index 00000000..0050582b
--- /dev/null
+++ b/html/svg/grid-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/html/svg/heart-fill.svg b/html/svg/heart-fill.svg
new file mode 100644
index 00000000..91e44eea
--- /dev/null
+++ b/html/svg/heart-fill.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/html/svg/heart-line.svg b/html/svg/heart-line.svg
new file mode 100644
index 00000000..8591aeaf
--- /dev/null
+++ b/html/svg/heart-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/html/svg/zoom-in-line.svg b/html/svg/zoom-in-line.svg
new file mode 100644
index 00000000..48a29cd8
--- /dev/null
+++ b/html/svg/zoom-in-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/html/svg/zoom-out-line.svg b/html/svg/zoom-out-line.svg
new file mode 100644
index 00000000..d85c8f20
--- /dev/null
+++ b/html/svg/zoom-out-line.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/javascript/generationParams.js b/javascript/generationParams.js
index 95f05093..545e81c0 100644
--- a/javascript/generationParams.js
+++ b/javascript/generationParams.js
@@ -8,10 +8,12 @@ onUiUpdate(function(){
if (!img2img_gallery) {
img2img_gallery = attachGalleryListeners("img2img")
}
+ /*
if (!modal) {
modal = gradioApp().getElementById('lightboxModal')
modalObserver.observe(modal, { attributes : true, attributeFilter : ['style'] });
}
+ */
});
let modalObserver = new MutationObserver(function(mutations) {
diff --git a/javascript/imageviewer.js b/javascript/imageviewer.js
index 28e748b7..f9a70d8f 100644
--- a/javascript/imageviewer.js
+++ b/javascript/imageviewer.js
@@ -1,4 +1,5 @@
// A full size 'lightbox' preview modal shown when left clicking on gallery previews
+/*
function closeModal() {
gradioApp().getElementById("lightboxModal").style.display = "none";
}
@@ -283,3 +284,122 @@ document.addEventListener("DOMContentLoaded", function() {
document.body.appendChild(modalFragment);
});
+*/
+
+//called from progressbar
+function showGalleryImage() {
+ //need to clean up the old code
+}
+
+let like;
+let tile;
+let slide = 0;
+let gallery = [];
+let fullImg_src;
+
+function tile_handler(event) {
+
+ const current_tile_state = !gallery[slide].tile;
+ gallery[slide].tile = current_tile_state;
+ this.classList.toggle("on");
+
+ const spl_img = document.querySelector("#spotlight .spl-pane img");
+ const spl_pane = spl_img.parentElement;
+
+ if(current_tile_state){
+ spl_pane.classList.add("hide");
+ spl_pane.style.setProperty('background-image', `url(${spl_img.src})`);
+ spl_pane.style.setProperty('background-position', "center");
+ } else {
+ spl_pane.classList.remove("hide");
+ spl_pane.style.setProperty('background-image', 'none');
+ Spotlight.autofit(true);
+ }
+}
+
+function like_handler(event){
+
+ const current_like_state = !gallery[slide].like;
+ gallery[slide].like = current_like_state;
+ this.classList.toggle("on");
+
+ if(current_like_state){
+ // add to favorites ...
+ }
+ else{
+ // remove from favorites ...
+ }
+}
+function createGallerySpotlight(src) {
+
+ slide = 0;
+ gallery = [];
+
+ gradioApp().querySelectorAll('.grid img.w-full.object-contain').forEach(function (elem, i){
+ elem.setAttribute("gal-id", i);
+ if(src == elem.src) slide = (i+1);
+ gallery[i] = {
+ src: elem.src,
+ like: false,
+ tile:false
+ }
+ })
+
+ const options = {
+
+ class: "sd-gallery",
+ index: slide,
+ //control: ["like","page","theme","fullscreen","autofit","zoom-in","zoom-out","close","download","play","prev","next"],
+ control: ["tile","like","page","fullscreen","autofit","zoom-in","zoom-out","close","download","prev","next"],
+ //animation: animation,
+ //onshow: function(index){
+ //like = Spotlight.addControl("like", handler);
+ //},
+ onchange: function(index, options){
+ slide = index - 1;
+ like.classList.toggle("on", gallery[slide].like);
+ tile.classList.toggle("on", gallery[slide].tile);
+ },
+ onclose: function(index){
+ //Spotlight.removeControl("like");
+ gradioApp().querySelector('.grid .gallery-item:nth-child('+(slide+1)+')').click();
+ }
+ };
+
+ //assign(options, modifier);
+ Spotlight.show(gallery, options);
+}
+
+
+function fullImg_click_handler(e){
+ e.stopPropagation();
+ e.preventDefault();
+ createGallerySpotlight(fullImg_src);
+}
+
+onUiUpdate(function() {
+
+ const fullImg_preview = gradioApp().querySelector('.modify-upload + img.w-full.object-contain');
+ if(opts.js_modal_lightbox && fullImg_preview ) {
+ //console.log("GALLERY UPDATED");
+ fullImg_src = fullImg_preview.src;
+ fullImg_preview.removeEventListener('click', fullImg_click_handler );
+ fullImg_preview.addEventListener('click', fullImg_click_handler, true );//bubbling phase
+ }
+})
+
+document.addEventListener("DOMContentLoaded", function() {
+
+ const head = document.head;
+ const link = document.createElement("link");
+
+ link.type = "text/css";
+ link.rel = "stylesheet";
+ link.href = "file=html/spotlight.css";
+ head.appendChild(link);
+
+ Spotlight.init();
+ like = Spotlight.addControl("like", like_handler);
+ tile = Spotlight.addControl("tile", tile_handler);
+
+});
\ No newline at end of file
diff --git a/javascript/spotlight.js b/javascript/spotlight.js
new file mode 100644
index 00000000..2d662ab6
--- /dev/null
+++ b/javascript/spotlight.js
@@ -0,0 +1,27 @@
+/**
+ * Spotlight.js v0.7.8
+ * Copyright 2019-2021 Nextapps GmbH
+ * Author: Thomas Wilkerling
+ * Licence: Apache-2.0
+ * https://github.com/nextapps-de/spotlight
+ */
+(function(){'use strict';Object.assign||(Object.assign=function(a,b){for(var c=Object.keys(b),e=0,f;e";var fa={},ha=document.createElement("video");function ia(a,b,c,e){if("node"!==e)for(var f=Object.keys(c),A=0,w;A.5*(0>a?1:a?-1:0)?cb():bb())}function W(a,b){("boolean"===typeof a?a:!R)===!R&&(R=R?clearTimeout(R):1,d(Ua,"on",R),b||sb(R))}function sb(a){ua&&(ba(O,function(){g(O,"transition-duration","");g(O,"transform","")}),a&&(g(O,"transition-duration",Fa+"s"),g(O,"transform","translateX(0)")));a&&(R=setTimeout(gb,1E3*Fa))}function X(){za&&(Wa=Date.now()+2950,S||(d(p,"menu",!0),Cb(3E3)))}
+function Cb(a){S=setTimeout(function(){var b=Date.now();b>=Wa?(d(p,"menu"),S=0):Cb(Wa-b)},a)}function Db(a){"boolean"===typeof a&&(S=a?S:0);S?(S=clearTimeout(S),d(p,"menu")):X()}function ib(a){ca(a,!0);qa=!0;ra=!1;var b=a.touches;b&&(b=b[0])&&(a=b);sa=oa*v<=u;la=a.pageX;ma=a.pageY;m(L)}function kb(a){ca(a);if(qa){if(ra){if(sa&&ra){var b=(a=r<-(u/7)&&(zu/7&&(1b?r=b:r<-b&&(r=-b),pa*v>na&&(b=(pa*v-na)/2,t-=ma-(ma=a.pageY),t>b?t=b:t<-b&&(t=-b)));ra=!0;Z(r,t)}else X()}function ab(a){var b=wb();if("boolean"!==typeof a||a!==!!b)if(b)document[Xa]();else p[T]()}function db(a){"string"!==typeof a&&(a=y?"":Aa||"white");y!==a&&(y&&d(p,y),a&&d(p,a,!0),y=a)}
+function V(a){"boolean"===typeof a&&(x=!a);x=1===v&&!x;d(N,"autofit",x);g(N,"transform","");v=1;t=r=0;ub();m(L);Z()}function bb(){var a=v/.65;50>=a&&(x&&V(),r/=.65,t/=.65,Z(r,t),Eb(a))}function cb(){var a=.65*v;x&&V();1<=a&&(1===a?r=t=0:(r*=.65,t*=.65),Z(r,t),Eb(a))}function Eb(a){v=a||1;qb()}function eb(){var a=K,b=document.createElement("a"),c=N.src;b.href=c;b.download=c.substring(c.lastIndexOf("/")+1);a.appendChild(b);b.click();a.removeChild(b)}
+function $a(a){setTimeout(function(){K.removeChild(p);L=N=P=D=E=C=va=wa=xa=Da=null},200);d(K,"hide-scrollbars");d(p,"show");ab(!1);ob();history.go(!0===a?-1:-2);Q&&(Ja.src="");R&&W();N&&vb(N);S&&(S=clearTimeout(S));y&&db();I&&d(p,I);xa&&xa()}function vb(a){if(a.g)a.g.appendChild(a),a.g=null;else{var b=a.parentNode;b&&b.removeChild(a);a.src=a.onerror=""}}function fb(a){a&&X();if(1z;z=a;nb(b);return!0}}
+function Gb(a){var b=C[z-1],c=b;D={};E&&Object.assign(D,E);Object.assign(D,c.dataset||c);ta=D.media;Da=D.onclick;Aa=D.theme;I=D["class"];za=Y("autohide",!0);G=Y("infinite");ua=Y("progress",!0);H=Y("autoslide");Ba=Y("preload",!0);Ca=D.buttonHref;Fa=H&&parseFloat(H)||7;y||Aa&&db(Aa);I&&d(p,I,!0);I&&ba(p);if(c=D.control){c="string"===typeof c?c.split(","):c;for(var e=0;e