diff --git a/assets/js/main.js b/assets/js/main.js index f3da5a3..a6bc30f 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -394,34 +394,43 @@ // Download-Button (direkt gebunden, nicht delegiert) $toolbar.on('click', '#sel-download', function() { if (selectedImages.length === 0) return; - $.ajax({ - url: '/api/download/selected', - type: 'POST', - contentType: 'application/json', - data: JSON.stringify({ images: selectedImages }), - xhrFields: { responseType: 'blob' }, - success: function(data, status, xhr) { - var ct = xhr.getResponseHeader('Content-Type'); - if (ct && ct.indexOf('application/json') !== -1) { - var reader = new FileReader(); - reader.onload = function() { - var resp = JSON.parse(this.result); - if (resp.mode === 'individual') { - resp.urls.forEach(function(url, i) { - setTimeout(function() { - var a = document.createElement('a'); - a.href = url; - a.download = ''; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - }, i * 300); - }); - } - }; - reader.readAsText(data); - } else { - var url = window.URL.createObjectURL(data); + var payload = JSON.stringify({ images: selectedImages }); + + if (selectedImages.length <= 3) { + // 1-3 Bilder: normales AJAX, Server gibt JSON mit URLs + $.ajax({ + url: '/api/download/selected', + type: 'POST', + contentType: 'application/json', + data: payload, + success: function(resp) { + if (resp.mode === 'individual') { + resp.urls.forEach(function(url, i) { + setTimeout(function() { + var a = document.createElement('a'); + a.href = url; + a.download = url.split('/').pop(); + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + }, i * 500); + }); + } + }, + error: function(xhr) { + var msg = (xhr.responseJSON && xhr.responseJSON.error) || 'Download fehlgeschlagen'; + alert(msg); + } + }); + } else { + // 4+ Bilder: Blob-Download fuer ZIP + var xhr = new XMLHttpRequest(); + xhr.open('POST', '/api/download/selected', true); + xhr.setRequestHeader('Content-Type', 'application/json'); + xhr.responseType = 'blob'; + xhr.onload = function() { + if (xhr.status === 200) { + var url = window.URL.createObjectURL(xhr.response); var a = document.createElement('a'); a.href = url; a.download = 'mischkomposition-auswahl.zip'; @@ -429,12 +438,25 @@ a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); + } else { + // Fehler-Blob als Text lesen + var reader = new FileReader(); + reader.onload = function() { + try { + var resp = JSON.parse(this.result); + alert(resp.error || 'Download fehlgeschlagen'); + } catch(e) { + alert('Download fehlgeschlagen (Status ' + xhr.status + ')'); + } + }; + reader.readAsText(xhr.response); } - }, - error: function(xhr) { - alert(xhr.responseJSON ? xhr.responseJSON.error : 'Download fehlgeschlagen'); - } - }); + }; + xhr.onerror = function() { + alert('Netzwerkfehler beim Download'); + }; + xhr.send(payload); + } }); // Abbrechen-Button (direkt gebunden) diff --git a/assets/js/main.min.js b/assets/js/main.min.js index 1864e7a..1d77919 100644 --- a/assets/js/main.min.js +++ b/assets/js/main.min.js @@ -1 +1 @@ -!function(e){var n,o=e(window),a=e("body");e("#wrapper");(breakpoints({xlarge:["1281px","1680px"],large:["981px","1280px"],medium:["737px","980px"],small:["481px","736px"],xsmall:[null,"480px"]}),"ie"==browser.name&&a.addClass("ie"),browser.mobile&&a.addClass("touch"),browser.canUse("transition"))&&(o.on("load",function(){window.setTimeout(function(){a.removeClass("is-preload")},100)}),o.on("resize",function(){window.clearTimeout(n),a.addClass("is-resizing"),n=window.setTimeout(function(){a.removeClass("is-resizing")},100)}));o.scrollTop(0);var t=e(".panel");t.each(function(){var n=e(this),o=e('[href="#'+n.attr("id")+'"]');e('
').appendTo(n).on("click",function(e){n.trigger("---hide")}),n.on("click",function(e){e.stopPropagation()}).on("---toggle",function(){n.hasClass("active")?n.triggerHandler("---hide"):n.triggerHandler("---show")}).on("---show",function(){a.hasClass("content-active")&&t.trigger("---hide"),n.addClass("active"),o.addClass("active"),a.addClass("content-active")}).on("---hide",function(){n.removeClass("active"),o.removeClass("active"),a.removeClass("content-active")}),o.removeAttr("href").css("cursor","pointer").on("click",function(e){e.preventDefault(),e.stopPropagation(),n.trigger("---toggle")})}),a.on("click",function(e){a.hasClass("content-active")&&(e.preventDefault(),e.stopPropagation(),t.trigger("---hide"))}),o.on("keyup",function(e){27==e.keyCode&&a.hasClass("content-active")&&(e.preventDefault(),e.stopPropagation(),t.trigger("---hide"))}),e("#header").find("a").each(function(){var n=e(this),o=n.attr("href");o&&"#"!=o.charAt(0)&&n.removeAttr("href").css("cursor","pointer").on("click",function(e){e.preventDefault(),e.stopPropagation(),window.location.href=o})}),e("#footer").find(".copyright").each(function(){var n=e(this),o=n.parent(),a=o.parent().children().last();breakpoints.on("<=medium",function(){n.appendTo(a)}),breakpoints.on(">medium",function(){n.appendTo(o)})});var i=e("#main"),r={},l=["jpg","jpeg","png","gif","webp"];function s(n){var o=e("#main").data("exif"),a="";for(var t in o){var i=o[t],r=EXIF.getTag(n,i.tag);void 0!==r&&(a+=' '+r+"  ")}return a}e.ajax({url:"/images/fulls/",dataType:"json",cache:!1,success:function(n){if(0!==n.length){var o=n.filter(function(e){if("file"!==e.type)return!1;var n=e.name.split(".").pop().toLowerCase();return-1!==l.indexOf(n)});0!==o.length?(o.sort(function(e,n){return e.name.localeCompare(n.name)}),o.forEach(function(n){var o=e('
');o.attr("data-name",n.name),n.folder&&o.attr("data-folder",n.folder);var a=n.folder?encodeURIComponent(n.folder)+"/":"",t="/images/fulls/"+a+encodeURIComponent(n.name),r="/images/thumbs/"+a+encodeURIComponent(n.name),l=e(''),s=e('');l.append(s),o.append(l),i.append(o)}),i.children(".thumb").each(function(){var n,o=e(this),a=o.find(".image"),t=a.children("img");0!=a.length&&(a.css("background-image","url('"+t.attr("src")+"')"),(n=t.data("position"))&&a.css("background-position",n),t.hide(),t[0].addEventListener("error",function(){var e=a.attr("href");e&&a.css("background-image","url('"+e+"')")}),t[0].addEventListener("load",function(){EXIF.getData(t[0],function(){r[t.data("name")]=s(this)})}))}),function(n){var o=[],a=!1,t=e('
');t.html('0 ausgewaehlt'),e("body").append(t);var i=e('
  • ');e("#header nav > ul").prepend(i);var r=[];function l(){var n=o.length;e("#sel-count").text(n+" ausgewaehlt"),e("#sel-download").prop("disabled",0===n),n>3?e("#sel-download").html(' Als ZIP ('+n+")"):n>0?e("#sel-download").html(' Herunterladen ('+n+")"):e("#sel-download").html(' Herunterladen')}function s(){o=[],e(".thumb").removeClass("selected"),l()}n.forEach(function(e){e.folder&&-1===r.indexOf(e.folder)&&r.push(e.folder)}),r.length>0&&r.forEach(function(n){var o=e('
  • ');e("#header nav > ul").prepend(o)}),e(document).on("click","#select-mode-toggle",function(n){n.preventDefault(),n.stopPropagation(),a=!a,e("body").toggleClass("selection-mode",a),a||s(),t.toggleClass("visible",a)}),document.addEventListener("click",function(n){if(a){var t=n.target.closest("#main .thumb");if(t){n.preventDefault(),n.stopImmediatePropagation();for(var i=e(t),r=i.attr("data-name"),s=i.attr("data-folder")||null,d=-1,c=0;cBild Speichern ';return void 0!==o?"

    "+o+a+"

    ":"

    "+a+"

    "},fadeSpeed:300,onPopupClose:function(){a.removeClass("modal-active")},onPopupOpen:function(){a.addClass("modal-active")},overlayOpacity:0,popupCloserText:"",popupHeight:150,popupLoaderText:"",popupSpeed:300,popupWidth:150,selector:".thumb > a.image",usePopupCaption:!0,usePopupCloser:!0,usePopupDefaultStyling:!1,usePopupForceClose:!0,usePopupLoader:!0,usePopupNav:!0,windowMargin:50}),breakpoints.on("<=xsmall",function(){i[0]._poptrox.windowMargin=0}),breakpoints.on(">xsmall",function(){i[0]._poptrox.windowMargin=50})):i.html('

    Es wurden noch keine passenden Bilder für diesen Account hochgeladen oder zugewiesen.

    ')}else i.html('

    Noch keine Bilder vorhanden.

    ')},error:function(){i.html('

    Keine Bilder gefunden. Lade Bilder in deinen Nextcloud-Ordner hoch.

    ')}});var d=localStorage.getItem("mischkomposition_theme")||"main";function c(n){"light"===n?e("#theme-toggle i").removeClass("fa-sun").addClass("fa-moon"):e("#theme-toggle i").removeClass("fa-moon").addClass("fa-sun")}c(d),e("#theme-toggle").click(function(n){n.preventDefault(),d="main"===d?"light":"main",localStorage.setItem("mischkomposition_theme",d),e("#theme-style").attr("href","assets/css/"+d+".min.css"),c(d)}),e.get("/api/auth/me").done(function(n){e("#login-username, #login-password, #login-submit").hide(),e("#logout-btn").show().css("display","inline-block"),e("#pw-change-section").show(),"admin"===n.role&&e("#admin-link").html('Admin-Dashboard'),e("#login-nav").html('Account ')}),e("#login-form").submit(function(n){n.preventDefault(),e.post("/api/auth/login",{username:e("#login-username").val(),password:e("#login-password").val()}).done(function(){window.location.reload()}).fail(function(e){var n="Login fehlgeschlagen.";e.responseJSON&&"Account abgelaufen"===e.responseJSON.error&&(n="Dein Account ist abgelaufen. Bitte kontaktiere den Administrator."),alert(n)})}),e("#logout-btn").click(function(n){n.preventDefault(),e.post("/api/auth/logout").done(function(){window.location.reload()})}),e("#pw-change-form").submit(function(n){n.preventDefault();var o=e("#pw-new").val();o===e("#pw-confirm").val()?e.post("/api/auth/change-password",{old_password:e("#pw-old").val(),new_password:o}).done(function(){alert("Passwort geaendert!"),e("#pw-old, #pw-new, #pw-confirm").val("")}).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")}):alert("Passwoerter stimmen nicht ueberein.")})}(jQuery); \ No newline at end of file +!function(e){var n,o=e(window),a=e("body");e("#wrapper");(breakpoints({xlarge:["1281px","1680px"],large:["981px","1280px"],medium:["737px","980px"],small:["481px","736px"],xsmall:[null,"480px"]}),"ie"==browser.name&&a.addClass("ie"),browser.mobile&&a.addClass("touch"),browser.canUse("transition"))&&(o.on("load",function(){window.setTimeout(function(){a.removeClass("is-preload")},100)}),o.on("resize",function(){window.clearTimeout(n),a.addClass("is-resizing"),n=window.setTimeout(function(){a.removeClass("is-resizing")},100)}));o.scrollTop(0);var t=e(".panel");t.each(function(){var n=e(this),o=e('[href="#'+n.attr("id")+'"]');e('
    ').appendTo(n).on("click",function(e){n.trigger("---hide")}),n.on("click",function(e){e.stopPropagation()}).on("---toggle",function(){n.hasClass("active")?n.triggerHandler("---hide"):n.triggerHandler("---show")}).on("---show",function(){a.hasClass("content-active")&&t.trigger("---hide"),n.addClass("active"),o.addClass("active"),a.addClass("content-active")}).on("---hide",function(){n.removeClass("active"),o.removeClass("active"),a.removeClass("content-active")}),o.removeAttr("href").css("cursor","pointer").on("click",function(e){e.preventDefault(),e.stopPropagation(),n.trigger("---toggle")})}),a.on("click",function(e){a.hasClass("content-active")&&(e.preventDefault(),e.stopPropagation(),t.trigger("---hide"))}),o.on("keyup",function(e){27==e.keyCode&&a.hasClass("content-active")&&(e.preventDefault(),e.stopPropagation(),t.trigger("---hide"))}),e("#header").find("a").each(function(){var n=e(this),o=n.attr("href");o&&"#"!=o.charAt(0)&&n.removeAttr("href").css("cursor","pointer").on("click",function(e){e.preventDefault(),e.stopPropagation(),window.location.href=o})}),e("#footer").find(".copyright").each(function(){var n=e(this),o=n.parent(),a=o.parent().children().last();breakpoints.on("<=medium",function(){n.appendTo(a)}),breakpoints.on(">medium",function(){n.appendTo(o)})});var i=e("#main"),l={},r=["jpg","jpeg","png","gif","webp"];function s(n){var o=e("#main").data("exif"),a="";for(var t in o){var i=o[t],l=EXIF.getTag(n,i.tag);void 0!==l&&(a+=' '+l+"  ")}return a}e.ajax({url:"/images/fulls/",dataType:"json",cache:!1,success:function(n){if(0!==n.length){var o=n.filter(function(e){if("file"!==e.type)return!1;var n=e.name.split(".").pop().toLowerCase();return-1!==r.indexOf(n)});0!==o.length?(o.sort(function(e,n){return e.name.localeCompare(n.name)}),o.forEach(function(n){var o=e('
    ');o.attr("data-name",n.name),n.folder&&o.attr("data-folder",n.folder);var a=n.folder?encodeURIComponent(n.folder)+"/":"",t="/images/fulls/"+a+encodeURIComponent(n.name),l="/images/thumbs/"+a+encodeURIComponent(n.name),r=e(''),s=e('');r.append(s),o.append(r),i.append(o)}),i.children(".thumb").each(function(){var n,o=e(this),a=o.find(".image"),t=a.children("img");0!=a.length&&(a.css("background-image","url('"+t.attr("src")+"')"),(n=t.data("position"))&&a.css("background-position",n),t.hide(),t[0].addEventListener("error",function(){var e=a.attr("href");e&&a.css("background-image","url('"+e+"')")}),t[0].addEventListener("load",function(){EXIF.getData(t[0],function(){l[t.data("name")]=s(this)})}))}),function(n){var o=[],a=!1,t=e('
    ');t.html('0 ausgewaehlt'),e("body").append(t);var i=e('
  • ');e("#header nav > ul").prepend(i);var l=[];function r(){var n=o.length;e("#sel-count").text(n+" ausgewaehlt"),e("#sel-download").prop("disabled",0===n),n>3?e("#sel-download").html(' Als ZIP ('+n+")"):n>0?e("#sel-download").html(' Herunterladen ('+n+")"):e("#sel-download").html(' Herunterladen')}function s(){o=[],e(".thumb").removeClass("selected"),r()}n.forEach(function(e){e.folder&&-1===l.indexOf(e.folder)&&l.push(e.folder)}),l.length>0&&l.forEach(function(n){var o=e('
  • ');e("#header nav > ul").prepend(o)}),e(document).on("click","#select-mode-toggle",function(n){n.preventDefault(),n.stopPropagation(),a=!a,e("body").toggleClass("selection-mode",a),a||s(),t.toggleClass("visible",a)}),document.addEventListener("click",function(n){if(a){var t=n.target.closest("#main .thumb");if(t){n.preventDefault(),n.stopImmediatePropagation();for(var i=e(t),l=i.attr("data-name"),s=i.attr("data-folder")||null,d=-1,c=0;cBild Speichern ';return void 0!==o?"

    "+o+a+"

    ":"

    "+a+"

    "},fadeSpeed:300,onPopupClose:function(){a.removeClass("modal-active")},onPopupOpen:function(){a.addClass("modal-active")},overlayOpacity:0,popupCloserText:"",popupHeight:150,popupLoaderText:"",popupSpeed:300,popupWidth:150,selector:".thumb > a.image",usePopupCaption:!0,usePopupCloser:!0,usePopupDefaultStyling:!1,usePopupForceClose:!0,usePopupLoader:!0,usePopupNav:!0,windowMargin:50}),breakpoints.on("<=xsmall",function(){i[0]._poptrox.windowMargin=0}),breakpoints.on(">xsmall",function(){i[0]._poptrox.windowMargin=50})):i.html('

    Es wurden noch keine passenden Bilder für diesen Account hochgeladen oder zugewiesen.

    ')}else i.html('

    Noch keine Bilder vorhanden.

    ')},error:function(){i.html('

    Keine Bilder gefunden. Lade Bilder in deinen Nextcloud-Ordner hoch.

    ')}});var d=localStorage.getItem("mischkomposition_theme")||"main";function c(n){"light"===n?e("#theme-toggle i").removeClass("fa-sun").addClass("fa-moon"):e("#theme-toggle i").removeClass("fa-moon").addClass("fa-sun")}c(d),e("#theme-toggle").click(function(n){n.preventDefault(),d="main"===d?"light":"main",localStorage.setItem("mischkomposition_theme",d),e("#theme-style").attr("href","assets/css/"+d+".min.css"),c(d)}),e.get("/api/auth/me").done(function(n){e("#login-username, #login-password, #login-submit").hide(),e("#logout-btn").show().css("display","inline-block"),e("#pw-change-section").show(),"admin"===n.role&&e("#admin-link").html('Admin-Dashboard'),e("#login-nav").html('Account ')}),e("#login-form").submit(function(n){n.preventDefault(),e.post("/api/auth/login",{username:e("#login-username").val(),password:e("#login-password").val()}).done(function(){window.location.reload()}).fail(function(e){var n="Login fehlgeschlagen.";e.responseJSON&&"Account abgelaufen"===e.responseJSON.error&&(n="Dein Account ist abgelaufen. Bitte kontaktiere den Administrator."),alert(n)})}),e("#logout-btn").click(function(n){n.preventDefault(),e.post("/api/auth/logout").done(function(){window.location.reload()})}),e("#pw-change-form").submit(function(n){n.preventDefault();var o=e("#pw-new").val();o===e("#pw-confirm").val()?e.post("/api/auth/change-password",{old_password:e("#pw-old").val(),new_password:o}).done(function(){alert("Passwort geaendert!"),e("#pw-old, #pw-new, #pw-confirm").val("")}).fail(function(e){alert(e.responseJSON?e.responseJSON.error:"Fehler")}):alert("Passwoerter stimmen nicht ueberein.")})}(jQuery); \ No newline at end of file