Mercurial Hosting > linkmystyle
comparison src/admin.js @ 0:8f4df159f06b
start public repo
| author | Franklin Schmidt <fschmidt@gmail.com> |
|---|---|
| date | Fri, 11 Jul 2025 20:57:49 -0600 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:8f4df159f06b |
|---|---|
| 1 'use strict'; | |
| 2 | |
| 3 let currentPulldown = null; | |
| 4 let newPulldown = null; | |
| 5 | |
| 6 function clickMenu(clicked,display) { | |
| 7 //console.log("clickMenu"); | |
| 8 let pulldown = clicked.parentNode.querySelector('[pulldown_menu]'); | |
| 9 if( pulldown !== currentPulldown ) { | |
| 10 pulldown.style.display = display || "block"; | |
| 11 newPulldown = pulldown; | |
| 12 window.onclick = function() { | |
| 13 //console.log("window.onclick"); | |
| 14 if( currentPulldown ) { | |
| 15 currentPulldown.style.display = "none"; | |
| 16 if( !newPulldown ) | |
| 17 window.onclick = null; | |
| 18 } | |
| 19 currentPulldown = newPulldown; | |
| 20 newPulldown = null; | |
| 21 }; | |
| 22 pulldown.scrollIntoViewIfNeeded(false); | |
| 23 } | |
| 24 } | |
| 25 | |
| 26 function stopPropagation(event) { | |
| 27 event.stopPropagation(); | |
| 28 } | |
| 29 | |
| 30 window.addEventListener( 'load', function() { | |
| 31 for( let pulldown of document.querySelectorAll('[pulldown_menu]') ) { | |
| 32 pulldown.onclick = stopPropagation; | |
| 33 } | |
| 34 } ); | |
| 35 | |
| 36 function copyLink() { | |
| 37 // avoid the paranoid security nonsense with navigator.clipboard | |
| 38 let input = document.querySelector('input[clipboard]'); | |
| 39 input.select(); | |
| 40 document.execCommand('copy'); | |
| 41 input.blur(); | |
| 42 | |
| 43 let span = document.querySelector('[pulldown_menu] span[copy]'); | |
| 44 span.textContent = 'Copied!'; | |
| 45 span.setAttribute('copy','copied'); | |
| 46 setTimeout(function(){ | |
| 47 span.textContent = 'Copy'; | |
| 48 span.setAttribute('copy',''); | |
| 49 } ,1000); | |
| 50 } | |
| 51 | |
| 52 function logout() { | |
| 53 document.cookie = 'user=; Max-Age=0; path=/;'; | |
| 54 document.cookie = 'password=; Max-Age=0; path=/;'; | |
| 55 location = '/'; | |
| 56 } | |
| 57 | |
| 58 | |
| 59 function uploadcareUrl(uuid) { | |
| 60 return "https://ucarecdn.com/" + uuid + "/-/quality/smart/"; | |
| 61 } | |
| 62 | |
| 63 if( typeof(uploadcare) !== 'undefined' ) { | |
| 64 uploadcare.publicKey = window.uploadcarePubKey; | |
| 65 uploadcare.imagesOnly = true; | |
| 66 uploadcare.maxFileSize = 10000000; | |
| 67 uploadcare.onError = function(status,text) { | |
| 68 let err = 'upload failed: ' + status; | |
| 69 if( text ) { | |
| 70 err += '\n' + text; | |
| 71 } | |
| 72 console.log(err); | |
| 73 ajax( '/error_log.js', 'err='+encodeURIComponent(err) ); | |
| 74 }; | |
| 75 } | |
| 76 | |
| 77 | |
| 78 let dropSelector, iDragging; | |
| 79 | |
| 80 function indexOf(a,el) { | |
| 81 for( let i=0; i<a.length; i++ ) { | |
| 82 if( a[i] === el ) | |
| 83 return i; | |
| 84 } | |
| 85 return -1; | |
| 86 } | |
| 87 | |
| 88 if( typeof(dad) !== 'undefined' ) { | |
| 89 dad.onStart = function(event) { | |
| 90 let dragging = event.original; | |
| 91 iDragging = indexOf(dragging.parentNode.querySelectorAll(dropSelector),dragging); | |
| 92 } | |
| 93 | |
| 94 dad.onEnter = function(event) { | |
| 95 let dropzone = event.dropzone | |
| 96 let original = event.original | |
| 97 let items = document.querySelectorAll(dropSelector); | |
| 98 let iDropzone = indexOf(items,dropzone); | |
| 99 let iOriginal = indexOf(items,original); | |
| 100 let where = iDropzone < iOriginal ? 'beforebegin' : 'afterend'; | |
| 101 dropzone.insertAdjacentElement(where,original); | |
| 102 }; | |
| 103 } | |
| 104 | |
| 105 function date(time) { | |
| 106 document.write(new Date(time).toLocaleDateString()); | |
| 107 } | |
| 108 | |
| 109 function ajaxForm(url,form) { | |
| 110 let post = ''; | |
| 111 for( let i=0; i<form.length; i++ ) { | |
| 112 let input = form[i]; | |
| 113 let name = input.name; | |
| 114 if( name === '' ) | |
| 115 continue; | |
| 116 let type = input.type; | |
| 117 if( (type==='radio' || type==='checkbox') && !input.checked ) | |
| 118 continue; | |
| 119 post += name + '=' + encodeURIComponent(input.value) + '&'; | |
| 120 } | |
| 121 ajax(url,post,{form:form}); | |
| 122 } | |
| 123 | |
| 124 function clearErrors(form) { | |
| 125 let divs = form.querySelectorAll('div[error]'); | |
| 126 for( let i=0; i<divs.length; i++ ) { | |
| 127 divs[i].textContent = ''; | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 function showError(form,field,message) { | |
| 132 clearErrors(form); | |
| 133 let err = form.querySelector('[error="'+field+'"]'); | |
| 134 err.textContent = message; | |
| 135 err.scrollIntoViewIfNeeded(false); | |
| 136 err.setAttribute('flash',''); | |
| 137 setTimeout(function(){err.removeAttribute('flash')},2000); | |
| 138 } | |
| 139 | |
| 140 function showPassword(div) { | |
| 141 div.querySelector('img[show]').style.display = 'none'; | |
| 142 div.querySelector('img[hide]').style.display = 'block'; | |
| 143 let input = div.querySelector('input'); | |
| 144 input.type = 'text'; | |
| 145 input.focus(); | |
| 146 } | |
| 147 function hidePassword(div) { | |
| 148 div.querySelector('img[show]').style.display = 'block'; | |
| 149 div.querySelector('img[hide]').style.display = 'none'; | |
| 150 let input = div.querySelector('input'); | |
| 151 input.type = 'password'; | |
| 152 input.focus(); | |
| 153 } | |
| 154 | |
| 155 | |
| 156 function isEmpty(obj) { | |
| 157 for( let _ in obj ) { | |
| 158 return false; | |
| 159 } | |
| 160 return true; | |
| 161 } | |
| 162 | |
| 163 function barChartHeight(rows) { | |
| 164 return 200 + 20*rows; | |
| 165 } | |
| 166 | |
| 167 | |
| 168 // Mixpanel | |
| 169 if( window.UserEmail ) { | |
| 170 mixpanel.ours.identify(window.UserEmail); | |
| 171 mixpanel.ours.people.set({'$email':window.UserEmail,'$name':window.UserName}); | |
| 172 } | |
| 173 | |
| 174 | |
| 175 // A/B tests | |
| 176 | |
| 177 function setAbTest(name,values) { | |
| 178 let props = {}; | |
| 179 props[name] = cookies[name]; | |
| 180 for( let i=1; i<=4; i++ ) { | |
| 181 props[name+'-null-'+i] = values[ Math.floor( Math.random() * values.length ) ]; | |
| 182 } | |
| 183 mixpanel.ours.identify(); | |
| 184 mixpanel.ours.people.set(props); | |
| 185 } | |
| 186 | |
| 187 function removeAbTest(name) { | |
| 188 let a = []; | |
| 189 a.push(name); | |
| 190 for( let i=1; i<=4; i++ ) { | |
| 191 a.push(name+'-null-'+i); | |
| 192 } | |
| 193 mixpanel.ours.people.unset(a); | |
| 194 } | |
| 195 | |
| 196 | |
| 197 | |
| 198 if( !location.pathname.match(/^\/private\//) ) { | |
| 199 fbTrack( 'track', 'PageView' ); | |
| 200 } |
