mirror of
https://github.com/BobbyWibowo/lolisafe.git
synced 2024-12-15 00:46:22 +00:00
3d09df501d
Better 'df' handling (check the TODO entry for more details). Simplified a few lines in dashboard.js. Bumped v1 version string.
3 lines
56 KiB
JavaScript
3 lines
56 KiB
JavaScript
var lsKeys={token:"token",viewType:{uploads:"viewTypeUploads",uploadsAll:"viewTypeUploadsAll"},selected:{uploads:"selectedUploads",uploadsAll:"selectedUploadsAll",users:"selectedUsers"}},page={dom:null,token:localStorage[lsKeys.token],username:null,permissions:null,menusContainer:null,menus:[],currentView:null,views:{uploads:{type:localStorage[lsKeys.viewType.uploads],album:null,pageNum:null},uploadsAll:{type:localStorage[lsKeys.viewType.uploadsAll],filters:null,pageNum:null,all:!0},users:{pageNum:null}},selected:{uploads:[],uploadsAll:[],users:[]},checkboxes:{uploads:[],uploadsAll:[],users:[]},lastSelected:{upload:null,uploadsAll:null,user:null},selectAlbumContainer:null,cache:{uploads:{},albums:{},users:{}},clipboardJS:null,lazyLoad:null,imageExts:[".webp",".jpg",".jpeg",".gif",".png",".tiff",".tif",".svg"],videoExts:[".webm",".mp4",".wmv",".avi",".mov",".mkv"],isTriggerLoading:null,fadingIn:null,albumTitleMaxLength:70,albumDescMaxLength:4e3,unhide:function(){document.querySelector("#loader").classList.add("is-hidden"),document.querySelector("#dashboard").classList.remove("is-hidden")},onError:function(e){console.error(e);var a=document.createElement("div");return a.innerHTML="<code>"+e.toString()+"</code>",swal({title:"An error occurred!",icon:"error",content:a})},onAxiosError:function(e){console.error(e);var a={520:"Unknown Error",521:"Web Server Is Down",522:"Connection Timed Out",523:"Origin Is Unreachable",524:"A Timeout Occurred",525:"SSL Handshake Failed",526:"Invalid SSL Certificate",527:"Railgun Error",530:"Origin DNS Error"}[e.response.status]||e.response.statusText,t=e.response.data&&e.response.data.description?e.response.data.description:"There was an error with the request, please check the console for more information.";return swal(e.response.status+" "+a,t,"error")},preparePage:function(){page.token?page.verifyToken(page.token,!0):window.location="auth"},verifyToken:function(e,a){axios.post("api/tokens/verify",{token:e}).then((function(t){if(!1===t.data.success)return swal({title:"An error occurred!",text:t.data.description,icon:"error"}).then((function(){a&&(localStorage.removeItem(lsKeys.token),window.location="auth")}));axios.defaults.headers.common.token=e,localStorage[lsKeys.token]=e,page.token=e,page.username=t.data.username,page.permissions=t.data.permissions,page.prepareDashboard()})).catch(page.onAxiosError)},prepareDashboard:function(){page.dom=document.querySelector("#page"),page.dom.addEventListener("click",page.domClick,!0),page.dom.addEventListener("submit",(function(e){if(e.target&&e.target.classList.contains("prevent-default"))return e.preventDefault()}),!0),page.menusContainer=document.querySelector("#menu");for(var e=[{selector:"#itemUploads",onclick:page.getUploads},{selector:"#itemDeleteUploadsByNames",onclick:page.deleteUploadsByNames},{selector:"#itemManageAlbums",onclick:page.getAlbums},{selector:"#itemManageToken",onclick:page.changeToken},{selector:"#itemChangePassword",onclick:page.changePassword},{selector:"#itemLogout",onclick:page.logout},{selector:"#itemManageUploads",onclick:page.getUploads,params:{all:!0},group:"moderator"},{selector:"#itemStatistics",onclick:page.getStatistics,group:"admin"},{selector:"#itemManageUsers",onclick:page.getUsers,group:"admin"}],a=function(a){if(!e[a].group||page.permissions[e[a].group]){var t=document.querySelector(e[a].selector);t.addEventListener("click",(function(t){page.menusContainer.classList.contains("is-loading")||e[a].onclick.call(null,Object.assign({trigger:t.currentTarget},e[a].params||{}))})),t.classList.remove("is-hidden"),page.menus.push(t)}},t=0;t<e.length;t++)a(t);page.permissions.moderator&&(document.querySelector("#itemLabelAdmin").classList.remove("is-hidden"),document.querySelector("#itemListAdmin").classList.remove("is-hidden")),document.querySelector("#itemLogout").innerHTML="Logout ( "+page.username+" )",page.unhide(),page.getAlbumsSidebar(),"function"==typeof page.prepareShareX&&page.prepareShareX()},logout:function(e){page.updateTrigger(e.trigger,"active"),localStorage.removeItem(lsKeys.token),window.location="auth"},updateTrigger:function(e,a){if(e)if("loading"===a?page.menusContainer.classList.add("is-loading"):page.menusContainer.classList.remove("is-loading"),"loading"===a)e.classList.add("is-loading");else if("active"===a){if("LI"!==e.parentNode.tagName)return;for(var t=0;t<page.menus.length;t++)page.menus[t].classList.remove("is-active");e.classList.remove("is-loading"),e.classList.add("is-active")}else e.classList.remove("is-loading"),e.classList.remove("is-active")},getItemID:function(e){var a=e.parentNode;return e.parentNode.classList.contains("controls")&&(a=a.parentNode),parseInt(a.dataset.id)},domClick:function(e){var a=e.target;if(a&&(["I"].includes(a.tagName)&&["SPAN"].includes(a.parentNode.tagName)&&(a=a.parentNode),["SPAN"].includes(a.tagName)&&["A","BUTTON"].includes(a.parentNode.tagName)&&(a=a.parentNode),a.dataset&&a.dataset.action&&!a.hasAttribute("disabled"))){e.stopPropagation();var t=page.getItemID(a),n=a.dataset.action;switch(n){case"view-list":return page.setUploadsView("list",a);case"view-thumbs":return page.setUploadsView("thumbs",a);case"clear-selection":return page.clearSelection();case"add-selected-uploads-to-album":return page.addSelectedUploadsToAlbum();case"select":return page.select(a,e);case"select-all":return page.selectAll(a);case"add-to-album":return page.addToAlbum(t);case"delete-upload":return page.deleteUpload(t);case"bulk-delete-uploads":return page.bulkDeleteUploads();case"display-preview":return page.displayPreview(t);case"submit-album":return page.submitAlbum(a);case"edit-album":return page.editAlbum(t);case"delete-album":return page.deleteAlbum(t);case"get-new-token":return page.getNewToken(a);case"edit-user":return page.editUser(t);case"disable-user":return page.disableUser(t);case"delete-user":return page.deleteUser(t);case"filters-help":return page.filtersHelp(a);case"filter-uploads":return page.filterUploads(a);case"view-user-uploads":return page.viewUserUploads(t,a);case"page-ellipsis":return page.focusJumpToPage();case"page-prev":case"page-next":case"page-goto":case"jump-to-page":return page.switchPage(n,a)}}},fadeAndScroll:function(e){page.fadingIn&&(clearTimeout(page.fadingIn),page.dom.classList.remove("fade-in")),e||(page.dom.classList.add("fade-in"),page.fadingIn=setTimeout((function(){page.dom.classList.remove("fade-in")}),500)),page.dom.scrollIntoView({behavior:e?"auto":"smooth",block:"start",inline:"nearest"})},switchPage:function(e,a){var t=Object.assign({trigger:a},page.views[page.currentView]),n="users"===page.currentView?page.getUsers:page.getUploads;switch(e){case"page-prev":return t.pageNum=page.views[page.currentView].pageNum-1,t.pageNum<0?swal("An error occurred!","This is already the first page.","error"):n(t);case"page-next":return t.pageNum=page.views[page.currentView].pageNum+1,n(t);case"page-goto":return t.pageNum=parseInt(a.dataset.goto),n(t);case"jump-to-page":var s=document.querySelector("#jumpToPage");if(!s.checkValidity())return;var i=parseInt(s.value);return t.pageNum=isNaN(i)?0:i-1,t.pageNum<0&&(t.pageNum=0),n(t)}},focusJumpToPage:function(){var e=document.querySelector("#jumpToPage");e&&(e.focus(),e.select())},getUploads:function(e){if(void 0===e&&(e={}),void 0===e&&(e={}),(e.all||e.filters)&&!page.permissions.moderator)return swal("An error occurred!","You can not do this!","error");page.updateTrigger(e.trigger,"loading"),("number"!=typeof e.pageNum||e.pageNum<0)&&(e.pageNum=0);var a=void 0!==e.album?"api/album/"+e.album+"/"+e.pageNum:"api/uploads/"+e.pageNum,t={all:e.all?"1":"",filters:e.filters||""};axios.get(a,{headers:t}).then((function(a){if(!1===a.data.success)return"No token provided"===a.data.description?page.verifyToken(page.token):(page.updateTrigger(e.trigger),swal("An error occurred!",a.data.description,"error"));var t=Math.ceil(a.data.count/25),n=a.data.files;if(e.pageNum&&0===n.length)return e.autoPage?(e.pageNum=t-1,page.getUploads(e)):(page.updateTrigger(e.trigger),swal("An error occurred!","There are no more uploads to populate page "+(e.pageNum+1)+".","error"));page.currentView=e.all?"uploadsAll":"uploads",page.cache.uploads={};var s=a.data.albums,i=a.data.users,l=a.data.basedomain,r=page.paginate(a.data.count,25,e.pageNum),o='<div class="column is-hidden-mobile"></div>';e.all&&(o='\n <div class="column">\n <form class="prevent-default">\n <div class="field has-addons">\n <div class="control is-expanded">\n <input id="filters" class="input is-small" type="text" placeholder="Filters" value="'+(e.filters||"")+'">\n </div>\n <div class="control">\n <button type="button" class="button is-small is-primary is-outlined" title="Help?" data-action="filters-help">\n <span class="icon">\n <i class="icon-help-circled"></i>\n </span>\n </button>\n </div>\n <div class="control">\n <button type="submit" class="button is-small is-info is-outlined" title="Filter uploads" data-action="filter-uploads">\n <span class="icon">\n <i class="icon-filter"></i>\n </span>\n </button>\n </div>\n </div>\n </form>\n </div>\n ');for(var c='\n <div class="columns">\n '+o+'\n <div class="column is-one-quarter">\n <form class="prevent-default">\n <div class="field has-addons">\n <div class="control is-expanded">\n <input id="jumpToPage" class="input is-small" type="number" min="1" max="'+t+'" value="'+(e.pageNum+1)+'"'+(1===t?" disabled":"")+'>\n </div>\n <div class="control">\n <button type="submit" class="button is-small is-info is-outlined" title="Jump to page" data-action="jump-to-page">\n <span class="icon">\n <i class="icon-paper-plane"></i>\n </span>\n </button>\n </div>\n </div>\n </form>\n </div>\n </div>\n ',d='\n <div class="columns">\n <div class="column is-hidden-mobile"></div>\n <div class="column has-text-centered">\n <a class="button is-small is-danger is-outlined" title="List view" data-action="view-list">\n <span class="icon">\n <i class="icon-th-list"></i>\n </span>\n </a>\n <a class="button is-small is-danger is-outlined" title="Thumbs view" data-action="view-thumbs">\n <span class="icon">\n <i class="icon-th-large"></i>\n </span>\n </a>\n </div>\n <div class="column has-text-right">\n <a class="button is-small is-info is-outlined" title="Clear selection" data-action="clear-selection">\n <span class="icon">\n <i class="icon-cancel"></i>\n </span>\n </a>\n '+(e.all?"":'\n <a class="button is-small is-warning is-outlined" title="Bulk add to album" data-action="add-selected-uploads-to-album">\n <span class="icon">\n <i class="icon-plus"></i>\n </span>\n </a>')+'\n <a class="button is-small is-danger is-outlined" title="Bulk delete" data-action="bulk-delete-uploads">\n <span class="icon">\n <i class="icon-trash"></i>\n </span>\n <span>Bulk delete</span>\n </a>\n </div>\n </div>\n ',u=!1,p=n.some((function(e){return void 0!==e.expirydate})),g=0;g<n.length;g++){n[g].file=l+"/"+n[g].name,n[g].thumb&&(n[g].thumb=l+"/"+n[g].thumb),n[g].type="other";var m=/.[\w]+(\?|$)/.exec(n[g].file),h=m&&m[0]?m[0].toLowerCase():null;page.imageExts.includes(h)?n[g].type="picture":page.videoExts.includes(h)&&(n[g].type="video"),page.cache.uploads[n[g].id]={name:n[g].name,thumb:n[g].thumb,original:n[g].file,type:n[g].type},n[g].prettyBytes=page.getPrettyBytes(parseInt(n[g].size)),n[g].prettyDate=page.getPrettyDate(new Date(1e3*n[g].timestamp)),p&&(n[g].prettyExpiryDate=n[g].expirydate?page.getPrettyDate(new Date(1e3*n[g].expirydate)):null),n[g].selected=page.selected[page.currentView].includes(n[g].id),n[g].selected||(u=!0),e.all?n[g].appendix=n[g].userid&&i[n[g].userid]||"":void 0===e.album&&(n[g].appendix=n[g].albumid&&s[n[g].albumid]||"")}if("thumbs"===page.views[page.currentView].type){page.dom.innerHTML="\n "+r+"\n "+c+"\n "+d+'\n <div id="table" class="columns is-multiline is-mobile is-centered">\n </div>\n '+r+"\n ";for(var b=document.querySelector("#table"),v=0;v<n.length;v++){var f=n[v],w=document.createElement("div");w.className="image-container column",w.dataset.id=f.id,void 0!==f.thumb?w.innerHTML='<a class="image" href="'+f.file+'" target="_blank" rel="noopener"><img alt="'+f.name+'" data-src="'+f.thumb+'"/></a>':w.innerHTML='<a class="image" href="'+f.file+'" target="_blank" rel="noopener"><h1 class="title">'+(f.extname||"N/A")+"</h1></a>",w.innerHTML+='\n <input type="checkbox" class="checkbox" title="Select" data-index="'+v+'" data-action="select"'+(f.selected?" checked":"")+'>\n <div class="controls">\n '+(f.thumb?'\n <a class="button is-small is-primary" title="Display preview" data-action="display-preview">\n <span class="icon">\n <i class="'+("other"!==f.type?"icon-"+f.type:"icon-doc-inv")+'"></i>\n </span>\n </a>':"")+'\n <a class="button is-small is-info clipboard-js" title="Copy link to clipboard" data-clipboard-text="'+f.file+'">\n <span class="icon">\n <i class="icon-clipboard"></i>\n </span>\n </a>\n <a class="button is-small is-warning" title="Add to album" data-action="add-to-album">\n <span class="icon">\n <i class="icon-plus"></i>\n </span>\n </a>\n <a class="button is-small is-danger" title="Delete" data-action="delete-upload">\n <span class="icon">\n <i class="icon-trash"></i>\n </span>\n </a>\n </div>\n <div class="details">\n <p><span class="name">'+f.name+"</span></p>\n <p>"+(f.appendix?"<span>"+f.appendix+"</span> – ":"")+f.prettyBytes+"</p>\n "+(p&&f.prettyExpiryDate?'\n <p class="expirydate">EXP: '+f.prettyExpiryDate+"</p>":"")+"\n </div>\n ",b.appendChild(w),page.checkboxes[page.currentView]=b.querySelectorAll('.checkbox[data-action="select"]')}}else{page.dom.innerHTML="\n "+r+"\n "+c+"\n "+d+'\n <div class="table-container">\n <table class="table is-narrow is-fullwidth is-hoverable">\n <thead>\n <tr>\n <th><input id="selectAll" class="checkbox" type="checkbox" title="Select all" data-action="select-all"></th>\n <th>File</th>\n '+(void 0===e.album?"<th>"+(e.all?"User":"Album")+"</th>":"")+"\n <th>Size</th>\n "+(e.all?"<th>IP</th>":"")+"\n <th>Date</th>\n "+(p?"<th>Expiry date</th>":"")+'\n <th></th>\n </tr>\n </thead>\n <tbody id="table">\n </tbody>\n </table>\n </div>\n '+r+"\n ";for(var y=document.querySelector("#table"),k=0;k<n.length;k++){var x=n[k],T=document.createElement("tr");T.dataset.id=x.id,T.innerHTML='\n <td class="controls"><input type="checkbox" class="checkbox" title="Select" data-index="'+k+'" data-action="select"'+(x.selected?" checked":"")+'></td>\n <th><a href="'+x.file+'" target="_blank" rel="noopener" title="'+x.file+'">'+x.name+"</a></th>\n "+(void 0===e.album?"<th>"+x.appendix+"</th>":"")+"\n <td>"+x.prettyBytes+"</td>\n "+(e.all?"<td>"+(x.ip||"")+"</td>":"")+"\n <td>"+x.prettyDate+"</td>\n "+(p?"<td>"+(x.prettyExpiryDate||"-")+"</td>":"")+'\n <td class="controls has-text-right">\n <a class="button is-small is-primary is-outlined" title="'+(x.thumb?"Display preview":"File can't be previewed")+'" data-action="display-preview"'+(x.thumb?"":" disabled")+'>\n <span class="icon">\n <i class="'+("other"!==x.type?"icon-"+x.type:"icon-doc-inv")+'"></i>\n </span>\n </a>\n <a class="button is-small is-info is-outlined clipboard-js" title="Copy link to clipboard" data-clipboard-text="'+x.file+'">\n <span class="icon">\n <i class="icon-clipboard"></i>\n </span>\n </a>\n '+(e.all?"":'\n <a class="button is-small is-warning is-outlined" title="Add to album" data-action="add-to-album">\n <span class="icon">\n <i class="icon-plus"></i>\n </span>\n </a>')+'\n <a class="button is-small is-danger is-outlined" title="Delete" data-action="delete-upload">\n <span class="icon">\n <i class="icon-trash"></i>\n </span>\n </a>\n </td>\n ',y.appendChild(T),page.checkboxes[page.currentView]=y.querySelectorAll('.checkbox[data-action="select"]')}}var A=document.querySelector("#selectAll");A&&!u&&n.length&&(A.checked=!0,A.title="Unselect all"),"thumbs"===page.views[page.currentView].type?(page.fadeAndScroll(!0),page.lazyLoad.update()):page.fadeAndScroll(),page.updateTrigger(e.trigger,"active"),"uploads"===page.currentView&&(page.views.uploads.album=e.album),"uploadsAll"===page.currentView&&(page.views.uploadsAll.filters=e.filters),page.views[page.currentView].pageNum=n.length?e.pageNum:0})).catch((function(a){page.updateTrigger(e.trigger),page.onAxiosError(a)}))},setUploadsView:function(e,a){localStorage[lsKeys.viewType[page.currentView]]=e,page.views[page.currentView].type=e,page.getUploads(Object.assign({trigger:a},page.views[page.currentView]))},displayPreview:function(e){var a=page.cache.uploads[e];if(a.thumb){var t=document.createElement("div");if(t.innerHTML='\n <div class="field has-text-centered">\n <label class="label">'+a.name+'</label>\n <div class="controls swal-display-thumb-container">\n <img id="swalThumb" src="'+a.thumb+'">\n </div>\n </div>\n ',a.original){var n=/.[\w]+(\?|$)/.exec(a.original),s=n&&n[0]?n[0].toLowerCase():null,i=page.imageExts.includes(s),l=!i&&page.videoExts.includes(s);(i||l)&&(t.innerHTML+='\n <div class="field has-text-centered">\n <div class="controls">\n <a id="swalOriginal" type="button" class="button is-info is-outlined is-fullwidth" data-original="'+a.original+'">\n <span class="icon">\n <i class="icon-arrows-cw"></i>\n </span>\n <span>Load original</span>\n </a>\n </div>\n </div>\n ',t.querySelector("#swalOriginal").addEventListener("click",(function(e){var n=e.currentTarget;if(!n.classList.contains("is-danger")){n.classList.add("is-loading");var s=t.querySelector("#swalThumb");if(i)s.src=a.original,s.onload=function(){n.classList.add("is-hidden"),document.body.querySelector(".swal-overlay .swal-modal:not(.is-expanded)").classList.add("is-expanded")},s.onerror=function(e){e.currentTarget.classList.add("is-hidden"),n.className="button is-danger is-fullwidth",n.innerHTML='\n <span class="icon">\n <i class="icon-block"></i>\n </span>\n <span>Unable to load original</span>\n '};else if(l){s.classList.add("is-hidden");var r=document.createElement("video");r.id="swalVideo",r.controls=!0,r.autoplay=!0,r.src=a.original,s.insertAdjacentElement("afterend",r),n.classList.add("is-hidden"),document.body.querySelector(".swal-overlay .swal-modal:not(.is-expanded)").classList.add("is-expanded")}}})))}return swal({content:t,buttons:!1}).then((function(){var e=t.querySelector("#swalVideo");e&&e.remove(),document.body.querySelector(".swal-overlay .swal-modal").classList.remove("is-expanded")}))}},selectAll:function(e){for(var a=0;a<page.checkboxes[page.currentView].length;a++){var t=page.getItemID(page.checkboxes[page.currentView][a]);isNaN(t)||page.checkboxes[page.currentView][a].checked!==e.checked&&(page.checkboxes[page.currentView][a].checked=e.checked,page.checkboxes[page.currentView][a].checked?page.selected[page.currentView].push(t):page.selected[page.currentView].splice(page.selected[page.currentView].indexOf(t),1))}page.selected[page.currentView].length?localStorage[lsKeys.selected[page.currentView]]=JSON.stringify(page.selected[page.currentView]):delete localStorage[lsKeys.selected[page.currentView]],e.title=e.checked?"Unselect all":"Select all"},selectInBetween:function(e,a){var t=parseInt(e.dataset.index),n=parseInt(a.dataset.index);if(!(Math.abs(t-n)<2))for(var s=0;s<page.checkboxes[page.currentView].length;s++)if(t>n&&s>n&&s<t||t<n&&s>t&&s<n){var i=page.checkboxes[page.currentView][s].checked=a.checked,l=page.getItemID(page.checkboxes[page.currentView][s]);!page.selected[page.currentView].includes(l)&&i?page.selected[page.currentView].push(l):page.selected[page.currentView].includes(l)&&!i&&page.selected[page.currentView].splice(page.selected[page.currentView].indexOf(l),1)}},select:function(e,a){var t=page.getItemID(e);if(!isNaN(t)){var n=page.lastSelected[page.currentView];a.shiftKey&&n?(page.selectInBetween(e,n),e.checked=n.checked):page.lastSelected[page.currentView]=e,!page.selected[page.currentView].includes(t)&&e.checked?page.selected[page.currentView].push(t):page.selected[page.currentView].includes(t)&&!e.checked&&page.selected[page.currentView].splice(page.selected[page.currentView].indexOf(t),1),page.selected[page.currentView].length?localStorage[lsKeys.selected[page.currentView]]=JSON.stringify(page.selected[page.currentView]):delete localStorage[lsKeys.selected[page.currentView]]}},clearSelection:function(){var e=page.selected[page.currentView],a="users"===page.currentView?"users":"uploads",t=e.length;if(!t)return swal("An error occurred!","You have not selected any "+a+".","error");var n=1===t?a.substring(0,a.length-1):a;return swal({title:"Are you sure?",text:"You are going to unselect "+t+" "+n+".",buttons:!0}).then((function(e){if(e){for(var a=page.checkboxes[page.currentView],s=0;s<a.length;s++)a[s].checked&&(a[s].checked=!1);page.selected[page.currentView]=[],delete localStorage[lsKeys.selected[page.currentView]];var i=document.querySelector("#selectAll");return i&&(i.checked=!1),swal("Cleared selection!","Unselected "+t+" "+n+".","success")}}))},filtersHelp:function(e){var a=document.createElement("div");a.style="text-align: left",a.innerHTML='\n This supports 3 filter keys, namely <b>user</b> (username), <b>ip</b> and <b>name</b> (upload name).\n Each key can be specified more than once.\n Backlashes should be used if the usernames have spaces.\n There are also 2 additional flags, namely <b>-user</b> and <b>-ip</b>, which will match uploads by non-registered users and have no IPs respectively.\n\n How does it work?\n First, it will filter uploads matching ANY of the supplied <b>user</b> or <b>ip</b> keys.\n Then, it will refine the matches using the supplied <b>name</b> keys.\n\n Examples:\n\n Uploads from user with username "demo":\n <code>user:demo</code>\n\n Uploads from users with username either "John Doe" OR "demo":\n <code>user:John\\ Doe user:demo</code>\n\n Uploads from IP "127.0.0.1" AND which upload names match "*.rar" OR "*.zip":\n <code>ip:127.0.0.1 name:*.rar name:*.zip</code>\n\n Uploads from user with username "test" OR from non-registered users:\n <code>user:test -user</code>\n '.trim().replace(/^ {6}/gm,"").replace(/\n/g,"<br>"),swal({content:a})},filterUploads:function(e){var a=document.querySelector("#filters").value.trim();page.getUploads({all:!0,filters:a},e)},viewUserUploads:function(e,a){var t=page.cache.users[e];t&&(a.classList.add("is-loading"),page.getUploads({all:!0,filters:"user:"+t.username.replace(/ /g,"\\ "),trigger:document.querySelector("#itemManageUploads")}))},deleteUpload:function(e){page.postBulkDeleteUploads({all:"uploadsAll"===page.currentView,field:"id",values:[e],cb:function(a){!a.length&&page.selected[page.currentView].includes(e)&&page.selected[page.currentView].splice(page.selected[page.currentView].indexOf(e),1),page.selected[page.currentView].length?localStorage[lsKeys.selected[page.currentView]]=JSON.stringify(page.selected[page.currentView]):delete localStorage[lsKeys.selected[page.currentView]],page.getUploads(Object.assign({autoPage:!0},page.views[page.currentView]))}})},bulkDeleteUploads:function(){if(!page.selected[page.currentView].length)return swal("An error occurred!","You have not selected any uploads.","error");page.postBulkDeleteUploads({all:"uploadsAll"===page.currentView,field:"id",values:page.selected[page.currentView],cb:function(e){e.length?page.selected[page.currentView]=page.selected[page.currentView].filter((function(a){return e.includes(a)})):page.selected[page.currentView]=[],page.selected[page.currentView].length?localStorage[lsKeys.selected[page.currentView]]=JSON.stringify(page.selected[page.currentView]):delete localStorage[lsKeys.selected[page.currentView]],page.getUploads(Object.assign({autoPage:!0},page.views[page.currentView]))}})},deleteUploadsByNames:function(e){void 0===e&&(e={});var a="";page.permissions.moderator&&(a="<br><b>Hint:</b> You can use this feature to delete uploads by other users."),page.dom.innerHTML='\n <form class="prevent-default">\n <div class="field">\n <label class="label">Upload names:</label>\n <div class="control">\n <textarea id="bulkDeleteNames" class="textarea"></textarea>\n </div>\n <p class="help">Separate each entry with a new line.'+a+'</p>\n </div>\n <div class="field">\n <div class="control">\n <button type="submit" id="submitBulkDelete" class="button is-danger is-outlined is-fullwidth">\n <span class="icon">\n <i class="icon-trash"></i>\n </span>\n <span>Bulk delete</span>\n </button>\n </div>\n </div>\n </form>\n ',page.fadeAndScroll(),page.updateTrigger(e.trigger,"active"),document.querySelector("#submitBulkDelete").addEventListener("click",(function(){var e=document.querySelector("#bulkDeleteNames"),a={},t=e.value.split(/\r?\n/).map((function(e){var a=e.trim();return/^[^\s]+$/.test(a)?a:""})).filter((function(e){return!(!e||Object.prototype.hasOwnProperty.call(a,e))&&(a[e]=!0)}));if(e.value=t.join("\n"),!t.length)return swal("An error occurred!","You have not entered any upload names.","error");page.postBulkDeleteUploads({all:!0,field:"name",values:t,cb:function(a){e.value=a.join("\n")}})}))},postBulkDeleteUploads:function(e){void 0===e&&(e={});var a=e.values.length,t=e.values.length+" upload"+(1===a?"":"s"),n="<p>You won't be able to recover "+t.replace(/^(\d*)(.*)/,"<b>$1</b>$2")+"!</p>";e.all&&(n+="\n<p><b>Warning:</b> You may be nuking "+(1===a?"an upload":"some uploads")+" by "+(1===a?"another user":"other users")+"!</p>");var s=document.createElement("div");s.innerHTML=n,swal({title:"Are you sure?",content:s,icon:"warning",dangerMode:!0,buttons:{cancel:!0,confirm:{text:"Yes, nuke "+(1===e.values.length?"it":"them")+"!",closeModal:!1}}}).then((function(n){n&&axios.post("api/upload/bulkdelete",{field:e.fields,values:e.values}).then((function(n){if(n){if(!1===n.data.success)return"No token provided"===n.data.description?page.verifyToken(page.token):swal("An error occurred!",n.data.description,"error");var s=Array.isArray(n.data.failed)?n.data.failed:[];s.length===e.values.length?swal("An error occurred!","Unable to delete any of the "+t+".","error"):s.length&&s.length<e.values.length?swal("Warning!","From "+t+", unable to delete "+s.length+" of them.","warning"):swal("Deleted!",t+" "+(1===a?"has":"have")+" been deleted.","success",{buttons:!1,timer:1500}),"function"==typeof e.cb&&e.cb(s)}})).catch(page.onAxiosError)}))},addSelectedUploadsToAlbum:function(){if("uploads"===page.currentView){if(!page.selected[page.currentView].length)return swal("An error occurred!","You have not selected any uploads.","error");page.addUploadsToAlbum(page.selected[page.currentView],(function(e){e&&(e.length?page.selected[page.currentView]=page.selected[page.currentView].filter((function(a){return e.includes(a)})):page.selected[page.currentView]=[],localStorage[lsKeys.selected[page.currentView]]=JSON.stringify(page.selected[page.currentView]),page.getUploads(page.views[page.currentView]))}))}},addToAlbum:function(e){page.addUploadsToAlbum([e],(function(e){e&&page.getUploads(page.views[page.currentView])}))},addUploadsToAlbum:function(e,a){var t=e.length,n=document.createElement("div");n.innerHTML='\n <div class="field has-text-centered">\n <p>You are about to add <b>'+t+"</b> upload"+(1===t?"":"s")+' to an album.</p>\n <p><b>If an upload is already in an album, it will be moved.</b></p>\n </div>\n <div class="field">\n <div class="control">\n <div class="select is-fullwidth">\n <select id="swalAlbum" disabled>\n <option value="-1">Remove from album</option>\n <option value="" selected disabled>Fetching albums list…</option>\n </select>\n </div>\n </div>\n </div>\n ',swal({icon:"warning",content:n,buttons:{cancel:!0,confirm:{text:"OK",closeModal:!1}}}).then((function(t){if(t){var n=parseInt(document.querySelector("#swalAlbum").value);if(isNaN(n))return swal("An error occurred!","You did not choose an album.","error");axios.post("api/albums/addfiles",{ids:e,albumid:n}).then((function(t){if(t)if(!1!==t.data.success){var s=e.length;t.data.failed&&t.data.failed.length&&(s-=t.data.failed.length);var i="upload"+(1===e.length?"":"s");if(!s)return swal("An error occurred!","Could not add the "+i+" to the album.","error");swal("Woohoo!","Successfully "+(n<0?"removed":"added")+" "+s+" "+i+" "+(n<0?"from":"to")+" the album.","success",{buttons:!1,timer:1500}),a(t.data.failed)}else"No token provided"===t.data.description?page.verifyToken(page.token):swal("An error occurred!",t.data.description,"error")})).catch(page.onAxiosError)}})),axios.get("api/albums").then((function(e){if(!1!==e.data.success){var a=document.querySelector("#swalAlbum");a&&(a.innerHTML+=e.data.albums.map((function(e){return'<option value="'+e.id+'">'+e.name+"</option>"})).join("\n"),a.getElementsByTagName("option")[1].innerHTML="Choose an album",a.removeAttribute("disabled"))}else"No token provided"===e.data.description?page.verifyToken(page.token):swal("An error occurred!",e.data.description,"error")})).catch(page.onAxiosError)},getAlbums:function(e){void 0===e&&(e={}),page.updateTrigger(e.trigger,"loading"),axios.get("api/albums").then((function(a){if(a){if(!1===a.data.success)return"No token provided"===a.data.description?page.verifyToken(page.token):(page.updateTrigger(e.trigger),swal("An error occurred!",a.data.description,"error"));page.cache.albums={},page.dom.innerHTML='\n <h2 class="subtitle">Create new album</h2>\n <form class="prevent-default">\n <div class="field">\n <div class="control">\n <input id="albumName" class="input" type="text" placeholder="Name" maxlength="'+page.albumTitleMaxLength+'">\n </div>\n <p class="help">Max length is '+page.albumTitleMaxLength+' characters.</p>\n </div>\n <div class="field">\n <div class="control">\n <textarea id="albumDescription" class="textarea" placeholder="Description" rows="1" maxlength="'+page.albumDescMaxLength+'"></textarea>\n </div>\n <p class="help">Max length is '+page.albumDescMaxLength+' characters.</p>\n </div>\n <div class="field">\n <div class="control">\n <button type="submit" id="submitAlbum" class="button is-info is-outlined is-fullwidth" data-action="submit-album">\n <span class="icon">\n <i class="icon-paper-plane"></i>\n </span>\n <span>Create</span>\n </button>\n </div>\n </div>\n </form>\n <hr>\n <h2 class="subtitle">List of albums</h2>\n <div class="table-container">\n <table class="table is-fullwidth is-hoverable">\n <thead>\n <tr>\n <th>ID</th>\n <th>Name</th>\n <th>Files</th>\n <th>Created at</th>\n <th>Public link</th>\n <th></th>\n </tr>\n </thead>\n <tbody id="table">\n </tbody>\n </table>\n </div>\n ';for(var t=a.data.homeDomain,n=document.querySelector("#table"),s=0;s<a.data.albums.length;s++){var i=a.data.albums[s],l=t+"/a/"+i.identifier;i.prettyDate=page.getPrettyDate(new Date(1e3*i.timestamp)),page.cache.albums[i.id]={name:i.name,download:i.download,public:i.public,description:i.description};var r=document.createElement("tr");r.innerHTML="\n <th>"+i.id+"</th>\n <th>"+i.name+"</th>\n <th>"+i.files+"</th>\n <td>"+i.prettyDate+"</td>\n <td><a "+(i.public?'href="'+l+'"':'class="is-linethrough"')+' target="_blank" rel="noopener">'+l+'</a></td>\n <td class="has-text-right" data-id="'+i.id+'">\n <a class="button is-small is-primary is-outlined" title="Edit album" data-action="edit-album">\n <span class="icon is-small">\n <i class="icon-pencil"></i>\n </span>\n </a>\n <a class="button is-small is-info is-outlined clipboard-js" title="Copy link to clipboard" '+(i.public?'data-clipboard-text="'+l+'"':"disabled")+'>\n <span class="icon is-small">\n <i class="icon-clipboard"></i>\n </span>\n </a>\n <a class="button is-small is-warning is-outlined" title="Download album" '+(i.download?'href="api/album/zip/'+i.identifier+"?v="+i.editedAt+'"':"disabled")+'>\n <span class="icon is-small">\n <i class="icon-download"></i>\n </span>\n </a>\n <a class="button is-small is-danger is-outlined" title="Delete album" data-action="delete-album">\n <span class="icon is-small">\n <i class="icon-trash"></i>\n </span>\n </a>\n </td>\n ',n.appendChild(r)}page.fadeAndScroll(),page.updateTrigger(e.trigger,"active")}})).catch((function(a){page.updateTrigger(e.trigger),page.onAxiosError(a)}))},editAlbum:function(e){var a=page.cache.albums[e];if(a){var t=document.createElement("div");t.innerHTML='\n <div class="field">\n <div class="controls">\n <input id="swalName" class="input" type="text" placeholder="Name" maxlength="'+page.albumTitleMaxLength+'" value="'+(a.name||"").substring(0,page.albumTitleMaxLength)+'">\n </div>\n <p class="help">Max length is '+page.albumTitleMaxLength+' characters.</p>\n </div>\n <div class="field">\n <div class="control">\n <textarea id="swalDescription" class="textarea" placeholder="Description" rows="2" maxlength="'+page.albumDescMaxLength+'">'+(a.description||"").substring(0,page.albumDescMaxLength)+'</textarea>\n </div>\n <p class="help">Max length is '+page.albumDescMaxLength+' characters.</p>\n </div>\n <div class="field">\n <div class="control">\n <label class="checkbox">\n <input id="swalDownload" type="checkbox" '+(a.download?"checked":"")+'>\n Enable download\n </label>\n </div>\n </div>\n <div class="field">\n <div class="control">\n <label class="checkbox">\n <input id="swalPublic" type="checkbox" '+(a.public?"checked":"")+'>\n Enable public link\n </label>\n </div>\n </div>\n <div class="field">\n <div class="control">\n <label class="checkbox">\n <input id="swalRequestLink" type="checkbox">\n Request new public link\n </label>\n </div>\n </div>\n ',swal({title:"Edit album",icon:"info",content:t,buttons:{cancel:!0,confirm:{closeModal:!1}}}).then((function(t){t&&axios.post("api/albums/edit",{id:e,name:document.querySelector("#swalName").value.trim(),description:document.querySelector("#swalDescription").value.trim(),download:document.querySelector("#swalDownload").checked,public:document.querySelector("#swalPublic").checked,requestLink:document.querySelector("#swalRequestLink").checked}).then((function(e){if(e){if(!1===e.data.success)return"No token provided"===e.data.description?page.verifyToken(page.token):swal("An error occurred!",e.data.description,"error");e.data.identifier?swal("Success!","Your album's new identifier is: "+e.data.identifier+".","success"):e.data.name!==a.name?swal("Success!","Your album was renamed to: "+e.data.name+".","success"):swal("Success!","Your album was edited!","success",{buttons:!1,timer:1500}),page.getAlbumsSidebar(),page.getAlbums()}})).catch(page.onAxiosError)}))}},deleteAlbum:function(e){swal({title:"Are you sure?",text:"This won't delete your uploads, only the album!",icon:"warning",dangerMode:!0,buttons:{cancel:!0,confirm:{text:"Yes, delete it!",closeModal:!1},purge:{text:"Umm, delete the uploads too please?",value:"purge",className:"swal-button--danger",closeModal:!1}}}).then((function(a){a&&axios.post("api/albums/delete",{id:e,purge:"purge"===a}).then((function(e){if(!1===e.data.success){var a=Array.isArray(e.data.failed)?e.data.failed:[];return"No token provided"===e.data.description?page.verifyToken(page.token):a.length?swal("An error occurred!","Unable to delete "+a.length+" of the album's upload"+(1===a.length?"":"s")+".","error"):swal("An error occurred!",e.data.description,"error")}swal("Deleted!","Your album has been deleted.","success",{buttons:!1,timer:1500}),page.getAlbumsSidebar(),page.getAlbums()})).catch(page.onAxiosError)}))},submitAlbum:function(e){page.updateTrigger(e,"loading"),axios.post("api/albums",{name:document.querySelector("#albumName").value.trim(),description:document.querySelector("#albumDescription").value.trim()}).then((function(a){if(a){if(page.updateTrigger(e),!1===a.data.success)return"No token provided"===a.data.description?page.verifyToken(page.token):swal("An error occurred!",a.data.description,"error");swal("Woohoo!","Album was created successfully.","success",{buttons:!1,timer:1500}),page.getAlbumsSidebar(),page.getAlbums()}})).catch((function(a){page.updateTrigger(e),page.onAxiosError(a)}))},getAlbumsSidebar:function(){axios.get("api/albums/sidebar").then((function(e){if(e){if(!1===e.data.success)return"No token provided"===e.data.description?page.verifyToken(page.token):swal("An error occurred!",e.data.description,"error");var a=document.querySelector("#albumsContainer"),t=a.querySelectorAll("li > a");if(t.length){for(var n=0;n<t.length;n++)page.menus.splice(page.menus.indexOf(t[n]),1);a.innerHTML=""}if(void 0!==e.data.albums)for(var s=0;s<e.data.albums.length;s++){var i=e.data.albums[s],l=document.createElement("li"),r=document.createElement("a");r.id=i.id,r.innerHTML=i.name,r.className="is-relative",r.addEventListener("click",(function(e){page.getUploads({album:parseInt(e.currentTarget.id),trigger:e.currentTarget})})),page.menus.push(r),l.appendChild(r),a.appendChild(l)}}})).catch(page.onAxiosError)},changeToken:function(e){void 0===e&&(e={}),page.dom.innerHTML='\n <div class="field">\n <label class="label">Your current token:</label>\n <div class="field">\n <div class="control">\n <input id="token" readonly class="input" type="text" placeholder="Your token" value="'+page.token+'">\n </div>\n </div>\n </div>\n <div class="field">\n <div class="control">\n <a id="getNewToken" class="button is-info is-outlined is-fullwidth">\n <span class="icon">\n <i class="icon-arrows-cw"></i>\n </span>\n <span>Request new token</span>\n </a>\n </div>\n </div>\n ',page.fadeAndScroll(),page.updateTrigger(e.trigger,"active"),document.querySelector("#getNewToken").addEventListener("click",(function(e){var a=e.currentTarget;page.updateTrigger(a,"loading"),axios.post("api/tokens/change").then((function(e){if(!1===e.data.success)return"No token provided"===e.data.description?page.verifyToken(page.token):(page.updateTrigger(a),swal("An error occurred!",e.data.description,"error"));page.updateTrigger(a),swal({title:"Woohoo!",text:"Your token was successfully changed.",icon:"success"}).then((function(){axios.defaults.headers.common.token=e.data.token,localStorage[lsKeys.token]=e.data.token,page.token=e.data.token,page.changeToken()}))})).catch((function(e){page.updateTrigger(a),page.onAxiosError(e)}))}))},changePassword:function(e){void 0===e&&(e={}),page.dom.innerHTML='\n <form class="prevent-default">\n <div class="field">\n <label class="label">New password:</label>\n <div class="control">\n <input id="password" class="input" type="password" minlength="6" maxlength="64">\n </div>\n </div>\n <div class="field">\n <label class="label">Re-type new password:</label>\n <div class="control">\n <input id="passwordConfirm" class="input" type="password" minlength="6" maxlength="64">\n </div>\n </div>\n <div class="field">\n <div class="control">\n <button type="submit" id="sendChangePassword" class="button is-info is-outlined is-fullwidth">\n <span class="icon">\n <i class="icon-paper-plane"></i>\n </span>\n <span>Set new password</span>\n </button>\n </div>\n </div>\n </form>\n ',page.fadeAndScroll(),page.updateTrigger(e.trigger,"active"),document.querySelector("#sendChangePassword").addEventListener("click",(function(e){page.dom.querySelector("form").checkValidity()&&(document.querySelector("#password").value===document.querySelector("#passwordConfirm").value?page.sendNewPassword(document.querySelector("#password").value,e.currentTarget):swal({title:"Password mismatch!",text:"Your passwords do not match, please try again.",icon:"error"}))}))},sendNewPassword:function(e,a){page.updateTrigger(a,"loading"),axios.post("api/password/change",{password:e}).then((function(e){if(!1===e.data.success)return"No token provided"===e.data.description?page.verifyToken(page.token):(page.updateTrigger(a),swal("An error occurred!",e.data.description,"error"));page.updateTrigger(a),swal({title:"Woohoo!",text:"Your password was successfully changed.",icon:"success",buttons:!1,timer:1500}).then((function(){page.changePassword()}))})).catch((function(e){page.updateTrigger(a),page.onAxiosError(e)}))},getUsers:function(e){if(void 0===e&&(e={}),page.updateTrigger(e.trigger,"loading"),void 0===e.pageNum&&(e.pageNum=0),!page.permissions.admin)return swal("An error occurred!","You can not do this!","error");var a="api/users/"+e.pageNum;axios.get(a).then((function(a){if(!1===a.data.success)return"No token provided"===a.data.description?page.verifyToken(page.token):(page.updateTrigger(e.trigger),swal("An error occurred!",a.data.description,"error"));var t=Math.ceil(a.data.count/25);if(e.pageNum&&0===a.data.users.length)return e.autoPage?(e.pageNum=t-1,page.getUsers(e)):(page.updateTrigger(e.trigger),swal("An error occurred!","There are no more users to populate page "+(e.pageNum+1)+".","error"));page.currentView="users",page.cache.users={};var n=page.paginate(a.data.count,25,e.pageNum),s='\n <div class="columns">\n <div class="column is-hidden-mobile"></div>\n <div class="column is-one-quarter">\n <form class="prevent-default">\n <div class="field has-addons">\n <div class="control is-expanded">\n <input id="jumpToPage" class="input is-small" type="number" min="1" max="'+t+'" value="'+(e.pageNum+1)+'"'+(1===t?" disabled":"")+'>\n </div>\n <div class="control">\n <button type="submit" class="button is-small is-info is-outlined" title="Jump to page" data-action="jump-to-page">\n <span class="icon">\n <i class="icon-paper-plane"></i>\n </span>\n </button>\n </div>\n </div>\n </form>\n </div>\n </div>\n ',i=!1;page.dom.innerHTML="\n "+n+"\n "+s+'\n \n <div class="columns is-hidden">\n <div class="column is-hidden-mobile"></div>\n <div class="column has-text-right">\n <a class="button is-small is-info" title="Clear selection" data-action="clear-selection">\n <span class="icon">\n <i class="icon-cancel"></i>\n </span>\n </a>\n <a class="button is-small is-warning" title="Bulk disable (WIP)" data-action="bulk-disable-users" disabled>\n <span class="icon">\n <i class="icon-hammer"></i>\n </span>\n <span>Bulk disable</span>\n </a>\n <a class="button is-small is-danger" title="Bulk delete (WIP)" data-action="bulk-delete-users" disabled>\n <span class="icon">\n <i class="icon-trash"></i>\n </span>\n <span>Bulk delete</span>\n </a>\n </div>\n </div>\n \n <div class="table-container">\n <table class="table is-narrow is-fullwidth is-hoverable">\n <thead>\n <tr>\n <th class="is-hidden"><input id="selectAll" class="checkbox" type="checkbox" title="Select all" data-action="select-all"></th>\n <th>ID</th>\n <th>Username</th>\n <th>Uploads</th>\n <th>Usage</th>\n <th>Group</th>\n <th></th>\n </tr>\n </thead>\n <tbody id="table">\n </tbody>\n </table>\n </div>\n '+n+"\n ";for(var l=document.querySelector("#table"),r=0;r<a.data.users.length;r++){var o=a.data.users[r],c=page.selected.users.includes(o.id);c||(i=!0);for(var d=null,u=Object.keys(o.groups),p=0;p<u.length&&o.groups[u[p]];p++)d=u[p];var g=!1!==o.enabled&&0!==o.enabled;page.cache.users[o.id]={username:o.username,groups:o.groups,enabled:g,displayGroup:d};var m=document.createElement("tr");m.dataset.id=o.id,m.innerHTML='\n <td class="controls is-hidden"><input type="checkbox" class="checkbox" title="Select" data-action="select"'+(c?" checked":"")+"></td>\n <th>"+o.id+"</th>\n <th"+(g?"":' class="is-linethrough"')+">"+o.username+"</td>\n <th>"+o.uploads+"</th>\n <td>"+page.getPrettyBytes(o.usage)+"</td>\n <td>"+d+'</td>\n <td class="controls has-text-right">\n <a class="button is-small is-primary is-outlined" title="Edit user" data-action="edit-user">\n <span class="icon">\n <i class="icon-pencil"></i>\n </span>\n </a>\n <a class="button is-small is-info is-outlined" title="'+(o.uploads?"View uploads":"User doesn't have uploads")+'" data-action="view-user-uploads" '+(o.uploads?"":"disabled")+'>\n <span class="icon">\n <i class="icon-docs"></i>\n </span>\n </a>\n <a class="button is-small is-warning is-outlined" title="'+(g?"Disable user":"User is disabled")+'" data-action="disable-user" '+(g?"":"disabled")+'>\n <span class="icon">\n <i class="icon-hammer"></i>\n </span>\n </a>\n <a class="button is-small is-danger is-outlined" title="Delete user" data-action="delete-user">\n <span class="icon">\n <i class="icon-trash"></i>\n </span>\n </a>\n </td>\n ',l.appendChild(m),page.checkboxes.users=l.querySelectorAll('.checkbox[data-action="select"]')}var h=document.querySelector("#selectAll");h&&!i&&(h.checked=!0,h.title="Unselect all"),page.fadeAndScroll(),page.updateTrigger(e.trigger,"active"),page.views.users.pageNum=a.data.users.length?e.pageNum:0})).catch((function(a){page.updateTrigger(e.trigger),page.onAxiosError(a)}))},editUser:function(e){var a=page.cache.users[e];if(a){var t=Object.keys(page.permissions).map((function(e,t,n){return'<option value="'+e+'"'+(e===a.displayGroup?" selected":"")+(!(n[t+1]&&page.permissions[n[t+1]])?" disabled":"")+">"+e+"</option>"})).join("\n"),n=document.createElement("div");n.innerHTML='\n <div class="field">\n <label class="label">Username</label>\n <div class="controls">\n <input id="swalUsername" class="input" type="text" value="'+(a.username||"")+'">\n </div>\n </div>\n <div class="field">\n <label class="label">User group</label>\n <div class="control">\n <div class="select is-fullwidth">\n <select id="swalGroup">\n '+t+'\n </select>\n </div>\n </div>\n </div>\n <div class="field">\n <div class="control">\n <label class="checkbox">\n <input id="swalEnabled" type="checkbox" '+(a.enabled?"checked":"")+'>\n Enabled\n </label>\n </div>\n </div>\n <div class="field">\n <div class="control">\n <label class="checkbox">\n <input id="swalResetPassword" type="checkbox">\n Reset password\n </label>\n </div>\n </div>\n ',swal({title:"Edit user",icon:"info",content:n,buttons:{cancel:!0,confirm:{closeModal:!1}}}).then((function(t){t&&axios.post("api/users/edit",{id:e,username:document.querySelector("#swalUsername").value,group:document.querySelector("#swalGroup").value,enabled:document.querySelector("#swalEnabled").checked,resetPassword:document.querySelector("#swalResetPassword").checked}).then((function(e){if(e){if(!1===e.data.success)return"No token provided"===e.data.description?page.verifyToken(page.token):swal("An error occurred!",e.data.description,"error");if(e.data.password){var t=document.createElement("div");t.innerHTML="\n <p><b>"+a.username+"</b>'s new password is:</p>\n <p><code>"+e.data.password+"</code></p>\n ",swal({title:"Success!",icon:"success",content:t})}else e.data.update&&e.data.update.username!==a.username?swal("Success!",a.username+" was renamed into: "+e.data.update.username+".","success"):swal("Success!","The user was edited!","success",{buttons:!1,timer:1500});page.getUsers(page.views.users)}})).catch(page.onAxiosError)}))}},disableUser:function(e){var a=page.cache.users[e];if(a&&a.enabled){var t=document.createElement("div");t.innerHTML="\n <p>You will be disabling a user named <b>"+page.cache.users[e].username+"</b>.</p>\n <p>Their files will remain.</p>\n ",swal({title:"Are you sure?",icon:"warning",content:t,dangerMode:!0,buttons:{cancel:!0,confirm:{text:"Yes, disable them!",closeModal:!1}}}).then((function(a){a&&axios.post("api/users/disable",{id:e}).then((function(a){if(a){if(!1===a.data.success)return"No token provided"===a.data.description?page.verifyToken(page.token):swal("An error occurred!",a.data.description,"error");swal("Success!",page.cache.users[e].username+" has been disabled.","success",{buttons:!1,timer:1500}),page.getUsers(page.views.users)}})).catch(page.onAxiosError)}))}},deleteUser:function(e){if(page.cache.users[e]){var a=document.createElement("div");a.innerHTML="\n <p>You will be deleting a user named <b>"+page.cache.users[e].username+"</b>.<p>\n <p>Their files will remain, unless you choose otherwise.</p>\n ",swal({title:"Are you sure?",icon:"warning",content:a,dangerMode:!0,buttons:{cancel:!0,confirm:{text:"Yes, delete it!",closeModal:!1},purge:{text:"Yes, and the uploads too!",value:"purge",className:"swal-button--danger",closeModal:!1}}}).then((function(a){a&&axios.post("api/users/delete",{id:e,purge:"purge"===a}).then((function(a){if(a){if(!1===a.data.success){var t=Array.isArray(a.data.failed)?a.data.failed:[];return"No token provided"===a.data.description?page.verifyToken(page.token):t.length?swal("An error occurred!","Unable to delete "+t.length+" of the user's upload"+(1===t.length?"":"s")+".","error"):swal("An error occurred!",a.data.description,"error")}swal("Success!",page.cache.users[e].username+" has been deleted.","success",{buttons:!1,timer:1500}),page.getUsers(Object.assign({autoPage:!0},page.views.users))}})).catch(page.onAxiosError)}))}},paginate:function(e,a,t){t+=1;var n=Math.ceil(e/a),s="",i=function(e,a){for(var n=e;n<=a;++n)s+='<li><a class="button pagination-link '+(n===t?" is-current":"")+'" aria-label="Goto page '+n+'" data-action="page-goto" data-goto="'+(n-1)+'">'+n+"</a></li>"},l=function(){s+='\n <li><a class="button pagination-link" aria-label="Goto page 1" data-action="page-goto" data-goto="0">1</a></li>\n <li data-action="page-ellipsis"><span class="pagination-ellipsis">…</span></li>\n '},r=function(){s+='\n <li data-action="page-ellipsis"><span class="pagination-ellipsis">…</span></li>\n <li><a class="button pagination-link" aria-label="Goto page '+n+'" data-action="page-goto" data-goto="'+(n-1)+'">'+n+"</a></li>\n "};return 7>=n?i(1,n):t<6?(i(1,6),r()):t>n-6+1?(l(),i(n-6+1,n)):(l(),i(t-3+1,t+3-1),r()),'\n <nav class="pagination is-centered is-small">\n <a class="button pagination-previous" data-action="page-prev"'+(1===t?" disabled":"")+'>Previous</a>\n <a class="button pagination-next" data-action="page-next"'+(t===n?" disabled":"")+'>Next page</a>\n <ul class="pagination-list">'+s+"</ul>\n </nav>\n "},getStatistics:function(e){if(void 0===e&&(e={}),!page.permissions.admin)return swal("An error occurred!","You can not do this!","error");page.updateTrigger(e.trigger,"loading");axios.get("api/stats").then((function(a){if(!1===a.data.success)return"No token provided"===a.data.description?page.verifyToken(page.token):(page.updateTrigger(e.trigger),swal("An error occurred!",a.data.description,"error"));for(var t="",n=Object.keys(a.data.stats),s=0;s<n.length;s++){var i="";if(a.data.stats[n[s]])try{for(var l=a.data.stats[n[s]]._types||{},r=Object.keys(a.data.stats[n[s]]),o=0;o<r.length;o++)if(!/^_/.test(r[o])){var c=a.data.stats[n[s]][r[o]],d=c;(l.number||[]).includes(r[o])&&(d=c.toLocaleString()),(l.byte||[]).includes(r[o])&&(d=page.getPrettyBytes(c)),(l.byteUsage||[]).includes(r[o])&&(d=page.getPrettyBytes(c.used)+" / "+page.getPrettyBytes(c.total)+" ("+Math.round(c.used/c.total*100)+"%)"),i+="\n <tr>\n <th>"+r[o].replace(/([A-Z])/g," $1").toUpperCase()+"</th>\n <td>"+d+"</td>\n </tr>\n "}}catch(e){i="\n <tr>\n <td>Error parsing response. Try again?</td>\n <td></td>\n </tr>\n ",page.onError(e)}else i+="\n <tr>\n <td>Generating, please try again later…</td>\n <td></td>\n </tr>\n ";t+='\n <div class="table-container">\n <table id="statistics" class="table is-fullwidth is-hoverable">\n <thead>\n <tr>\n <th>'+n[s].toUpperCase()+"</th>\n <td></td>\n </tr>\n </thead>\n <tbody>\n "+i+"\n </tbody>\n </table>\n </div>\n "}page.dom.innerHTML=t,page.fadeAndScroll(),page.updateTrigger(e.trigger,"active")})).catch((function(a){page.updateTrigger(e.trigger),page.onAxiosError(a)}))}};window.onload=function(){"function"!=typeof Object.assign&&Object.defineProperty(Object,"assign",{value:function(e,a){"use strict";var t=arguments;if(null==e)throw new TypeError("Cannot convert undefined or null to object");for(var n=Object(e),s=1;s<arguments.length;s++){var i=t[s];if(null!=i)for(var l in i)Object.prototype.hasOwnProperty.call(i,l)&&(n[l]=i[l])}return n},writable:!0,configurable:!0}),"ontouchstart"in document.documentElement||document.documentElement.classList.add("no-touch");for(var e=["uploads","uploadsAll","users"],a=0;a<e.length;a++){var t=localStorage[lsKeys.selected[e[a]]];t&&(page.selected[e[a]]=JSON.parse(t))}page.preparePage(),page.clipboardJS=new ClipboardJS(".clipboard-js"),page.clipboardJS.on("success",(function(){return swal("","The link has been copied to clipboard.","success",{buttons:!1,timer:1500})})),page.clipboardJS.on("error",page.onError),page.lazyLoad=new LazyLoad};
|
||
//# sourceMappingURL=dashboard.js.map
|