/* -------------------------------------------------------------------- Chevereto http://chevereto.com/ @author Rodolfo Berrios A. Copyright (C) Rodolfo Berrios A. All rights reserved. BY USING THIS SOFTWARE YOU DECLARE TO ACCEPT THE CHEVERETO EULA http://chevereto.com/license --------------------------------------------------------------------- */ $(function(){ // Window listeners $(window).on("resize", function(){ CHV.fn.uploader.boxSizer(); if(typeof user_background_full_fix == "function") { user_background_full_fix(); } CHV.fn.bindSelectableItems(); }); // Landing fancy load if($("body").hasClass("landing") && $("#home-cover, #maintenance-wrapper").css("background-image")) { var $landing_el = $(!$("#maintenance-wrapper").exists() ? "#home-cover" : "#maintenance-wrapper"); var landing_src = $landing_el.css("background-image").slice(4, -1).replace(/^\"|\"$/g, ""); function showHomeCover() { $("body").addClass("load"); setTimeout(function() { $("body").addClass("loaded"); }, 400 * 1.5); } if(landing_src) { $("").attr("src", landing_src) .on("load error", function() { $(this).remove(); showHomeCover(); }); } else { showHomeCover(); } } // Set the anywhere objects, just for shorter calling in $. var anywhere_upload = CHV.fn.uploader.selectors.root, anywhere_upload_queue = CHV.fn.uploader.selectors.queue, $anywhere_upload = $(anywhere_upload), $anywhere_upload_queue = $(anywhere_upload_queue); // Toggle anywhere upload on/off $(document).on("click", "[data-action=top-bar-upload]", function(e){ CHV.fn.uploader.toggle(); }); // Close upload box $("[data-action=close-upload], [data-action=cancel-upload]", $anywhere_upload).click(function() { if($anywhere_upload.is(":animated")) return; $("[data-action=top-bar-upload]", "#top-bar").click(); }); // Cancel remaining uploads $("[data-action=cancel-upload-remaining]", $anywhere_upload).click(function() { $("[data-action=cancel]", $anywhere_upload_queue).click(); CHV.fn.uploader.is_uploading = false; if(CHV.fn.uploader.results.success.length > 0) { CHV.fn.uploader.displayResults(); return; } else { CHV.fn.uploader.reset(); } }); // Toggle upload privacy $(document).on("click", "[data-action=upload-privacy]:not(disabled)", function(e){ if(e.isDefaultPrevented()) return; current_privacy = $(this).data("privacy"); target_privacy = current_privacy=="public" ? "private" : "public"; this_lock = $(".icon", this).data("lock"); this_unlock = $(".icon", this).data("unlock"); $(".icon", this).removeClass(this_lock + " " + this_unlock).addClass(current_privacy=="public" ? this_lock : this_unlock); $(this).data("privacy", target_privacy); $("[data-action=upload-privacy-copy]").html($("[data-action=upload-privacy]").html()); $upload_button = $("[data-action=upload]", $anywhere_upload); $upload_button.text($upload_button.data(target_privacy)); $(this).tipTip("hide"); }); // Do the thing when the fileupload changes $(CHV.fn.uploader.selectors.file+", "+CHV.fn.uploader.selectors.camera).on("change", function(e){ if(!$(CHV.fn.uploader.selectors.root).data("shown")) { CHV.fn.uploader.toggle({callback: function(e) { CHV.fn.uploader.add(e); }}, e); } else { CHV.fn.uploader.add(e); } }).on("click", function(e) { if($(this).data('login-needed') && !PF.fn.is_user_logged()) { return; } }); function isFileTransfer(e) { var e = e.originalEvent, isFileTransfer = false; if(e.dataTransfer.types) { for(var i=0; i').css({width: "100%", height: "100%", position: "fixed",/* opacity: 0.5, background: "red",*/ zIndex: 1000, left: 0, top: 0})); } } }); $(document).on({ dragover: function(e) { e.preventDefault(); if(!isFileTransfer(e)) { return false; } if(!$(CHV.fn.uploader.selectors.root).data("shown")) { CHV.fn.uploader.toggle({reset: false}); } }, dragleave: function(e) { $(CHV.fn.uploader.selectors.dropzone).remove(); if($.isEmptyObject(CHV.fn.uploader.files)) { CHV.fn.uploader.toggle(); } }, drop: function(e) { e.preventDefault(); CHV.fn.uploader.add(e); $(CHV.fn.uploader.selectors.dropzone).remove(); }, }, CHV.fn.uploader.selectors.dropzone); } // $(document).on("keyup change", "[data-action=resize-combo-input]", function(e) { var $parent = $(this).closest("[data-action=resize-combo-input]"); var $input_width = $("[name=form-width]", $parent); var $input_height = $("[name=form-height]", $parent); var ratio = $input_width.data("initial") / $input_height.data("initial"); if($(e.target).is($input_width)) { $input_height.prop("value", Math.round(Math.round($input_width.prop("value")/ratio))); } else { $input_width.prop("value", Math.round(Math.round($input_height.prop("value")*ratio))); } }) // Edit item from queue $(document).on("click", anywhere_upload_queue +" [data-action=edit]", function() { var $item = $(this).closest("li"), $queue = $item.closest("ul"), id = $item.data("id"), file = CHV.fn.uploader.files[id]; var modal = PF.obj.modal.selectors.root; var queueObject = $.extend({}, file.formValues || file.parsedMeta); // Attempt to inject the category id if(typeof queueObject.category_id == typeof undefined) { var upload_category = $("[name=upload-category-id]", CHV.fn.uploader.selectors.root).prop("value") || null; queueObject.category_id = upload_category; } // Attempt to inject the NSFW flag if(typeof queueObject.nsfw == typeof undefined) { var upload_nsfw = $("[name=upload-nsfw]:checked", CHV.fn.uploader.selectors.root).prop("value") || null; queueObject.nsfw = upload_nsfw; } // Resize before upload /* var canvas = $("")[0]; canvas.width = 500; canvas.height = 500; var ctx = canvas.getContext("2d"); ctx.drawImage(file.parsedMeta.canvas, 0, 0, canvas.width, canvas.height); var dataurl = canvas.toDataURL("image/jpeg"); console.log(dataurl); */ PF.fn.modal.call({ type: "html", template: $("#anywhere-upload-edit-item").html(), callback: function() { $.each(queueObject, function(i, v) { var name = "[name=form-" + i.replace(/_/g, "-") + "]"; var $input = $(name, modal); if(!$input.exists()) return true; // Input handler if($input.is(":checkbox")) { $input.prop("checked", $input.attr("value") == v); } else if($input.is("select")) { var $option = $input.find("[value="+v+"]"); if(!$option.exists()) { $option = $input.find("option:first"); } $option.prop("selected", true); } else { $input.prop("value", v); } if(i == "width" || i == "height") { $input.prop("max", file.parsedMeta[i]).data("initial", file.parsedMeta[i]); } }); // Warning on GIF images if(file.parsedMeta.mimetype !== "image/gif") { $("[ data-content=animated-gif-warning]", modal).remove(); } // Canvas image preview $(".image-preview", modal).append($('',{'class':'canvas'})); var source_canvas = $(".queue-item[data-id="+id+"] .preview .canvas")[0]; var target_canvas = $(".image-preview .canvas", modal)[0]; target_canvas.width = source_canvas.width; target_canvas.height = source_canvas.height; var target_canvas_ctx = target_canvas.getContext('2d'); target_canvas_ctx.drawImage(source_canvas, 0, 0); }, confirm: function() { if(!PF.fn.form_modal_has_changed()){ PF.fn.modal.close(); return; } // Validations (just in case) var errors = false; $.each(["width", "height"], function(i, v) { var $input = $("[name=form-" + v + "]", modal); var input_val = parseInt($input.val()); var min_val = parseInt($input.attr("min")); var max_val = parseInt($input.attr("max")); if(input_val > max_val || input_val < min_val) { $input.highlight(); errors = true; return true; } }); if(errors) { PF.fn.growl.expirable(PF.fn._s("Check the errors in the form to continue.")); return false; } if(typeof file.formValues == typeof undefined) { // Stock formvalues object file.formValues = { title: null, category_id: null, width: null, height: null, nsfw: null, expiration: null, description: null, }; } $(":input[name]", modal).each(function(i, v) { var key = $(this).attr("name").replace("form-", "").replace(/-/g, "_"); if(typeof file.formValues[key] == typeof undefined) return true; file.formValues[key] = $(this).is(":checkbox") ? ($(this).is(":checked") ? $(this).prop("value") : null) : $(this).prop("value"); }); CHV.fn.uploader.files[id].formValues = file.formValues; return true; } }); }); // Remove item from queue $(document).on("click", anywhere_upload_queue +" [data-action=cancel]", function() { var $item = $(this).closest("li"), $queue = $item.closest("ul"), id = $item.data("id"), queue_height = $queue.height(), item_xhr_cancel = false; if($item.hasClass("completed") || $item.hasClass("failed")) { return; } $("#tiptip_holder").hide(); $item.tipTip("destroy").remove(); if(queue_height !== $queue.height()) { CHV.fn.uploader.boxSizer(); } if(!$("li", $anywhere_upload_queue).exists()){ $("[data-group=upload-queue-ready], [data-group=upload-queue], [data-group=upload-queue-ready]", $anywhere_upload).css("display", ""); } if(CHV.fn.uploader.files[id] && typeof CHV.fn.uploader.files[id].xhr !== "undefined") { CHV.fn.uploader.files[id].xhr.abort(); item_xhr_cancel = true; } if(typeof CHV.fn.uploader.files[id] !== typeof undefined && typeof CHV.fn.uploader.files[id].fromClipboard !== typeof undefined) { var c_md5 = CHV.fn.uploader.files[id].md5; var c_index = CHV.fn.uploader.clipboardImages.indexOf(c_md5); if (c_index > -1) { CHV.fn.uploader.clipboardImages.splice(c_index, 1); } } delete CHV.fn.uploader.files[id]; CHV.fn.uploader.queueSize(); if(Object.size(CHV.fn.uploader.files) == 0) { // No queue left // Null result ? if(CHV.fn.uploader.results.success.length == 0 && CHV.fn.uploader.results.error.length == 0) { CHV.fn.uploader.reset(); } } else { // An abort was called, we need to process the next item? if(item_xhr_cancel) { if($("li.waiting", $queue).first().length !== 0) { CHV.fn.uploader.upload($("li.waiting", $queue).first()); } else if(CHV.fn.uploader.results.success.length !== 0 || CHV.fn.uploader.results.error.length !== 0) { CHV.fn.uploader.displayResults(); } } } }); // Uploader $(document).on("click", "[data-action=upload]", function(){ $("[data-group=upload], [data-group=upload-queue-ready]", $anywhere_upload).hide(); $("[data-group=uploading]", $anywhere_upload).show(); CHV.fn.uploader.queueSize(); CHV.fn.uploader.can_add = false; $queue_items = $("li", $anywhere_upload_queue); $queue_items.addClass("uploading waiting"); CHV.fn.uploader.timestamp = new Date().getTime(); CHV.fn.uploader.upload($queue_items.first("li")); }); /*CHV.obj.image_viewer.$container.swipe({ swipe: function(event, direction, distance, duration, fingerCount) { // right prev, left next if(direction == "left" || direction == "right") { var go = direction == "left" ? "next" : "prev", $link = $("[data-action="+go+"]", ".image-viewer-navigation"); if($link.exists()) { window.location = $link.attr("href"); return; } } }, threshold: 100, excludedElements: ".noSwipe", allowPageScroll: "vertical" });*/ // User page if($("body#user").exists()) { if(PF.obj.listing.query_string.page > 1) { var State = History.getState(); console.log(State.data) if(State.data && typeof State.data.scrollTop !== "undefined") { if($(window).scrollTop() !== State.data.scrollTop) { $(window).scrollTop(State.data.scrollTop); } } else { //var scrollTop = $(".follow-scroll").offset().top - $(".follow-scroll").height(); var scrollTop = $("#background-cover").height() - 160; $("html, body").animate({scrollTop: scrollTop}, 0); } } } if(!PF.fn.isDevice('phone')) { if($("#top-bar-shade").exists()) { if($("#top-bar-shade").css("opacity")) { $("#top-bar-shade").data("initial-opacity", Number($("#top-bar-shade").css("opacity"))); } } $(window).scroll(function(){ var Y = $(window).scrollTop(); var is_slim_shady = $("#top-bar-shade").exists() && !$("html").hasClass("top-bar-box-shadow-none"); if(Y < 0) return; var $top_bar = $("#top-bar"); var rate = Number(Y / ($("#background-cover, [data-content=follow-scroll-opacity]").height() - $top_bar.height())); if(rate > 1) rate = 1; if(is_slim_shady) { if($("#top-bar-shade").data("initial-opacity")) { rate += $("#top-bar-shade").data("initial-opacity"); } $("#top-bar-shade").css({opacity: rate}); } if(rate == 1) return; $("#background-cover-src").css({ transform: "translate(0, "+ Y*0.8 + "px"+")" //transform: "scale("+(1+rate/16)+") translate(0, "+ Y*0.8 + "px"+")", //transition: "all 1s" }); }); } // Selectable list items CHV.fn.bindSelectableItems(); // Image viewer page if($("body#image").exists()) { // Aux fn var ImageZoomClass = function() { if(CHV.obj.image_viewer.$container.hasClass("jscursor-zoom-in")) { CHV.obj.image_viewer.$container.addClass("cursor-zoom-in").removeClass("jscursor-zoom-in"); } } // Data load detected if($(CHV.obj.image_viewer.selector + " [data-load=full]").length > 0) { if(CHV.obj.image_viewer.$loading.exists()) { CHV.obj.image_viewer.$loading.removeClass("soft-hidden").css({zIndex: 2}); PF.fn.loading.inline(CHV.obj.image_viewer.$loading, {color: "white", size: "small", center: true, valign: true}); CHV.obj.image_viewer.$loading.hide().fadeIn("slow"); } CHV.obj.image_viewer.image.html = CHV.obj.image_viewer.$container.html(); CHV.obj.image_viewer.$container.prepend($(CHV.obj.image_viewer.image.html).css({top: 0, zIndex: 0})); CHV.obj.image_viewer.$container.find("img").eq(0).css("zIndex", 1); CHV.obj.image_viewer.$container.find("img").eq(1).attr("src", CHV.obj.image_viewer.image.url).css({ width: CHV.obj.image_viewer.$container.find("img")[0].getBoundingClientRect().width, // getBoundingClientRect -> get the real decimal width height: CHV.obj.image_viewer.$container.find("img")[0].getBoundingClientRect().height }); CHV.obj.image_viewer.$container.find("img").eq(1).imagesLoaded(function(){ CHV.obj.image_viewer.$container.find("img").eq(1).css({width: "", height: ""}); CHV.obj.image_viewer.$container.find("img").eq(0).remove(); PF.fn.loading.destroy(CHV.obj.image_viewer.$loading); ImageZoomClass(); }); // Fix viewer width when height changes and boom! a wild scrollbar appears $(document).bind("DOMSubtreeModified", function() { if($("html").height() > $(window).innerHeight() && !$("html").hasClass("scrollbar-y")) { $("html").addClass("scrollbar-y"); $(document).data({ width: $(this).width(), height: $(this).height() }); CHV.fn.image_viewer_full_fix(); } }); $(window).on("resize", function() { CHV.fn.image_viewer_full_fix(); }); // Viewer navigation $(document).on("keyup", function(e) { var $this = $(e.target), key = e.charCode || e.keyCode; if($this.is(":input")) { return; } else { // Next 39, Prev 37 if(CHV.obj.image_viewer.$navigation.exists() && (key==37 || key==39)) { var navigation_jump_url = $("[data-action="+ (key==37 ? "prev" : "next") +"]", CHV.obj.image_viewer.$navigation).attr("href"); if(typeof navigation_jump_url !== "undefined" && navigation_jump_url !== "") { window.location = $("[data-action="+ (key==37 ? "prev" : "next") +"]", CHV.obj.image_viewer.$navigation).attr("href"); } } } }); } else { ImageZoomClass(); } } $(document).on("click", CHV.obj.image_viewer.container, function(e) { var zoom = $(this).hasClass("cursor-zoom-in") || $(this).hasClass("cursor-zoom-out"); if(!zoom) return; if(zoom && PF.fn.isDevice(["phone", "phablet"])) { //window.location = $("img[data-load=full]", this).attr("src"); //return; } var zoom_in = $(this).hasClass("cursor-zoom-in"); $(this).removeClass("cursor-zoom-in cursor-zoom-out"); if(zoom_in) { // We use getBoundingClientRect to get the not rounded value var width = $(this)[0].getBoundingClientRect().width, height = $(this)[0].getBoundingClientRect().height, ratio = $("img", this).attr("width")/$("img", this).attr("height"), new_width; $(this).data({dimentions: {width: width, height: height}, ratio: ratio}); if($("img", this).attr("width") > $(window).width()) { $(this).css({width: "100%"}); new_width = $(this).width(); $(this).css({width: width}); } else { new_width = $("img", this).attr("width"); } $(this).addClass("cursor-zoom-out").css({width: new_width, height: (new_width/ratio) + "px"}); } else { $(this).addClass("cursor-zoom-in").css($(this).data("dimentions")); } e.preventDefault(); }).on("contextmenu", CHV.obj.image_viewer.container, function(e) { if(!CHV.obj.config.image.right_click) { e.preventDefault(); return false; } }); $(document).on("click", "[data-action=test-email]", function(e){ e.preventDefault(); var $email = $("input[name=test-email]"); if($email.prop("disabled")) { return; } var $parent = $(this).closest(".input-label"); var email = $email.val(); if(!email.isEmail()) { PF.fn.growl.expirable(PF.fn._s("Please provide a valid email address")); return; } $email.prop("disabled", true); PF.fn.loading.inline($('.loading', $parent), {size: "small", valign: "middle"}); $parent.find(".btn .text").hide(); $.ajax({ data: {action: "test", test: {object: "email"}, email: email}, cache: false }) .complete(function(XHR) { var response = XHR.responseJSON; $email.prop("disabled", false); $('.loading', $parent).empty(); $parent.find(".btn .text").show(); PF.fn.growl.call(response[response.status_code == 200 ? "success" : "error"].message); }); }); /* // Input copy $(document).on("mouseenter mouseleave", ".input-copy", function(e){ if(navigator.userAgent.match(/(iPad|iPhone|iPod)/i)) { return; } $(".btn-copy", this)[e.type == "mouseenter" ? "show" : "hide"](); }); $(document).on("click", ".input-copy .btn-copy", function(){ var $input = $(this).closest(".input-copy").find("input"); $(this).hide(); $input.highlight(); }); */ /** * USER SIDE LISTING EDITOR * ------------------------------------------------------------------------------------------------- */ $(document).on("click", ".list-item, [data-action=list-tools] [data-action]", function(e) { var $this = $(e.target), $list_item = $this.closest(".list-item"); if($list_item && $list_item.find("[data-action=select]").exists() && (e.ctrlKey || e.metaKey) && e.altKey) { CHV.fn.list_editor.toggleSelectItem($list_item, !$list_item.hasClass("selected")); e.preventDefault(); e.stopPropagation(); } }); // On listing ajax, clear the "Clear selection" toggle PF.fn.listing.ajax.callback = function(XHR) { if(XHR.status !== 200) return; CHV.fn.list_editor.listMassActionSet("select"); }; // Select all $(document).on("click", "[data-action=list-select-all]", function() { CHV.fn.list_editor.selectItem($(".list-item:visible:not(.selected)")); CHV.fn.list_editor.listMassActionSet("clear"); }); // Clear all $(document).on("click", "[data-action=list-clear-all]", function() { PF.fn.close_pops(); CHV.fn.list_editor.clearSelection(); }); // List item tools action (single) $(document).on("click", "[data-action=list-tools] [data-action]", function(e){ if(e.isPropagationStopped()) return false; var $this_list_item = $(this).closest(PF.obj.listing.selectors.list_item), $this_list_item_tools = $(this).closest("[data-action=list-tools]"); var $this_icon, this_add_class, this_remove_class, this_label_text, dealing_with; if(typeof $this_list_item.data("type") !== "undefined"){ dealing_with = $this_list_item.data("type"); } else { console.log("Error: data-type not defined"); return; } switch($(this).data("action")){ case "select": CHV.fn.list_editor.toggleSelectItem($this_list_item, !$this_list_item.hasClass("selected")); break; case "edit": var modal_source = "[data-modal=form-edit-single]"; // Populate the modal before casting it switch(dealing_with) { case "image": $("[name=form-image-title]", modal_source).attr("value", $this_list_item.data("title")); $("[name=form-image-description]", modal_source).html(PF.fn.htmlEncode($this_list_item.data("description"))); $("[name=form-album-id]", modal_source).find("option").removeAttr("selected"); $("[name=form-album-id]", modal_source).find("[value="+$this_list_item.data(dealing_with == "image" ? "album-id" : "id")+"]").attr("selected", true); $("[name=form-category-id]", modal_source).find("option").removeAttr("selected"); $("[name=form-category-id]", modal_source).find("[value="+$this_list_item.data("category-id") + "]").attr("selected", true); $("[name=form-nsfw]", modal_source).attr("checked", $this_list_item.data("flag") == "unsafe"); // Just in case... $("[name=form-album-name]", modal_source).attr("value", ""); $("[name=form-album-description]", modal_source).html(""); $("[name=form-privacy]", modal_source).find("option").removeAttr("selected"); break; case "album": $("[data-action=album-switch]", modal_source).remove(); $("[name=form-album-name]", modal_source).attr("value", $this_list_item.data("name")); $("[name=form-album-description]", modal_source).html(PF.fn.htmlEncode($this_list_item.data("description"))); $("[name=form-privacy]", modal_source).find("option").removeAttr("selected"); $("[name=form-privacy]", modal_source).find("[value="+$this_list_item.data('privacy')+"]").attr("selected", true); break; } PF.fn.modal.call({ type: "html", template: $(modal_source).html(), ajax: { url: PF.obj.config.json_api, deferred: { success: function(XHR) { CHV.fn.list_editor.updateItem("[data-id="+$this_list_item.data("id")+"]", XHR.responseJSON[dealing_with], "edit"); } } }, confirm: function() { var $modal = $(PF.obj.modal.selectors.root); if((dealing_with == "image" || dealing_with == "album") && $("[data-content=form-new-album]", $modal).is(":visible") && $("[name=form-album-name]", $modal).val() == "") { PF.fn.growl.call(PF.fn._s("You must enter the album name.")); $("[name=form-album-name]", $modal).highlight(); return false; } if(!PF.fn.form_modal_has_changed()){ PF.fn.modal.close(); return; } PF.obj.modal.form_data = { action: "edit", // use the same method applied in viewer edit: $this_list_item.data("type"), single: true, owner: CHV.obj.resource.user.id, editing: { id: $this_list_item.data("id"), description: $("[name=form-" + dealing_with + "-description]", $modal).val() } }; switch(dealing_with) { case "image": PF.obj.modal.form_data.editing.title = $("[name=form-image-title]", $modal).val(); PF.obj.modal.form_data.editing.category_id = $("[name=form-category-id]", $modal).val() || null; PF.obj.modal.form_data.editing.nsfw = $("[name=form-nsfw]", $modal).prop("checked") ? 1 : 0; break; case "album": PF.obj.modal.form_data.editing.name = $("[name=form-album-name]", $modal).val(); PF.obj.modal.form_data.editing.privacy = $("[name=form-privacy]", $modal).val(); break; } PF.obj.modal.form_data.editing.new_album = $("[data-content=form-new-album]", $modal).is(":visible"); if(PF.obj.modal.form_data.editing.new_album) { PF.obj.modal.form_data.editing.album_name = $("[name=form-album-name]", $modal).val(); PF.obj.modal.form_data.editing.album_privacy = $("[name=form-privacy]", $modal).val(); PF.obj.modal.form_data.editing.album_description = $("[name=form-album-description]", $modal).val(); } else { PF.obj.modal.form_data.editing.album_id = $("[name=form-album-id]", $modal).val(); } return true; } }); break; case "move": // Move or create album var modal_source = "[data-modal=form-move-single]"; // Fool the selected album $("[name=form-album-id]", modal_source).find("option").removeAttr("selected"); $("[name=form-album-id]", modal_source).find("[value="+$this_list_item.data(dealing_with == "image" ? "album-id" : "id")+"]").attr("selected", true); // Just in case... $("[name=form-album-name]", modal_source).attr("value", ""); $("[name=form-album-description]", modal_source).html(""); $("[name=form-privacy]", modal_source).find("option").removeAttr("selected"); PF.fn.modal.call({ type: "html", template: $(modal_source).html(), ajax: { url: PF.obj.config.json_api, deferred: { success: function(XHR) { CHV.fn.list_editor.updateMoveItemLists(XHR.responseJSON, dealing_with, $this_list_item); } } }, confirm: function() { var $modal = $(PF.obj.modal.selectors.root); if($("[data-content=form-new-album]", $modal).is(":visible") && $("[name=form-album-name]", $modal).val() == "") { PF.fn.growl.call(PF.fn._s("You must enter the album name.")); $("[name=form-album-name]", $modal).highlight(); return false; } if(!PF.fn.form_modal_has_changed()){ PF.fn.modal.close(); return; } PF.obj.modal.form_data = { action: "edit", // use the same method applied in viewer edit: $this_list_item.data("type"), single: true, owner: CHV.obj.resource.user.id, editing: { id: $this_list_item.data("id") } }; PF.obj.modal.form_data.editing.new_album = $("[data-content=form-new-album]", $modal).is(":visible"); if(PF.obj.modal.form_data.editing.new_album) { PF.obj.modal.form_data.editing.album_name = $("[name=form-album-name]", $modal).val(); PF.obj.modal.form_data.editing.album_privacy = $("[name=form-privacy]", $modal).val(); PF.obj.modal.form_data.editing.album_description = $("[name=form-album-description]", $modal).val(); } else { PF.obj.modal.form_data.editing.album_id = $("[name=form-album-id]", $modal).val(); } return true; } }); break; case "delete": PF.fn.modal.call({ type: "html", template: $("[data-modal=form-delete-single]").html(), button_submit: PF.fn._s("Confirm"), ajax: { url: PF.obj.config.json_api, deferred: { success: function(XHR) { if(dealing_with == "album") { $("[name=form-album-id]", "[data-modal]").find("[value="+$this_list_item.data("id")+"]").remove(); CHV.fn.list_editor.updateUserCounters("image", XHR.responseJSON.success.affected, "-"); } CHV.fn.list_editor.deleteFromList($this_list_item); CHV.fn.queuePixel(); } } }, confirm: function() { PF.obj.modal.form_data = { action: "delete", single: true, delete: $this_list_item.data("type"), deleting: { id: $this_list_item.data("id") } }; return true; } }); break; case "flag": $.ajax({ type: "POST", data: {action: 'edit', edit: 'image', single: true, editing: {id: $this_list_item.data("id"), nsfw: $this_list_item.data("flag") == "unsafe" ? 0 : 1}} }).complete(function(XHR){ var response = XHR.responseJSON, flag = response.image.nsfw == 1 ? "unsafe" : "safe"; $this_list_item.removeClass("safe unsafe").addClass(flag).attr("data-flag", flag).data("flag", flag); // Remember me gansito CHV.fn.list_editor.selectionCount(); }); break; } }); // Item action (multiple) $(".pop-box-menu a", "[data-content=list-selection]").click(function(e){ var $content_listing = $(PF.obj.listing.selectors.content_listing_visible); if(typeof $content_listing.data("list") !== "undefined"){ dealing_with = $content_listing.data("list"); } else { console.log("Error: data-list not defined"); return; } var $targets = $(PF.obj.listing.selectors.list_item+".selected", $content_listing), ids = $.map($targets, function(e,i) { return $(e).data("id"); }); $(this).closest(".pop-btn").click(); switch($(this).data("action")){ case "get-embed-codes": // Prepare the HTML var template = "[data-modal=form-embed-codes]"; $("textarea", template).html(""), objects = []; // Build the object $targets.each(function() { objects.push({image: $.parseJSON(decodeURIComponent($(this).data("object")))}); }); CHV.fn.fillEmbedCodes(objects, template, "html"); PF.fn.modal.call({ type: "html", template: $(template).html(), buttons: false }); break; case "clear": CHV.fn.list_editor.clearSelection(); e.stopPropagation(); break; case "move": case "create-album": var template = $(this).data("action") == "move" ? "form-move-multiple" : "form-create-album", modal_source = "[data-modal="+template+"]", dealing_id_data = (/image/.test(dealing_with) ? "album-id" : "id"); $("[name=form-album-id]", modal_source).find("[value=null]").remove(); // Fool the album selection $("[name=form-album-id]", modal_source).find("option").removeAttr("selected"); // Just in case... $("[name=form-album-name]", modal_source).attr("value", ""); $("[name=form-album-description]", modal_source).html(""); $("[name=form-privacy]", modal_source).find("option").removeAttr("selected"); // This is an extra step... var album_id = $targets.first().data(dealing_id_data), same_album = true; $targets.each(function() { if($(this).data(dealing_id_data) !== album_id) { same_album = false; return false; } }); if(!same_album) { $("[name=form-album-id]", modal_source).prepend(''); } $("[name=form-album-id]", modal_source).find("[value="+(same_album ? $targets.first().data(dealing_id_data) : "null")+"]").attr("selected", true); PF.fn.modal.call({ type: "html", template: $(modal_source).html(), ajax: { url: PF.obj.config.json_api, deferred: { success: function(XHR) { CHV.fn.list_editor.updateMoveItemLists(XHR.responseJSON, dealing_with, $targets); } } }, confirm: function() { var $modal = $(PF.obj.modal.selectors.root), new_album = false; if($("[data-content=form-new-album]", $modal).is(":visible") && $("[name=form-album-name]", $modal).val() == "") { PF.fn.growl.call(PF.fn._s("You must enter the album name.")); $("[name=form-album-name]", $modal).highlight(); return false; } if($("[data-content=form-new-album]", $modal).is(":visible")) { new_album = true; } if(!PF.fn.form_modal_has_changed()){ PF.fn.modal.close(); return; } var album_object = new_album ? "creating" : "moving"; PF.obj.modal.form_data = { action: new_album ? "create-album" : "move", type: dealing_with, owner: CHV.obj.resource.user.id, multiple: true, album: { ids: ids, "new": new_album } }; if(new_album) { PF.obj.modal.form_data.album.name = $("[name=form-album-name]", $modal).val(); PF.obj.modal.form_data.album.privacy = $("[name=form-privacy]", $modal).val(); PF.obj.modal.form_data.album.description = $("[name=form-album-description]", $modal).val(); } else { PF.obj.modal.form_data.album.id = $("[name=form-album-id]", $modal).val(); } return true; } }); break; case "delete": PF.fn.modal.call({ template: $("[data-modal=form-delete-multiple]").html(), button_submit: PF.fn._s("Confirm"), ajax: { url: PF.obj.config.json_api, deferred: { success: function(XHR) { // unificar if(dealing_with == "albums") { $targets.each(function() { $("[name=form-album-id]", "[data-modal]").find("[value="+$(this).data("id")+"]").remove(); }); CHV.fn.list_editor.updateUserCounters("image", XHR.responseJSON.success.affected, "-"); } CHV.fn.list_editor.deleteFromList($targets); CHV.fn.queuePixel(); } } }, confirm: function() { PF.obj.modal.form_data = { action: "delete", from: "list", "delete": dealing_with, multiple: true, deleting: { ids: ids } }; return true; } }); break; case "assign-category": var category_id = $targets.first().data("category-id"), same_category = true; $targets.each(function() { if($(this).data("category-id") !== category_id) { same_category = false; return false; } }); PF.fn.modal.call({ type: "html", template: $("[data-modal=form-assign-category]").html(), forced: true, ajax: { url: PF.obj.config.json_api, deferred: { success: function(XHR) { $targets.each(function() { var response = XHR.responseJSON; $(this).data("category-id", response.category_id) }); CHV.fn.list_editor.clearSelection(); } } }, confirm: function() { var $modal = $(PF.obj.modal.selectors.root), form_category = $("[name=form-category-id]", $modal).val() || null; if(same_category && category_id == form_category) { PF.fn.modal.close(function() { CHV.fn.list_editor.clearSelection(); }); return false; } PF.obj.modal.form_data = { action: "edit-category", from: "list", multiple: true, editing: { ids: ids, category_id: form_category } }; return true; } }); break; case "flag-safe": case "flag-unsafe": var action = $(this).data("action"), flag = action == "flag-safe" ? "safe" : "unsafe"; PF.fn.modal.call({ template: $("[data-modal=form-" + action + "]").html(), button_submit: PF.fn._s("Confirm"), ajax: { url: PF.obj.config.json_api, deferred: { success: function(XHR) { $targets.each(function() { $(this).removeClass("safe unsafe").addClass(flag).removeAttr("data-flag").attr("data-flag", flag).data("flag", flag); }); CHV.fn.list_editor.clearSelection(); } } }, confirm: function() { PF.obj.modal.form_data = { action: action, from: "list", multiple: true, editing: { ids: ids, nsfw: action == "flag-safe" ? 0 : 1 } }; return true; } }); break; } if(PF.fn.isDevice(["phone", "phablet"])) { return false; } }); // Image page if($("body#image").exists()) { $(window).scroll(function(){ CHV.obj.topBar.transparencyScrollToggle(); }); } $(document).on("click", "[data-action=disconnect]", function() { var $this = $(this), connection = $this.data("connection"); PF.fn.modal.confirm({ message: $this.data("confirm-message"), ajax: { data: {action: 'disconnect', disconnect: connection, user_id: CHV.obj.resource.user.id}, deferred: { success: function(XHR) { var response = XHR.responseJSON; $("[data-connection="+connection+"]").fadeOut(function() { $($("[data-connect="+connection+"]")).fadeIn(); $(this).remove(); if($("[data-connection]").length == 0) { $("[data-content=empty-message]").show(); } PF.fn.growl.expirable(response.success.message); }); }, error: function(XHR) { var response = XHR.responseJSON; PF.fn.growl.call(response.error.message); } } } }); }); $(document).on("click", "[data-action=delete-avatar]", function() { var $parent = $(".user-settings-avatar"), $loading = $(".loading-placeholder", $parent), $top = $("#top-bar"); $loading.removeClass("hidden"); PF.fn.loading.inline($loading, {center: true}); $.ajax({ type: "POST", data: {action: "delete", delete: "avatar", owner: CHV.obj.resource.user.id} }).complete(function(XHR){ $loading.addClass("hidden").empty(); if(XHR.status == 200) { if(CHV.obj.logged_user.id == CHV.obj.resource.user.id) { $("img.user-image", $top).hide(); $(".default-user-image", $top).removeClass("hidden"); } $(".default-user-image", $parent).removeClass("hidden").css({opacity: 0}); $(".btn-alt", $parent).closest("div").hide(); $("img.user-image", $parent).fadeOut(function() { $(".default-user-image", $parent).animate({opacity: 1}); }); } else { PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later.")); } }); }); $(document).on("change", "[data-content=user-avatar-upload-input]", function(e) { e.preventDefault(); e.stopPropagation(); var $this = $(this), $parent = $(".user-settings-avatar"), $loading = $(".loading-placeholder", ".user-settings-avatar"), $top = $("#top-bar"), user_avatar_file = $(this)[0].files[0]; if($this.data("uploading")) { return; } if(/^image\/.*$/.test(user_avatar_file.type) == false) { PF.fn.growl.call(PF.fn._s("Please select a valid image file type.")); return; } if(user_avatar_file.size > CHV.obj.config.user.avatar_max_filesize.getBytes()) { PF.fn.growl.call(PF.fn._s("Please select a picture of at most %s size.", CHV.obj.config.user.avatar_max_filesize)); return; } $loading.removeClass("hidden"); PF.fn.loading.inline($loading, {center: true}); $this.data("uploading", true); // HTML5 method var user_avatar_fd = new FormData(); user_avatar_fd.append("source", user_avatar_file); user_avatar_fd.append("action", "upload"); user_avatar_fd.append("type", "file"); user_avatar_fd.append("what", "avatar"); user_avatar_fd.append("owner", CHV.obj.resource.user.id); user_avatar_fd.append("auth_token", PF.obj.config.auth_token); avatarXHR = new XMLHttpRequest(); avatarXHR.open("POST", PF.obj.config.json_api, true); avatarXHR.send(user_avatar_fd); avatarXHR.onreadystatechange = function(){ if(this.readyState == 4){ var response = this.responseType !== "json" ? JSON.parse(this.response) : this.response, image = response.success.image; $loading.addClass("hidden").empty(); if(this.status == 200) { change_avatar = function(parent) { $("img.user-image", parent).attr("src", image.url).removeClass("hidden").show(); }; hide_default = function(parent) { $(".default-user-image", parent).addClass("hidden"); }; // Form hide_default($parent); $(".btn-alt", $parent).closest("div").show(); change_avatar($parent); // Top if(CHV.obj.logged_user.id == CHV.obj.resource.user.id) { change_avatar($top); hide_default($top); } PF.fn.growl.expirable(PF.fn._s("Profile image updated.")); } else { PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later.")); } $this.data("uploading", false); } } }); $(document).on("change", "[data-content=user-background-upload-input]", function(e) { e.preventDefault(); e.stopPropagation(); var $this = $(this), $parent = $("[data-content=user-background-cover]"), $src = $("[data-content=user-background-cover-src]"), $loading = $(".loading-placeholder", $parent), $top = $("#top-bar"), user_file = $(this)[0].files[0]; if($this.data("uploading")) { return; } if(/^image\/.*$/.test(user_file.type) == false) { PF.fn.growl.call(PF.fn._s("Please select a valid image file type.")); return; } if(user_file.size > CHV.obj.config.user.background_max_filesize.getBytes()) { PF.fn.growl.call(PF.fn._s("Please select a picture of at most %s size.", CHV.obj.config.user.background_max_filesize)); return; } $loading.removeClass("hidden"); PF.fn.loading.inline($loading, {center: true, size: 'big', color: '#FFF'}); $this.data("uploading", true); // HTML5 method var user_picture_fd = new FormData(); user_picture_fd.append("source", user_file); user_picture_fd.append("action", "upload"); user_picture_fd.append("type", "file"); user_picture_fd.append("what", "background"); user_picture_fd.append("owner", CHV.obj.resource.user.id); user_picture_fd.append("auth_token", PF.obj.config.auth_token); avatarXHR = new XMLHttpRequest(); avatarXHR.open("POST", PF.obj.config.json_api, true); avatarXHR.send(user_picture_fd); avatarXHR.onreadystatechange = function(){ if(this.readyState == 4){ var response = this.responseType !== "json" ? JSON.parse(this.response) : this.response, image = response.success.image; if(this.status == 200) { var $img = $(""); $img.attr('src', image.url).imagesLoaded(function(){ $loading.addClass("hidden").empty(); $src.css("background-image", "url("+image.url+")").hide().fadeIn(); $("[data-content=user-change-background]", $parent).removeClass("hidden"); $parent.removeClass("no-background"); $("[data-content=user-upload-background]").hide(); $("[data-content=user-change-background]").show(); PF.fn.growl.expirable(PF.fn._s("Profile background image updated.")); $img.remove(); if(typeof user_background_full_fix == "function") { user_background_full_fix(); //PF.fn.follow_scroll_update(); } }); } else { $loading.addClass("hidden").empty(); PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later.")); } $this.data("uploading", false); } } }); /* $(document).on("click", "[data-action=disconnect]", function() { var $this = $(this), connection = $this.data("connection"); PF.fn.modal.confirm({ message: $this.data("confirm-message"), ajax: { data: {action: 'disconnect', disconnect: connection, user_id: CHV.obj.resource.user.id}, deferred: { success: function(XHR) { var response = XHR.responseJSON; $("[data-connection="+connection+"]").fadeOut(function() { $($("[data-connect="+connection+"]")).fadeIn(); $(this).remove(); if($("[data-connection]").length == 0) { $("[data-content=empty-message]").show(); } PF.fn.growl.expirable(response.success.message); }); }, error: function(XHR) { var response = XHR.responseJSON; PF.fn.growl.expirable(response.error.message); } } } }); }); */ CHV.fn.user_background = { delete : { submit: function() { PF.obj.modal.form_data = { action: "delete", delete: "background", owner: CHV.obj.resource.user.id }; return true; }, deferred: { success: { before: function(XHR) { $("[data-content=user-background-cover-src]").css("background-image", "none"); $("[data-content=user-background-cover]").addClass("no-background").height(""); $("[data-content=user-upload-background]").removeClass("hidden").show(); $("[data-content=user-change-background]").hide(); $("#top-bar").removeClass("transparent background-transparent"); $("#top-bar-shade").remove(); //PF.fn.follow_scroll_update(); }, done: function(XHR) { PF.fn.modal.close(function(){ PF.fn.growl.expirable(PF.fn._s("Profile background image deleted.")); }); } }, error: function(XHR) { PF.fn.growl.expirable(PF.fn._s("Error deleting profile background image.")); } } } }; // Form things CHV.str.mainform = "[data-content=main-form]"; CHV.obj.timezone = { 'selector' : "[data-content=timezone]", 'input' : "#timezone-region" }; // Detect form changes $(document).on("keyup change", CHV.str.mainform + " :input", function() { if($(this).is("[name=username]")) { $("[data-text=username]").text($(this).val()); } }); // Timezone handler $(document).on("change", CHV.obj.timezone.input, function(){ var value = $(this).val(), $timezone_combo = $("#timezone-combo-"+value); $timezone_combo.find("option:first").prop("selected", true); $(CHV.obj.timezone.selector).val($timezone_combo.val()).change(); }); $(document).on("change", "[id^=timezone-combo-]", function(){ var value = $(this).val(); $(CHV.obj.timezone.selector).val(value).change(); }); // Password match $(document).on("keyup change blur", "[name^=new-password]", function() { var $new_password = $("[name=new-password]"), $new_password_confirm = $("[name=new-password-confirm]"), hide = $new_password.val() == $new_password_confirm.val(), $warning = $new_password_confirm.closest(".input-password").find(".input-warning"); if($(this).is($new_password_confirm)) { $new_password_confirm.data("touched", true); } if($new_password_confirm.data("touched")) { $warning.text(!hide ? $warning.data("text") : "")[!hide ? 'removeClass' : 'addClass']('hidden-visibility'); } }); // Submit form $(document).on("submit", CHV.obj.mainform, function() { switch($(this).data("type")) { case "password": var $p1 = $("[name=new-password]", this), $p2 = $("[name=new-password-confirm]", this); if($p1.val() !== "" || $p2.val() !== "") { if($p1.val() !== $p2.val()) { $p1.highlight(); $p2.highlight(); PF.fn.growl.expirable(PF.fn._s("Passwords don't match")); return false; } } break; } }); $(document).on("change", "[name=theme_tone]", function() { $("html")[0].className = $("html")[0].className.replace(/\btone-[\w-]+\b/g, ''); $("html").addClass("tone-"+$(this).val()); }); $(document).on("change", "[name=theme_top_bar_color]", function() { //$("html")[0].className = $("html")[0].className.replace(/\btone-[\w-]+\b/g, ''); $("#top-bar, .top-bar").removeClass("black white").addClass($(this).val()); }); $(document).on("click", "[data-action=check-for-updates]", function() { PF.fn.loading.fullscreen(); CHV.fn.system.checkUpdates(function(XHR) { PF.fn.loading.destroy("fullscreen"); if(XHR.status !== 200) { PF.fn.growl.call(PF.fn._s("An error occurred. Please try again later.")); return; } var data = XHR.responseJSON.software; if(PF.fn.versionCompare(CHV.obj.system_info.version, data.current_version) == -1) { PF.fn.modal.simple({ title: PF.fn._s("Update available v%s", data.current_version), message: '

' + PF.fn._s('There is an update available for your system. You can automatic download and install this update or go to %s to proceed to download the file.', 'chevereto.com') + '

' + PF.fn._s('The release notes for this update are:') + '

' + '' + '', html: true }); } else { PF.fn.growl.call(PF.fn._s("Your website is running the latest version of Chevereto.")); } }); }); // Topbar native js thing if($("body#image").exists() && window.scrollY > 0) { $("#top-bar").removeClass("transparent"); } // Storage form $(document).on("click", "[data-action=toggle-storage-https]", function() { CHV.fn.storage.toggleHttps($(this).closest("[data-content=storage]").data('storage-id')); }); $(document).on("click", "[data-action=toggle-storage-active]", function() { CHV.fn.storage.toggleActive($(this).closest("[data-content=storage]").data('storage-id')); }); // Detect paste image event if($(CHV.fn.uploader.selectors.root).exists()) { CHV.fn.uploader.$pasteCatcher = $("
", {contenteditable: "true", id: CHV.fn.uploader.selectors.paste.replace(/#/, "")}); $("body").append(CHV.fn.uploader.$pasteCatcher); // Hack Ctrl/Cmd+V to focus pasteCatcher $(document).keydown(function(e) { var key = e.keyCode; var ctrlDown = e.ctrlKey || e.metaKey; // Mac support if(ctrlDown && key==86 && !$(e.target).is(":input")) { // Paste detected on "body" CHV.fn.uploader.$pasteCatcher.focus(); } }); // Add the paste event listener window.addEventListener("paste", CHV.fn.uploader.pasteImageHandler); } /* LIKE BUTTON */ $(document).on("click", "[data-action=like]", function() { if(!PF.fn.is_user_logged()) { PF.fn.modal.call({type: "login"}); return; } var $this = $(this); // Block ajax while this thing is still working... if($this.data("XHR")) return; $this.data("XHR", true); var $object = $(this).is("[data-liked]") ? $(this) : $(this).closest("[data-liked]"); var isSingle = !$object.closest("[data-list]").exists() && typeof CHV.obj.resource !== typeof undefined; var liked = $object.is("[data-liked=1]"); var action = !liked ? 'like' : 'dislike'; var content = { id: isSingle ? CHV.obj.resource.id : $(this).closest("[data-id]").data("id"), type: isSingle ? CHV.obj.resource.type : $(this).closest("[data-type]").data("type") }; var ajax = { data: {action: action}, cache: false }; ajax.data[action] = { object: content.type, id: content.id, }; $.ajax(ajax) .complete(function(XHR) { var response = XHR.responseJSON; $this.data("XHR", false); if(response.status_code !== 200) { PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later.")); return; } if(isSingle && typeof response.content !== typeof undefined) { $("[data-text=likes-count]").html(response.content.likes); } $object.attr("data-liked", liked ? 0 : 1); // Toggle indicator }); }); /* FOLLOW BUTTON */ $(document).on("click", "[data-action=follow]", function() { if(!PF.fn.is_user_logged()) { PF.fn.modal.call({type: "login"}); return; } var $this = $(this); // Block ajax while this thing is still working... if($this.data("XHR")) return; $this.data("XHR", true); var $object = $(this).is("[data-followed]") ? $(this) : $(this).closest("[data-followed]"); var isSingle = typeof CHV.obj.resource !== typeof undefined; var followed = $object.is("[data-followed=1]"); var action = !followed ? 'follow' : 'unfollow'; var content = { id: isSingle ? CHV.obj.resource.id : $(this).closest("[data-id]").data("id"), type: isSingle ? CHV.obj.resource.type : $(this).closest("[data-type]").data("type") }; var ajax = { data: {action: action}, cache: false }; ajax.data[action] = { object: content.type, id: content.id, }; $.ajax(ajax) .complete(function(XHR) { var response = XHR.responseJSON; $this.data("XHR", false); if(response.status_code !== 200) { PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later.")); return; } if(isSingle) { if(typeof response.user_followed !== typeof undefined) { var $followersLabel = $("[data-text=followers-label]"); var label = { single: $followersLabel.data('label-single'), plural: $followersLabel.data('label-plural') }; $("[data-text=followers-count]").html(response.user_followed.followers); $followersLabel.html(PF.fn._n(label.single, label.plural, response.user_followed.followers)); } } $object.attr("data-followed", followed ? 0 : 1); // Toggle indicator }); }); // Notifications antiscroll. Must be called on visible elements. function notifications_scroll() { if(PF.fn.isDevice(["phone", "phablet"])) return; var $visible_list = $(".top-bar-notifications-list ul", ".top-bar:visible"); var height; var height_auto; $visible_list.css("height", ""); // Reset any change height = $visible_list.height(); $visible_list.data("height", height).css("height", "auto"); height_auto = $visible_list.height(); if(height_auto > height){ $visible_list.height(height); $visible_list.closest(".antiscroll-wrap").antiscroll(); } } // Notifications list $(document).on("click", "[data-action=top-bar-notifications]", function(e) { var _this = this; var $this = $(this); var $container = $(".top-bar-notifications-container", $this); var $list = $(".top-bar-notifications-list", $this); var $ul = $("ul", $list); var $loading = $(".loading", $container); if($this.data("XHR")) { return; } else { $loading.removeClass("hidden"); PF.fn.loading.inline($loading, {size: "small", message: PF.fn._s("loading")}); } $.ajax({data: {action: "notifications"}, cache: false}) .complete(function(XHR) { var response = XHR.responseJSON; if(response.status_code !== 200) { PF.fn.growl.expirable(PF.fn._s("An error occurred. Please try again later.")); $this.data("XHR", false); $loading.addClass("hidden").html(""); return; } $this.data("XHR", true); $loading.remove(); if(!response.html) { $(".empty", $container).removeClass("hidden"); return; } $list.removeClass("hidden"); $ul.html(response.html); notifications_scroll(); var $li = $("li.new", $ul); $li.addClass("transition"); setTimeout(function() { $li.removeClass("new"); $("[data-content=notifications-counter]", _this).removeClass("on").html("0"); setTimeout(function() { $li.removeClass("transition"); }, 150); }, 1500); }) }); if($("#g-recaptcha").is(':empty') && CHV.obj.config.recaptcha.enabled && CHV.obj.config.recaptcha.sitekey) { reCaptchaCallback = function() { grecaptcha.render("g-recaptcha", { "sitekey" : CHV.obj.config.recaptcha.sitekey }); } $.getScript("https://www.google.com/recaptcha/api.js?onload=reCaptchaCallback&render=explicit"); } }); if(typeof CHV == "undefined") { CHV = {obj: {}, fn: {}, str:{}}; } CHV.obj.image_viewer = { selector: "#image-viewer", container: "#image-viewer-container", navigation: ".image-viewer-navigation", loading: "#image-viewer-loading" }; CHV.obj.image_viewer.$container = $(CHV.obj.image_viewer.container); CHV.obj.image_viewer.$navigation = $(CHV.obj.image_viewer.navigation); CHV.obj.image_viewer.$loading = $(CHV.obj.image_viewer.loading); CHV.fn.system = { checkUpdates: function(callback) { $.ajax({ url: "https://chevereto.com/api/get/info/", data: null, cache: false }) .always(function(data, status, XHR) { if(typeof callback == "function") { callback(XHR); } }); } }; CHV.fn.bindSelectableItems = function() { var el = 'content-listing-wrapper'; if(!$("#" + el).exists()) { $("[data-content=list-selection]").closest(".content-width").wrap("
"); } if(!$("[data-content=list-selection]").exists() || PF.fn.isDevice(["phone", "phablet"])) { return; } $("#content-listing-wrapper").selectable({ filter: PF.obj.listing.selectors.list_item, cancel: ".viewer-title, .header-link, .top-bar, .content-listing-pagination *, #fullscreen-modal, #top-user, #background-cover, .list-item-desc, .list-item-image-tools", delay: 5, // Avoids unattended click reset selecting: function(event, ui) { var $this = $(ui.selecting); var unselect = $this.hasClass("selected"); CHV.fn.list_editor[(unselect ? "unselect" : "select") + "Item"]($this); }, unselecting: function(event, ui) { CHV.fn.list_editor.unselectItem($(ui.unselecting)); } }); }; // this is just an stock if the fn isn't defined in /image /*CHV.fn.image_viewer_full_fix = function() { if(!$(".image-viewer.full-viewer").exists()) return; var canvas = { height: Math.max($(window).height() - $("#top-bar").height(), parseInt($(".image-viewer").css("minHeight"))), width: $(window).width() }, img = { width: CHV.obj.image_viewer.image.width, height: CHV.obj.image_viewer.image.height }, ratio = CHV.obj.image_viewer.image.ratio; if(img.height > canvas.height && (img.height/img.width) < 3) { img.height = canvas.height; } if(img.height == canvas.height) { img.width = Math.round(img.height * ratio); } if(PF.fn.isDevice('phone') || PF.fn.isDevice('phablet')) { if(img.width > canvas.width) { img.width = canvas.width; } img.height = Math.round(img.width/ratio); } else { if(img.height > canvas.height && (img.height/img.width) < 3) { img.height = canvas.height; } if(img.height == canvas.height) { img.width = Math.round(img.height * ratio); } } if(img.width > canvas.width) { img.width = canvas.width; img.height = Math.round(img.width / CHV.obj.image_viewer.image.ratio); } else if((img.height/img.width) > 3) { // wow, very tall. such heights img = imgSource; if(img.width > canvas.width) { img.width = canvas.width * 0.8; } img.height = Math.round(img.width/ratio); } $(".image-viewer.full-viewer").height(img.height); img.display = "block"; $(".image-viewer-container").css(img); };*/ CHV.obj.embed_tpl = {}; CHV.obj.topBar = { transparencyScrollToggle: function() { var Y = $(window).scrollTop(); $("#top-bar")[(Y > 0 ? "remove" : "add") + "Class"]("transparent"); } }; CHV.fn.uploader = { options: { image_types: ["png", "jpg", "jpeg", "gif", "bmp"], max_filesize: "2 MB" }, selectors: { root: "#anywhere-upload", queue: "#anywhere-upload-queue", queue_complete: ".queue-complete", queue_item: ".queue-item", close_cancel: "[data-button=close-cancel]", file: "#anywhere-upload-input", camera: "#anywhere-upload-input-camera", upload_item_template: "#anywhere-upload-item-template", item_progress_bar: "[data-content=progress-bar]", item_progress_percent: "[data-text=progress-percent]", failed_result: "[data-content=failed-upload-result]", fullscreen_mask: "#fullscreen-uploader-mask", dropzone: "#uploader-dropzone", paste: "#anywhere-upload-paste", }, is_uploading: false, can_add: true, queue_status : "ready", files: {}, results: {success: [], error: []}, toggleWorking: 0, toggle: function(options, args) { var $switch = $("[data-action=top-bar-upload]", ".top-bar"); var show = !$(CHV.fn.uploader.selectors.root).data("shown"); var options = $.extend({callback: null, reset: true}, options); PF.fn.growl.close(true); PF.fn.close_pops(); if(this.toggleWorking == 1 || $(CHV.fn.uploader.selectors.root).is(":animated") || CHV.fn.uploader.is_uploading || ($switch.data('login-needed') && !PF.fn.is_user_logged())) return; this.toggleWorking = 1; var uploadBoxHeight = $(CHV.fn.uploader.selectors.root).outerHeight() + "px"; var uploadBoxTop = $(CHV.fn.uploader.selectors.root).css("top"); var uploadBoxPush = (parseInt(uploadBoxHeight) + parseInt(uploadBoxTop)) + "px"; var animation = { core: !show ? ("-" + uploadBoxPush) : uploadBoxPush, time: 500, }, callbacks = function() { if(options.reset) { CHV.fn.uploader.reset(); } if(PF.obj.follow_scroll.$node.exists()) { PF.obj.follow_scroll.$node.removeClass("fixed"); PF.obj.follow_scroll.set(); } if(!show) { $(CHV.fn.uploader.selectors.root).css({visibility: "hidden"}).addClass("hidden-visibility"); } PF.fn.topMenu.hide(); if(typeof options.callback == "function") { options.callback(args); } CHV.fn.uploader.boxSizer(); CHV.fn.uploader.toggleWorking = 0; }; if(show) { $(CHV.fn.uploader.selectors.root).data("initial-height", uploadBoxHeight); $("html").data({ "followed-scroll": $("html").hasClass("followed-scroll"), "top-bar-box-shadow-prevent": true }).removeClass("followed-scroll").addClass("top-bar-box-shadow-none"); $("#top-bar").data({ "stock_classes": $("#top-bar").attr("class") }); var top_bar_color = $("#top-bar").hasClass("white") ? "white" : "black"; var is_slim_shady = $("#top-bar-shade").exists(); //if($("#top-bar").hasClass("transparent")) { if(!is_slim_shady) { $("
", { id: "top-bar-shade", "class": "top-bar " + top_bar_color }).insertBefore("#top-bar"); } //$("#top-bar").attr("class", "top-bar").addClass(top_bar_color); //} var shade_target_opacity = 1; if($("body").hasClass("landing") || $("body").hasClass("split_landing")) { shade_target_opacity = 0; } if(PF.fn.isDevice("phone")) { $("#top-bar-shade").css({opacity: shade_target_opacity}); } else { $("#top-bar-shade").animate({opacity: shade_target_opacity}, animation.time/2, animation.easing); } $(".current[data-nav]", ".top-bar").each(function(){ if($(this).is("[data-action=top-bar-menu-full]")) return; $(this).removeClass("current").attr("data-current", 1); }); $(CHV.fn.uploader.selectors.root).removeClass("hidden-visibility").css({visibility: "visible", top: "-" + uploadBoxHeight}); if(PF.fn.isDevice("mobile")) { var $upload_heading = $(".upload-box-heading", $(CHV.fn.uploader.selectors.root)); $upload_heading.css({position: "relative", top: 0.5*($(window).height() - $upload_heading.height())+"px"}); } $(CHV.fn.uploader.selectors.root).css({ transform: "translate(0,"+animation.core+")" }); CHV.fn.uploader.focus(function() { setTimeout(function() { callbacks(); if(PF.fn.isDevice(["phone", "phablet"])) { $("html").addClass("overflow-hidden"); } }, animation.time); }); } else { // hide $("[data-nav][data-current=1]", ".top-bar").each(function(){ $(this).addClass("current"); }); var fade_slim_shady = function() { if(PF.fn.isDevice("phone")) { $("#top-bar-shade").remove(); return; } $("#top-bar-shade").animate({opacity: 0}, animation.time, animation.easing, function() { if(!is_slim_shady) { $(this).remove(); } }); } if(!$("#top-bar").hasClass("transparent")) { fade_slim_shady() } $(CHV.fn.uploader.selectors.fullscreen_mask).css({opacity: 0}); setTimeout(function() { $(CHV.fn.uploader.selectors.fullscreen_mask).remove(); if($("html").data("followed-scroll")) { $("html").addClass("followed-scroll"); } }, 250); var _uploadBoxHeight = $(CHV.fn.uploader.selectors.root).outerHeight(); var _uploadBoxPush = (_uploadBoxHeight - parseInt($(CHV.fn.uploader.selectors.root).data("initial-height"))) + "px"; $(CHV.fn.uploader.selectors.root).css({ transform: "translate(0,-"+_uploadBoxPush+")" }); setTimeout(function() { $("#top-bar").attr("class", $("#top-bar").data("stock_classes")); $("html").removeClass(($(".follow-scroll-wrapper.position-fixed").exists() ? "" : "top-bar-box-shadow-none")); }, animation.time * 1/3); setTimeout(function() { $(CHV.fn.uploader.selectors.root).css({top: ""}); if($("#top-bar-shade").exists()) { fade_slim_shady() } if($("body#image").exists()) { CHV.obj.topBar.transparencyScrollToggle(); } callbacks(); $("html") .removeClass("overflow-hidden") .data({"top-bar-box-shadow-prevent": false}); }, animation.time); } $(CHV.fn.uploader.selectors.root).data("shown", show); $switch.toggleClass("current").removeClass("opened"); }, reset: function() { this.files = {}; this.is_uploading = false; this.can_add = true; this.results = {success: [], error: []}; this.queue_status = "ready"; $("li", this.selectors.queue).remove(); $(this.selectors.anywhere).height("").css({"overflow-y": "", "overflow-x": ""}); $(this.selectors.queue).removeClass(this.selectors.queue_complete.substring(1)); $("[data-group=upload-result] textarea", this.selectors.anywhere).prop("value", ""); $.each(['upload-queue-ready', 'uploading', 'upload-result', 'upload-queue-ready', 'upload-queue'], function(i,v) { $("[data-group="+v+"]").hide(); }); //$("[data-group=upload-queue-ready], [data-group=uploading], [data-group=upload-result], [data-group=upload-queue-ready], [data-group=upload-queue]", this.selectors.anywhere).hide(); $("[data-group=upload]", this.selectors.anywhere).show(); $("[name=upload-category-id]", this.selectors.root).val(""); $("[name=upload-nsfw]", this.selectors.root).prop("checked", this.defaultChecked); $(this.selectors.close_cancel, this.selectors.anywhere).hide().each(function() { if($(this).data("action") == "close-upload") $(this).show(); }); this.boxSizer(true); }, focus: function(callback) { if($(this.selectors.fullscreen_mask).exists()) return; $("body").append($("
", { id: (this.selectors.fullscreen_mask.replace("#", "")), class: "fullscreen soft-black", }).css({ top: PF.fn.isDevice("phone") ? 0 : $(CHV.fn.uploader.selectors.root).data("top") })); setTimeout(function() { $(CHV.fn.uploader.selectors.fullscreen_mask).css({opacity: 1}) setTimeout(function() { if(typeof callback == "function") { callback(); } }, PF.fn.isDevice(["phone", "phablet"]) ? 0 : 250); }, 1); }, boxSizer: function(forced) { if($(this.selectors.root).css("visibility") == "visible") { $("html")[(PF.fn.isDevice(["phone", "phablet"]) ? "add" : "remove") + "Class"]("overflow-hidden"); } var doit = $(this.selectors.root).css("visibility") == "visible" || forced; if(!doit) return; $(this.selectors.root).height(""); if($(this.selectors.root).height() + $("#top-bar").outerHeight(true) > $(window).height()) { $(this.selectors.root).height($(window).height() - $("#top-bar").outerHeight(true)).css({"overflow-y": "scroll", "overflow-x": "auto"}); $("body").addClass("overflow-hidden"); } else { $(this.selectors.root).css("overflow-y", ""); $("body").removeClass("overflow-hidden"); } }, pasteURL: function() { var urlvalues = $("[name=urls]", "#fullscreen-modal").val(); if(urlvalues) { CHV.fn.uploader.add({}, urlvalues); } }, pasteImageHandler: function(e) { // Leave the inputs alone if($(e.target).is(":input")) { return; } // Get the items from the clipboard if(typeof e.clipboardData !== typeof undefined && e.clipboardData.items) { var items = e.clipboardData.items; } else { // Get the items from the contenteditable catcher setTimeout(function() { // Hack to get the items after paste e.clipboardData = {}; e.clipboardData.items = []; $.each($("img", CHV.fn.uploader.$pasteCatcher), function(i,v) { e.clipboardData.items.push(PF.fn.dataURItoBlob($(this).attr("src"))); }); $(CHV.fn.uploader.selectors.paste).html(""); return CHV.fn.uploader.pasteImageHandler(e); }, 1); } if (items) { // Loop through all items, looking for any kind of image for (var i = 0; i < items.length; i++) { if (items[i].type.indexOf("image") !== -1) { var file = items[i] instanceof Blob ? items[i] : items[i].getAsFile(); var reader = new FileReader(); reader.onload = function(evt) { var uploaderIsVisible = $(CHV.fn.uploader.selectors.root).data("shown"); // Give a name to this clipboard image file.name = PF.fn._s('Clipboard image') + ' ' + PF.fn.getDateTime(); // Mimic file select event var file_evt = { originalEvent: { dataTransfer: {files: [file]}, preventDefault: function() {}, stopPropagation: function() {}, clipboard: true, dataURL: evt.target.result, name: file.name } }; if(!uploaderIsVisible) { CHV.fn.uploader.toggle({callback: function() { CHV.fn.uploader.add(file_evt); }}); } else { CHV.fn.uploader.add(file_evt); } }; reader.readAsDataURL(file); } } } }, item_add_id : 0, clipboardImages : [], add: function(e, urls) { var md5; if(typeof CHV.obj.config !== "undefined" && typeof CHV.obj.config.image !== "undefined" && CHV.obj.config.image.max_filesize !== "undefined") { this.options.max_filesize = CHV.obj.config.image.max_filesize; } // Prevent add items ? if(!this.can_add) { var e = e.originalEvent; e.preventDefault(); e.stopPropagation(); return false; }; $fileinput = $(this.selectors.file); $fileinput.replaceWith($fileinput = $fileinput.clone(true)); var item_queue_template = $(this.selectors.upload_item_template).html(), files; if(typeof urls == typeof undefined) { // Local files var e = e.originalEvent; e.preventDefault(); e.stopPropagation(); files = e.dataTransfer || e.target; files = $.makeArray(files.files); // Keep a map for the clipboard images if(e.clipboard) { md5 = PF.fn.md5(e.dataURL); if($.inArray(md5, this.clipboardImages) != -1) { return null; } this.clipboardImages.push(md5); } // Filter non images var failed_files = []; files = $.map(files, function(file, i){ var image_type_str; if(typeof file.type == "undefined" || file.type == "") { // Some browsers (Android) don't set the correct file.type image_type_str = file.name.substr(file.name.lastIndexOf('.') + 1).toLowerCase(); } else { image_type_str = file.type.replace("image/", ""); } // And yes... Android can output shit like image:10 as the full file name so ignore this filter if(CHV.fn.uploader.options.image_types.indexOf(image_type_str) == -1 && /android/i.test(navigator.userAgent) == false) { failed_files.push({id: i, name: file.name.truncate_middle() + " - " + PF.fn._s("Invalid or unsupported file format.")}); return null; } if(file.size > CHV.obj.config.image.max_filesize.getBytes()){ failed_files.push({id: i, name: file.name.truncate_middle() + " - " + PF.fn._s("File too big.")}); return null; } file.fromClipboard = e.clipboard == true; if(md5) { file.md5 = md5; } return file; }); if(failed_files.length > 0 && files.length == 0) { var failed_message = ''; for(var i = 0; i < failed_files.length; i++){ failed_message += "
  • " + failed_files[i].name + "
  • "; } PF.fn.modal.simple({title: PF.fn._s("Some files couldn't be added"), message: "
      " + "
    • " + failed_message + "
    "}); return; } if(files.length == 0) return; } else { // Remote files files = urls.match_image_urls(); if(!files) return; files = files.array_unique(); files = $.map(files, function(file,i){ return {name: file, url: file}; }); } // Empty current files object? if($.isEmptyObject(this.files)) { for(var i=0; i img_h || img_w == img_h){ // Landscape var queue_img_h = img_h < queue_item_h ? img_h : queue_item_h; if(img_w > img_h){ $img.height(queue_img_h).width(queue_img_h*img_r); } } if(img_w < img_h || img_w == img_h){ // Portrait var queue_img_w = img_w < queue_item_w ? img_w : queue_item_w; if(img_w < img_h){ $img.width(queue_img_w).height(queue_img_w/img_r); } } if(img_w == img_h) { $img.height(queue_img_h).width(queue_img_w); } $img.css({marginTop: - $img.height()/2, marginLeft: - $img.width()/2}).show(); } // Last one if(j == files.length) { if(typeof failed_before !== "undefined") { failed_files = failed_files.concat(failed_before); } if(failed_files.length > 0) { var failed_message = ""; for(var i = 0; i < failed_files.length; i++){ failed_message += "
  • " + failed_files[i].name + "
  • "; delete CHV.fn.uploader.files[failed_files[i].id]; $("li[data-id="+ failed_files[i].id +"]", CHV.fn.uploader.selectors.queue).find("[data-action=cancel]").click() } PF.fn.modal.simple({title: PF.fn._s("Some files couldn't be added"), message: '
      '+failed_message+'
    '}); } else { CHV.fn.uploader.focus(); } CHV.fn.uploader.boxSizer(); } }, $.extend({}, default_options, {orientation: data.exif ? data.exif.get("Orientation") : 1})); }); }); }, queueSize: function() { $("[data-text=queue-objects]", this.selectors.root).text(PF.fn._n("image", "images", Object.size(this.files))); $("[data-text=queue-size]", this.selectors.root).text(Object.size(this.files)); }, queueProgress: function(e) { var total_queue_items_done = $("> .completed, > .failed", this.selectors.queue).length, total_queue_items = $(this.selectors.queue).children().length, total_queueProgress = parseInt(100 * (parseFloat(total_queue_items_done/total_queue_items) + parseFloat((e.loaded / e.total)/total_queue_items))); $("[data-text=queue-progress]", this.selectors.root).text(total_queueProgress); }, upload: function($queue_item) { var id = $queue_item.data("id"), f = this.files[id], queue_is_url = typeof f.url !== "undefined"; var source = queue_is_url ? f.url : f; var hasForm = typeof f.formValues !== typeof undefined; if(typeof f == "undefined") { if($queue_item.next().exists()) { this.upload($queue_item.next()); } return; } $(this.selectors.close_cancel, this.selectors.root).hide().each(function() { if($(this).data("action") == "cancel-upload") $(this).show(); }); this.is_uploading = true; // Client side resizing if(!queue_is_url && f.parsedMeta.mimetype !== "image/gif" && typeof f.formValues !== typeof undefined && f.formValues.width !== f.parsedMeta.width) { isBlob = true; var canvas = $("")[0]; canvas.width = f.formValues.width; canvas.height = f.formValues.height; var ctx = canvas.getContext("2d"); ctx.drawImage(f.parsedMeta.canvas, 0, 0, canvas.width, canvas.height); source = PF.fn.dataURItoBlob(canvas.toDataURL(f.parsedMeta.mimetype)); }; // HTML5 form var form = new FormData(); var formData = { //source: source, type: queue_is_url ? "url" : "file", action: "upload", privacy: $("[data-privacy]", this.selectors.root).first().data("privacy"), timestamp: this.timestamp, auth_token: PF.obj.config.auth_token, category_id: $("[name=upload-category-id]", this.selectors.root).val() || null, nsfw: $("[name=upload-nsfw]", this.selectors.root).prop("checked") ? 1 : 0 }; if(queue_is_url) { formData.source = source; } if(hasForm) { // Merge with each queue item form data $.each(f.formValues, function(i,v) { formData[i.replace(/image_/g, "")] = v; }); }; $.each(formData, function(i,v) { form.append(i, v); }); if(typeof formData.source == typeof undefined) { form.append("source", source, f.name); } this.files[id].xhr = new XMLHttpRequest(); $queue_item.removeClass("waiting"); if(!queue_is_url) { this.files[id].xhr.upload.onprogress = function(e) { if(e.lengthComputable) { CHV.fn.uploader.queueProgress(e); percentComplete = parseInt((e.loaded / e.total) * 100); $(CHV.fn.uploader.selectors.item_progress_percent, $queue_item).text(percentComplete); $(CHV.fn.uploader.selectors.item_progress_bar, $queue_item).width(100 - percentComplete + "%"); if(percentComplete == 100) { $(CHV.fn.uploader.selectors.item_progress_percent, $queue_item).text(""); CHV.fn.uploader.itemLoading($queue_item); } } } } else { this.queueSize(); this.queueProgress({loaded: 1, total: 1}); this.itemLoading($queue_item); } this.files[id].xhr.onreadystatechange = function(){ var is_error = false; if(this.readyState == 4 && typeof CHV.fn.uploader.files[id].xhr !== "undefined" && CHV.fn.uploader.files[id].xhr.status !== 0) { $(".loading-indicator", $queue_item).remove(); $queue_item.removeClass("waiting uploading"); try { // Parse the json response var JSONresponse = this.responseType !== "json" ? JSON.parse(this.response) : this.response; if(typeof JSONresponse !== "undefined" && this.status == 200) { $("[data-group=image-link]", $queue_item).attr("href", JSONresponse.image.url_viewer); } else { if(JSONresponse.error.context == "PDOException") { JSONresponse.error.message = "Database error"; } JSONresponse.error.message = CHV.fn.uploader.files[id].name.truncate_middle() + " - " + JSONresponse.error.message; } // Save the server responses CHV.fn.uploader.results[this.status == 200 ? "success" : "error"].push(JSONresponse); if(this.status !== 200) is_error = true; } catch(err) { is_error = true; var err_handle; if(typeof JSONresponse == "undefined") { // Server epic error err_handle = { status: 500, statusText: "Internal server error" } } else { err_handle = { status: 400, statusText: JSONresponse.error.message } } JSONresponse = { status_code: err_handle.status, error: { message: CHV.fn.uploader.files[id].name.truncate_middle() + " - Server error (" + err_handle.statusText + ")", code: err_handle.status, context: "XMLHttpRequest" }, status_txt: err_handle.statusText }; CHV.fn.uploader.results.error.push(JSONresponse); console.log("server error", JSONresponse); } $queue_item.addClass(!is_error ? "completed" : "failed"); if(typeof JSONresponse.error !== "undefined" && typeof JSONresponse.error.message !== "undefined") { $queue_item.attr("rel", "tooltip").data("tiptip", "top").attr("title", JSONresponse.error.message); PF.fn.bindtipTip($queue_item); } if($queue_item.next().exists()) { CHV.fn.uploader.upload($queue_item.next()); $(CHV.fn.uploader.selectors.close_cancel, CHV.fn.uploader.selectors.root).hide().each(function() { if($(this).data("action") == "cancel-upload-remaining") $(this).show(); }); } else { CHV.fn.uploader.is_uploading = false; CHV.fn.uploader.displayResults(); } $(".done", $queue_item).fadeOut(); } }; this.files[id].xhr.open("POST", PF.obj.config.json_api, true); this.files[id].xhr.setRequestHeader("Accept", "application/json"); this.files[id].xhr.send(form); }, itemLoading: function($queue_item) { PF.fn.loading.inline($(".progress", $queue_item), {color: "#FFF", size: "normal", center: true, position: "absolute", shadow: true}); $("[data-action=cancel], [data-action=edit]", $queue_item).hide(); }, displayResults: function() { var group_result = "[data-group=upload-result][data-result=%RESULT%]", result_types = ["error", "mixed", "success"], results = {}; for(var i=0; i 0) { var error_files = []; for(var i = 0; i < this.results.error.length; i++) { error_files.push(this.results.error[i].error.message); } if(Object.size(error_files) > 0) { $(this.selectors.failed_result).html("
  • " + error_files.join("
  • ") + "
  • "); } } else { $(results.error, this.selectors.root).hide(); } // Append the embed codes if(this.results.success.length > 0 && $("[data-group=upload-result] textarea", this.selectors.root).exists()) { CHV.fn.fillEmbedCodes(this.results.success, CHV.fn.uploader.selectors.root, "val"); } if(this.results.success.length > 0 && this.results.error.length > 0) { $(results.mixed+", "+results.success, this.selectors.root).show(); } else if(this.results.success.length > 0) { $(results.success, this.selectors.root).show(); } else if(this.results.error.length > 0) { $(results.error, this.selectors.root).show(); } if($(results.success, this.selectors.root).is(":visible")) { $(results.success, this.selectors.root).find("[data-group=user], [data-group=guest]").hide(); $(results.success, this.selectors.root).find("[data-group=" + (PF.fn.is_user_logged() ? "user" : "guest") + "]").show(); if(typeof this.results.success[0].image.album !== "undefined") { $("[data-text=upload-target]").text(this.results.success[0].image.album.name); $("[data-link=upload-target]").attr("href", this.results.success[0].image.album.url); } } this.boxSizer(); this.queue_status = "done"; } }; CHV.fn.fillEmbedCodes = function(elements, parent, fn) { if(typeof fn == "undefined") { fn = "val"; } $.each(elements, function(key, value) { var image = value.image; if(!image.medium) { // Medium doesn't exists image.medium = {}; var imageProp = ["filename", "name", "width", "height", "ratio", "bits", "channels", "extension", "filename", "height", "mime", "name", "ratio", "size", "size_formatted", "url", "width"]; for(var i=0; i 0) { $.each(CHV.obj.categories, function(i,v){ if(typeof id !== "undefined" && v.id == id) return true; if(v.url_key == $("[name=form-category-url_key]", modal).val()) { used_url_key = true; return false; } }); } if(used_url_key) { PF.fn.growl.call(PF.fn._s("Category URL key already being used.")); $("[name=form-category-url_key]", modal).highlight(); return false; } return true; }, edit: { before: function(e) { var $this = $(e.target), id = $this.data("category-id"), category = CHV.obj.categories[id], modal_source = "[data-modal=" + $this.data("target") + "]"; $.each(CHV.fn.category.formFields , function(i, v) { var i = "form-category-" + v, v = category[v], $input = $("[name=" + i +"]", modal_source); if($input.is("textarea")) { $input.html(PF.fn.htmlEncode(v)); } else { $input.attr("value", v); } }); }, submit: function() { var modal = PF.obj.modal.selectors.root, id = $("[name=form-category-id]", modal).val(); if(!CHV.fn.category.validateForm(id)) { return false; } PF.obj.modal.form_data = { action: "edit", edit: "category", editing: {} }; $.each(CHV.fn.category.formFields, function(i,v) { PF.obj.modal.form_data.editing[v] = $("[name=form-category-"+v+"]", modal).val(); }); return true; }, complete: { success: function(XHR) { var category = XHR.responseJSON.category, parent = "[data-content=category][data-category-id=" + category.id + "]"; $.each(category, function(i,v) { $("[data-content=category-" + i + "]", parent).html(PF.fn.htmlEncode(v)); }); $("[data-link=category-url]").attr("href", category.url); CHV.obj.categories[category.id] = category; } } }, delete: { before: function(e) { var $this = $(e.target), id = $this.data("category-id"), category = CHV.obj.categories[id]; $this.attr("data-confirm", $this.attr("data-confirm").replace("%s", '"' + category.name + '"')); }, submit: function(id) { PF.obj.modal.form_data = { action: "delete", delete: "category", deleting: { id: id } }; return true; }, complete: { success: function(XHR) { PF.fn.growl.expirable(PF.fn._s("Category successfully deleted.")); var id = XHR.responseJSON.request.deleting.id; $("[data-content=category][data-category-id=" + id + "]").remove(); delete CHV.obj.categories[id]; } } }, add: { submit: function() { var modal = PF.obj.modal.selectors.root; if(!CHV.fn.category.validateForm()) { return false; } PF.obj.modal.form_data = { action: "add-category", category: {} }; $.each(CHV.fn.category.formFields, function(i,v) { if(v=="id") return; PF.obj.modal.form_data.category[v] = $("[name=form-category-"+v+"]", modal).val(); }); return true; }, complete: { success: function(XHR) { var category = XHR.responseJSON.category, list = "[data-content=dashboard-categories-list]", html = $("[data-content=category-dashboard-template]").html(), replaces = {}; $.each(category, function(i,v) { html = html.replace(new RegExp("%" + i.toUpperCase() + "%", "g"), v ? v : ""); }); $(list).append(html); if(Object.size(CHV.obj.categories) == 0) { CHV.obj.categories = {}; } CHV.obj.categories[category.id] = category; PF.fn.growl.call(PF.fn._s("Category %s added.", '"'+ category.name + '"')); } } } }; // IP ban edit CHV.fn.ip_ban = { formFields: ["id", "ip", "expires", "message"], validateForm: function(id) { var modal = PF.obj.modal.selectors.root, submit = true, already_banned = false, ip = $("[name=form-ip_ban-ip]", modal).val(); if(!CHV.fn.common.validateForm(modal)) { return false; } if($("[name=form-ip_ban-expires]", modal).val() !== "" && /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test($("[name=form-ip_ban-expires]", modal).val()) == false) { PF.fn.growl.call(PF.fn._s("Invalid expiration date.")); $("[name=form-ip_ban-expires]", modal).highlight(); return false; } if(Object.size(CHV.obj.ip_bans) > 0) { $.each(CHV.obj.ip_bans, function(i,v){ if(typeof id !== "undefined" && v.id == id) return true; if(v.ip == ip) { already_banned = true; return false; } }); } if(already_banned) { PF.fn.growl.call(PF.fn._s("IP %s already banned.", ip)); $("[name=form-ip_ban-ip]", modal).highlight(); return false; } return true; }, add: { submit: function() { var modal = PF.obj.modal.selectors.root; if(!CHV.fn.ip_ban.validateForm()) { return false; } PF.obj.modal.form_data = { action: "add-ip_ban", ip_ban: {} }; $.each(CHV.fn.ip_ban.formFields, function(i,v) { if(v=="id") return; PF.obj.modal.form_data.ip_ban[v] = $("[name=form-ip_ban-"+v+"]", modal).val(); }); return true; }, complete: { success: function(XHR) { var ip_ban = XHR.responseJSON.ip_ban, list = "[data-content=dashboard-ip_bans-list]", html = $("[data-content=ip_ban-dashboard-template]").html(), replaces = {}; if(typeof html !== "undefined") { $.each(ip_ban, function(i,v) { html = html.replace(new RegExp("%" + i.toUpperCase() + "%", "g"), v ? v : ""); }); $(list).append(html); } if(Object.size(CHV.obj.ip_bans) == 0) { CHV.obj.ip_bans = {}; } CHV.obj.ip_bans[ip_ban.id] = ip_ban; $("[data-content=ban_uploader_ip]").hide(); $("[data-content=banned_uploader_ip]").show(); PF.fn.growl.call(PF.fn._s("IP %s banned.", ip_ban.ip)); }, error: function(XHR) { // experimental var error = XHR.responseJSON.error; PF.fn.growl.call(PF.fn._s(error.message)); } } }, edit: { before: function(e) { var $this = $(e.target), id = $this.data("ip_ban-id"), target = CHV.obj.ip_bans[id], modal_source = "[data-modal=" + $this.data("target") + "]"; $.each(CHV.fn.ip_ban.formFields , function(i, v) { var i = "form-ip_ban-" + v, v = target[v], $input = $("[name=" + i +"]", modal_source); if($input.is("textarea")) { $input.html(PF.fn.htmlEncode(v)); } else { $input.attr("value", v); } }); }, submit: function() { var modal = PF.obj.modal.selectors.root, id = $("[name=form-ip_ban-id]", modal).val(); if(!CHV.fn.ip_ban.validateForm(id)) { return false; } PF.obj.modal.form_data = { action: "edit", edit: "ip_ban", editing: {} }; $.each(CHV.fn.ip_ban.formFields, function(i,v) { PF.obj.modal.form_data.editing[v] = $("[name=form-ip_ban-"+v+"]", modal).val(); }); return true; }, complete: { success: function(XHR) { var ip_ban = XHR.responseJSON.ip_ban, parent = "[data-content=ip_ban][data-ip_ban-id=" + ip_ban.id + "]"; $.each(ip_ban, function(i,v) { $("[data-content=ip_ban-" + i + "]", parent).html(PF.fn.htmlEncode(v)); }); CHV.obj.ip_bans[ip_ban.id] = ip_ban; } } }, delete: { before: function(e) { var $this = $(e.target), id = $this.data("ip_ban-id"), ip_ban = CHV.obj.ip_bans[id]; $this.attr("data-confirm", $this.attr("data-confirm").replace("%s", ip_ban.ip)); }, submit: function(id) { PF.obj.modal.form_data = { action: "delete", delete: "ip_ban", deleting: { id: id } }; return true; }, complete: { success: function(XHR) { PF.fn.growl.expirable(PF.fn._s("IP ban successfully deleted.")); var id = XHR.responseJSON.request.deleting.id; $("[data-content=ip_ban][data-ip_ban-id=" + id + "]").remove(); delete CHV.obj.ip_bans[id]; } } } }; // Storage edit CHV.fn.storage = { formFields: ["id", "name", "api_id", "bucket", "server", "capacity", "region", "key", "secret", "url", "account_id", "account_name"], calling: false, validateForm: function() { var modal = PF.obj.modal.selectors.root, id = $("[name=form-storage-id]", modal).val(), submit = true; $.each($(":input", modal), function(i,v) { if($(this).is(":hidden")) { if($(this).attr("required")) { $(this).removeAttr("required").attr("data-required", 1); } } else { if($(this).attr("data-required") == 1) { $(this).attr("required", "required"); } } if($(this).is(":visible") && $(this).val() == "" && $(this).attr("required")) { $(this).highlight(); submit = false; } }); if(!submit) { PF.fn.growl.call(PF.fn._s("Please fill all the required fields.")); return false; } // Validate storage capacity var $storage_capacity = $("[name=form-storage-capacity]", modal), storage_capacity = $storage_capacity.val(), capacity_error_msg; if(storage_capacity !== "") { if(/^[\d\.]+\s*[A-Za-z]{2}$/.test(storage_capacity) == false || typeof storage_capacity.getBytes() == "undefined") { capacity_error_msg = PF.fn._s("Invalid storage capacity value. Make sure to use a valid format."); } else if(typeof CHV.obj.storages[id] !== "undefined" && storage_capacity.getBytes() < CHV.obj.storages[id].space_used) { capacity_error_msg = PF.fn._s("Storage capacity can't be lower than its current usage (%s).", CHV.obj.storages[id].space_used.formatBytes()); } if(capacity_error_msg) { PF.fn.growl.call(capacity_error_msg); $storage_capacity.highlight(); return false; } } if(/^https?:\/\/.+$/.test($("[name=form-storage-url]", modal).val()) == false) { PF.fn.growl.call(PF.fn._s("Invalid URL.")); $("[name=form-storage-url]", modal).highlight(); return false; } return true; }, toggleHttps: function(id) { this.toggleBool(id, "https"); }, toggleActive: function(id) { this.toggleBool(id, "active"); }, toggleBool: function(id, string) { if(this.calling) return; this.calling = true; var $root = $("[data-storage-id="+id+"]"), $parent = $("[data-content=storage-" + string + "]", $root), $el = $("[data-checkbox]", $parent), checked = CHV.obj.storages[id]["is_" + string], toggle = checked == 0 ? 1 : 0, data = { action: "edit", edit: "storage", editing: { id: id } }; data.editing["is_" + string] = toggle; if(string == "https") { data.editing.url = CHV.obj.storages[id].url; } PF.fn.loading.fullscreen(); $.ajax({data: data}) .always(function(data, status, XHR) { CHV.fn.storage.calling = false; PF.fn.loading.destroy("fullscreen"); if(typeof data.storage == "undefined") { PF.fn.growl.call(data.responseJSON.error.message); return; } var storage = data.storage; CHV.obj.storages[storage.id] = storage; PF.fn.growl.expirable(PF.fn._s("Storage successfully edited.")); switch(string) { case "https": $("[data-content=storage-url]", $root).html(storage.url); break; } CHV.fn.storage.toggleBoolDisplay($el, toggle); CHV.fn.queuePixel(); // For the lulz }); }, edit: { before: function(e) { var $this = $(e.target), id = $this.data("storage-id"), storage = CHV.obj.storages[id], modal_source = "[data-modal=" + $this.data("target") + "]", combo = "[data-combo-value~=" + storage['api_id'] + "]"; $.each(CHV.fn.storage.formFields, function(i, v) { var i = "form-storage-" + v, v = storage[v], $combo_input = $(combo + " [name=" + i +"]", modal_source), $global_input = $("[name=" + i +"]", modal_source), $input = $combo_input.exists() ? $combo_input : $global_input; if($input.is("textarea")) { $input.html(PF.fn.htmlEncode(v)); } else if($input.is("select")) { $("option", $input).removeAttr("selected"); $("option", $input).each(function() { if($(this).attr("value") == v) { $(this).attr("selected", "selected"); return false; } }); } else { if($input.is("[name=form-storage-capacity]") && typeof v !== "undefined" && v > 0) { v = v.formatBytes(2); } $input.attr("value", v); } }); // Co-combo breaker $("[data-combo-value]").addClass("soft-hidden"); $(combo).removeClass("soft-hidden"); }, submit: function() { var modal = PF.obj.modal.selectors.root, id = $("[name=form-storage-id]", modal).val(), used_url_key = false; if(!CHV.fn.storage.validateForm()) { return false; } PF.obj.modal.form_data = { action: "edit", edit: "storage", editing: {} }; $.each(CHV.fn.storage.formFields, function(i,v) { var sel; sel = "[name=form-storage-"+v+"]"; if($(sel, modal).attr("type") !== "hidden") { sel += ":visible" } PF.obj.modal.form_data.editing[v] = $(sel, modal).val(); }); return true; }, complete: { success: function(XHR) { var storage = XHR.responseJSON.storage, parent = "[data-content=storage][data-storage-id=" + storage.id + "]", $el = $("[data-action=toggle-storage-https]", parent); $.each(storage, function(i,v) { $("[data-content=storage-" + i + "]", parent).html(PF.fn.htmlEncode(v)); }); CHV.obj.storages[storage.id] = storage; CHV.fn.storage.toggleBoolDisplay($el, storage['is_https'] == 1); CHV.fn.queuePixel(); // For the lulz }, error: function(XHR) { var response = XHR.responseJSON, message = response.error.message; PF.fn.growl.call(message); } } }, add: { submit: function() { if(!CHV.fn.storage.validateForm()) { return false; } var modal = PF.obj.modal.selectors.root; PF.obj.modal.form_data = { action: "add-storage", storage: {} }; $.each(CHV.fn.storage.formFields, function(i,v) { if(v=="id") return; var sel; sel = "[name=form-storage-"+v+"]"; if($(sel, modal).attr("type") !== "hidden") { sel += ":visible" } PF.obj.modal.form_data.storage[v] = $(sel, modal).val(); }); return true; }, complete: { success: function(XHR) { var storage = XHR.responseJSON.storage, list = "[data-content=dashboard-storages-list]", html = $("[data-content=storage-dashboard-template]").html(), replaces = {}; $.each(storage, function(i,v) { var upper = i.toUpperCase(); if(i == "is_https" || i == "is_active") { var v = CHV.obj.storageTemplate.icon.replace("%TITLE%", CHV.obj.storageTemplate.messages[i]).replace("%ICON%", CHV.obj.storageTemplate.checkboxes[v]).replace("%PROP%", i.replace("is_", "")); } html = html.replace(new RegExp("%" + upper + "%", "g"), v ? v : ""); }); $(list).append(html); PF.fn.bindtipTip($("[data-storage-id="+storage.id+"]")); if(CHV.obj.storages.length == 0) { CHV.obj.storages = {}; } CHV.obj.storages[storage.id] = storage; CHV.fn.queuePixel(); // For the lulz }, error: function(XHR) { var response = XHR.responseJSON, message = response.error.message; PF.fn.growl.call(message); } } }, toggleBoolDisplay: function($el, toggle) { var icons = { 0: $el.data("unchecked-icon"), 1: $el.data("checked-icon") }; $el.removeClass(icons[0] + " " + icons[1]).addClass(icons[toggle ? 1 : 0]); } }; CHV.fn.common = { validateForm: function(modal) { if(typeof modal == "undefined") { var modal = PF.obj.modal.selectors.root } var submit = true; $.each($(":input:visible", modal), function(i,v) { if($(this).val() == "" && $(this).attr("required")) { $(this).highlight(); submit = false; } }); if(!submit) { PF.fn.growl.call(PF.fn._s("Please fill all the required fields.")); return false; } return true; }, updateDoctitle: function(pre_doctitle) { if(typeof CHV.obj.page_info !== typeof undefined) { CHV.obj.page_info.pre_doctitle = pre_doctitle; CHV.obj.page_info.doctitle = CHV.obj.page_info.pre_doctitle + CHV.obj.page_info.pos_doctitle; document.title = CHV.obj.page_info.doctitle; } } }; CHV.fn.user = { add: { submit: function() { var $modal = $(PF.obj.modal.selectors.root), submit = true; $.each($(":input", $modal), function(i,v) { if($(this).val() == "" && $(this).attr("required")) { $(this).highlight(); submit = false; } }); if(!submit) { PF.fn.growl.call(PF.fn._s("Please fill all the required fields.")); return false; } PF.obj.modal.form_data = { action: "add-user", user: { username: $("[name=form-username]", $modal).val(), email: $("[name=form-email]", $modal).val(), password: $("[name=form-password]", $modal).val(), role: $("[name=form-role]", $modal).val() } }; return true; }, complete: { success: function(XHR) { var response = XHR.responseJSON; PF.fn.growl.expirable(PF.fn._s("User added successfully.")); }, error: function(XHR) { var response = XHR.responseJSON; PF.fn.growl.call(PF.fn._s(response.error.message)); } } }, delete: { submit: function() { PF.obj.modal.form_data = { action: "delete", delete: "user", owner: CHV.obj.resource.user.id, deleting: CHV.obj.resource.user }; return true; } } }; // Resource delete CHV.fn.submit_resource_delete = function() { PF.obj.modal.form_data = { action: "delete", delete: CHV.obj.resource.type, from: "resource", owner: typeof CHV.obj.resource.user !== "undefined" ? CHV.obj.resource.user.id : null, deleting: CHV.obj.resource }; return true; }; CHV.fn.complete_resource_delete = { success: function(XHR) { var response = XHR.responseJSON; $("body").fadeOut("normal", function() { var redir; if(CHV.obj.resource.type == "album" || CHV.obj.resource.type == "image") { redir = CHV.obj.resource.parent_url; } else { redir = CHV.obj.resource.user ? CHV.obj.resource.user.url : CHV.obj.resource.url; } if(typeof redir !== "undefined") { window.location = redir + "?deleted"; } }); } }; CHV.fn.list_editor = { // Update all the selection counts selectionCount: function() { var $content_listing = $(PF.obj.listing.selectors.content_listing); $content_listing.each(function() { var $listing_options = $("[data-content=pop-selection]", "[data-content=list-selection][data-tab=" + $(this).attr("id") + "]"), selection_count = $(PF.obj.listing.selectors.list_item+".selected", this).length; all_count = $(PF.obj.listing.selectors.list_item, this).length; $listing_options[selection_count > 0 ? "removeClass" : "addClass"]("disabled"); $("[data-text=selection-count]", $listing_options).text(selection_count > 0 ? selection_count : ""); // Sensitive display if($content_listing.data('list') == 'images' && selection_count > 0) { var has_sfw = $(PF.obj.listing.selectors.list_item+".selected[data-flag=safe]", this).length > 0, has_nsfw = $(PF.obj.listing.selectors.list_item+".selected[data-flag=unsafe]", this).length > 0; $("[data-action=flag-safe]", $listing_options)[(has_nsfw ? "remove" : "add") + "Class"]("hidden"); $("[data-action=flag-unsafe]", $listing_options)[(has_sfw ? "remove" : "add") + "Class"]("hidden"); } if($(this).is(":visible")) { CHV.fn.list_editor.listMassActionSet(all_count == selection_count ? "clear" : "select"); } }); }, // Remove (delete or move) items from list removeFromList: function($target, msg) { if(typeof $target == "undefined") return; var $target = $target instanceof jQuery == false ? $($target) : $target, $content_listing = $(PF.obj.listing.selectors.content_listing_visible), target_size = $target.length; $target.fadeOut("fast"); // Promise // Update counts var type = $target.first().data("type"), new_count = parseInt($("[data-text="+type+"-count]").text()) - target_size; CHV.fn.list_editor.updateUserCounters($target.first().data("type"), target_size, "-"); $target.promise().done(function() { // Get count related to each list var affected_content_lists = {}; $target.each(function() { $("[data-id="+$(this).data("id")+"]").each(function(){ var list_id = $(this).closest(PF.obj.listing.selectors.content_listing).attr("id"); if(!affected_content_lists[list_id]) { affected_content_lists[list_id] = 0; } affected_content_lists[list_id] += 1; }); }); if(target_size == 1) { $("[data-id="+$(this).data("id")+"]").remove(); } else { $target.each(function(){ $("[data-id="+$(this).data("id")+"]").remove(); }); } PF.fn.listing.columnizerQueue(); PF.fn.listing.refresh(); CHV.fn.list_editor.selectionCount(); if(typeof msg !== "undefined" && typeof msg == "string") { PF.fn.growl.expirable(msg); } // Update offset list (+stock) for(var k in affected_content_lists) { var $list = $("#"+k), stock_offset = $list.data("offset"), offset = - affected_content_lists[k];; stock_offset = (typeof stock_offset == "undefined") ? 0 : parseInt(stock_offset); $list.data("offset", stock_offset + offset); } if(!$(PF.obj.listing.selectors.content_listing_pagination, $content_listing).exists() && $(".list-item", $content_listing).length == 0) { new_count = 0; } // On zero add the empty template if(new_count == 0) { $content_listing.html(PF.obj.listing.template.empty); // Reset ajaxed status of all $(PF.obj.listing.selectors.content_listing+":not("+PF.obj.listing.selectors.content_listing_visible+")").data({empty: null, load: "ajax"}); $("[data-content=list-selection][data-tab="+$content_listing.attr("id")+"]").addClass("disabled"); } else { // Count isn't zero.. But the view? if($(PF.obj.listing.selectors.list_item, $content_listing).length == 0) { $(PF.obj.listing.selectors.pad_content).height(0); $content_listing.find("[data-action=load-more]").click(); PF.obj.listing.recolumnize = true; } } }); }, deleteFromList: function($target) { if(typeof growl == "undefined") { var growl = true; } var $target = $target instanceof jQuery == false ? $($target) : $target; this.removeFromList($target, growl ? PF.fn._s("The content has been deleted.") : null); }, moveFromList: function($target, growl) { if(typeof growl == "undefined") { var growl = true; } var $target = $target instanceof jQuery == false ? $($target) : $target; this.removeFromList($target, growl ? PF.fn._s("The content has been moved.") : null); }, toggleSelectItem: function($list_item, select) { if(typeof select !== "boolean") { var select = true; } var $icon = $("[data-action=select] .btn-icon", $list_item), add_class, remove_class, label_text; if(!select){ $list_item.removeClass("selected").find(".list-item-image-tools").css("display", "none"); add_class = $icon.data("icon-unselected"); remove_class = $icon.data("icon-selected"); label_text = PF.fn._s("Select"); setTimeout(function() { // Nifty hack to prevent flicker $list_item.find(".list-item-image-tools").css("display", ""); }, 0); } else { $list_item.addClass("selected"); add_class = $icon.data("icon-selected"); remove_class = $icon.data("icon-unselected"); label_text = PF.fn._s("Unselect"); } $("[data-action=select] .label", $list_item).text(label_text); $icon.removeClass(remove_class).addClass(add_class); CHV.fn.list_editor.selectionCount(); }, selectItem: function($list_item) { this.toggleSelectItem($list_item, true); }, unselectItem: function($list_item) { this.toggleSelectItem($list_item, false); }, clearSelection: function(all) { var $targets = $(PF.obj.listing.selectors.list_item+".selected", PF.obj.listing.selectors[all ? "content_listing" : "content_listing_visible"]); this.unselectItem($targets); this.listMassActionSet("select"); }, listMassActionSet: function(action) { var current = action == "select" ? "clear" : "select"; var $target = $("[data-action=list-" + current + "-all]:visible"); var text = $target.data("text-" + action + "-all"); $target.text(text).attr("data-action", "list-" + action + "-all"); }, updateItem: function($target, response, action, growl) { if($target instanceof jQuery == false) { var $target = $($target); } var dealing_with = $target.data("type"), album = dealing_with == "image" ? response.album : response; this.addAlbumtoModals(album); $("option[value="+album.id_encoded+"]","[name=form-album-id]").html(PF.fn.htmlEncode(album.name)); if(typeof action == "undefined") { var action = "edit"; } if(action == "edit" || action == "move") { if(action == "move" && CHV.obj.resource.type == "album") { CHV.fn.list_editor.moveFromList($target, growl); return } $target.data("description", response.description); if(dealing_with == "image") { if(typeof response.title !== typeof undefined) { $target.data("title", response.title); $target.find("[title]").attr("title", response.title); $("[data-text=image-title]", $target).html(PF.fn.htmlEncode(response.title)); } if(typeof response.title_truncated !== typeof undefined) { $("[data-text=image-title-truncated]", $target).html(PF.fn.htmlEncode(response.title_truncated)); } if(typeof response.category_id !== typeof undefined) { $target.data("category-id", response.category_id); } $target.data({"album-id": album.id_encoded, flag: response.nsfw == 1 ? "unsafe" : "safe"}).removeClass("safe unsafe").addClass(response.nsfw == 1 ? "unsafe" : "safe"); $("[data-content=album-link]", $target).attr("href", album.url); } else { $target.data("privacy", album.privacy); $target.data("name", album.name); } $target.removeClass("privacy-public privacy-private").addClass("privacy-" + album.privacy); $("[data-text=album-name]", $target).html(PF.fn.htmlEncode(album.name)); PF.fn.growl.expirable(action == "edit" ? PF.fn._s("The content has been edited.") : PF.fn._s("The content has been moved.")); } }, addAlbumtoModals: function(album) { var added = false; $("[name=form-album-id]", "[data-modal]").each(function(){ if(album.id_encoded && !$("option[value=" + album.id_encoded + "]", this).exists()) { $(this).append(''); added = true; } }); if(added) { CHV.fn.list_editor.updateUserCounters("album", 1, "+"); } }, updateAlbum: function(album) { $("[data-id="+album.id_encoded+"]").each(function() { if(album.html !== "") { $(this).after(album.html); $(this).remove(); } }); }, updateUserCounters: function(counter, number, operation) { if(typeof operation == "undefined") { var operation = "+"; } // Current resource counter var $count = $("[data-text="+counter+"-count]"), $count_label = $("[data-text="+counter+"-label]"), number = parseInt(number), old_count = parseInt($count.html()), new_count, delta; switch(operation) { case "+": new_count = old_count + number; break; case "-": new_count = old_count - number; break; case "=": new_count = number; break; } delta = new_count - old_count; // Total counter var $total_count = $("[data-text=total-"+$count.data("text")+"]"), $total_count_label = $("[data-text="+$total_count.data("text")+"-label]"), old_total_count = parseInt($total_count.html()), new_total_count = old_total_count + delta; $count.text(new_count); $total_count.text(new_total_count); $count_label.text($count_label.data(new_count == 1 ? "label-single" : "label-plural")); $total_count_label.text($count_label.data(new_total_count == 1 ? "label-single" : "label-plural")); }, updateMoveItemLists: function(response, dealing_with, $targets) { CHV.fn.list_editor.clearSelection(); if(/image/.test(dealing_with)) { /*if( (response.request.editing && response.request.editing.new_album == "true") || (response.request.album && response.request.album.new == "true")) { //CHV.fn.list_editor.updateUserCounters("album", 1); }*/ if(dealing_with == "image") { // single CHV.fn.list_editor.updateItem("[data-id="+$targets.data("id")+"]", response.image, "move"); } else { $targets.each(function() { CHV.fn.list_editor.updateItem("[data-id="+$(this).data("id")+"]", response, "move", false); }); PF.fn.growl.expirable(PF.fn._s("The content has been moved.")); } } else { // /album? if(CHV.obj.resource.type == "album") { CHV.fn.list_editor.moveFromList($targets); } else { PF.fn.growl.expirable(PF.fn._s("The content has been moved.")); } if(typeof response.albums_old !== "undefined") { for(var i=0; i'; $("body").append(img); }