feat(filehole): add rj1 filehole UI

This commit is contained in:
hgc 2023-05-30 04:45:37 +00:00
parent be16d6ff47
commit 32f6054941

View File

@ -1,46 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Filehole</title>
<style>
body {
font-family: sans-serif;
}
@media (prefers-color-scheme: dark) {
body {
background: black;
color: white;
}
}
.container {
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
@media (min-width: 768px) {
.container {
width: 750px;
}
}
@media (min-width: 992px) {
.container {
width: 970px;
}
}
@media (min-width: 1200px) {
.container {
width: 1170px;
}
}
input,select {
margin-bottom: 1em;
}
</style>
</head>
<body>
<head>
<title>filehole.org</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
body{background-color:#1a1c1d;color:#fff;font-family:monospace;font-size:14px;padding:20px;text-align:center}h1{font-size:32px;margin-bottom:2px}h1 small{font-size:8px;margin-bottom:-5px;vertical-align:top}.slogan{background:-webkit-linear-gradient(#1a4e1d,#c8ffa5);-webkit-background-clip:text;-webkit-text-fill-color:transparent;margin-top:-10px;font-size:12px;vertical-align:top}h2{font-size:12px;margin-bottom:20px}#hole{display:flex;justify-content:center;cursor:pointer;margin:0 auto;margin-bottom:20px}#hole:hover{border-color:#ccc}#filelist{list-style:none;margin:0 auto;max-width:600px;padding:0}.file{border-radius:5px;background-color:#333;border:1px solid #555;color:#fff;display:flex;align-items:center;justify-content:space-between;margin:5px 0;padding:10px;transition:all .3s ease-in-out}.file:hover{background-color:#444;box-shadow:0 1px 3px rgba(0,0,0,.3)}.file a{color:#fff;margin-right:10px;text-decoration:none}.file a:hover{text-decoration:underline}.file button{background-color:transparent;border:none;color:#fff;cursor:pointer;font-size:18px;margin-left:10px;margin-right:-7px;padding:0;transition:opacity .3s ease-in-out}.file button:hover{opacity:.7}button{background-color:transparent;border:2px solid #3e4446;border-radius:5px;color:#fff;cursor:pointer;font-size:16px;margin-top:10px;padding:7px 20px;text-transform:uppercase;transition:background-color .3s ease-in-out}button:hover{background-color:#444;border-color:#fff}#options{align-items:center;display:flex;flex-wrap:wrap;justify-content:center;margin-top:20px}.option{background-color:#222;border:2px solid #444;border-radius:5px;color:#fff;cursor:pointer;font-size:16px;margin:5px;padding:7px 20px;transition:all .3s ease-in-out}.option:hover{background-color:#444;border-color:#fff}#options label{font-size:16px;margin-right:10px}#options input[type=number],#options select[name=expiry]{background-color:#333;border:none;border-radius:5px;color:#fff;font-size:16px;height:30px;margin-right:10px;padding:0 10px;text-align:center;transition:all .3s ease-in-out;width:80px}#options input[type=number]:hover,#options select[name=expiry]:hover{background-color:#444;cursor:pointer}#options input[type=number]:focus,#options select[name=expiry]:focus{background-color:#444;outline:none}@media(max-width:768px){body{font-size:12px;padding:10px}h1{font-size:24px;margin-bottom:10px}#hole{max-width:150px;min-height:150px;padding:10px;margin-bottom:20px}#filelist{max-width:400px}.file{border-radius:5px;padding:8px;margin:3px 0}.file a{font-size:12px;margin-right:5px}.file button{font-size:14px;margin-left:5px;margin-right:-3px}button{font-size:14px;margin-top:5px;padding:5px 12px}#options{margin-top:10px}#options label{font-size:14px;margin-right:5px}#options input[type=number],#options select[name=expiry]{font-size:14px;height:25px;margin-right:5px;padding:0 5px;width:80px}}.blackhole{width:10em;height:10em}.blackhole .mega{width:100%;height:100%;border-radius:100%;background:linear-gradient(#b494ba,#6845ba,#5f27e1);box-shadow:0 0 60px 30px #b38faf29;display:flex;justify-content:center;align-items:center;filter:blur(5px)}.blackhole .black{width:90%;height:90%;border-radius:45% 50% 50% 50%;background-color:#000;transform:rotate(0deg);animation:hole .1s linear infinite normal;color:#fff;content:"hi"}@keyframes hole{100%{transform:rotate(360deg)}}
</style>
<link href="style.css" rel="stylesheet" />
</head>
<body>
<noscript>
<div class="container">
<h1>Filehole</h1>
<form method="POST" enctype="multipart/form-data">
@ -60,15 +30,47 @@
<input type="submit" />
</form>
<hr>
<h1>How to put your files in the hole</h1>
<h1>How to put your files in the hole</h1>
<h2>curl</h2>
<p><pre>curl -X POST -F 'file=@filehole.png' https://filehole.org</pre></p>
<p><pre>curl -X POST -F 'file=@filehole.png' -F "url_len=5" -F "expiry=86400" https://filehole.org</pre></p>
<h2>Firefox</h2>
<a href="https://addons.mozilla.org/en-US/firefox/addon/post-image/">POST Image by rj1</a>
<h2>Mac OS</h2>
<a href="https://github.com/AndroidKitKat/Filehole.org-Mac">Filehole.org-Mac by AndroidKitKat</a>*
<p><small>*not actually tested or endorsed because I will never own a Mac</small></p>
<h2>Mac OS</h2>
<a href="https://github.com/AndroidKitKat/Filehole.org-Mac">Filehole.org-Mac by AndroidKitKat</a>*
<p><small>*not actually tested or endorsed because I will never own a Mac</small></p>
</div>
</body>
<hr>
</noscript>
<h1>filehole</h1>
<div class="slogan">deprogrammed edition</div>
<h2>drop some files into the hole</h2>
<div id="hole">
<div class="blackhole">
<div class="mega">
<div class="black"></div>
</div>
</div>
</div>
<ul id="filelist"></ul>
<button id="clear">clear files</button>
<button id="upload" disabled>upload files</button>
<div id="options">
<label for="url_len">url length:</label>
<input id="url_len" name="url_len" type="number" value="5" min="5" max="64" />
<label for="expiry">expiry time:</label>
<select id="expiry" name="expiry">
<option value="3600">1 hour</option>
<option value="18000">5 hours</option>
<option value="86400" selected>1 day</option>
<option value="140400">39 hours</option>
<option value="172800">2 days</option>
<option value="248400">69 hours</option>
<option value="432000">5 days</option>
</select>
</div>
<script>const hole=document.getElementById("hole");const filelist=document.getElementById("filelist");const clearButton=document.getElementById("clear");const uploadButton=document.getElementById("upload");const urlLength=document.getElementById("url_len");const expiryTime=document.getElementById("expiry");let files=[];hole.addEventListener("dragover",(e)=>{e.preventDefault();hole.style.borderColor="#ccc";});hole.addEventListener("dragleave",()=>{hole.style.borderColor="#444";});hole.addEventListener("drop",(e)=>{e.preventDefault();hole.style.borderColor="#444";const newFiles=Array.from(e.dataTransfer.files);addFiles(newFiles);updateButtons();});hole.addEventListener("click",()=>{const input=document.createElement("input");input.type="file";input.multiple="true";input.accept="*";input.style.display="none";input.addEventListener("change",(e)=>{const newFiles=Array.from(e.target.files);addFiles(newFiles);updateButtons();});document.body.appendChild(input);input.click();document.body.removeChild(input);});const addFiles=(newFiles)=>{newFiles.forEach((file)=>{const listItem=document.createElement("li");listItem.classList.add("file");const fileName=document.createElement("span");fileName.textContent=file.name;listItem.appendChild(fileName);const fileSize=document.createElement("span");let sizeInBytes=file.size;if(sizeInBytes<1024){fileSize.textContent=sizeInBytes+" bytes";}else if(sizeInBytes<1024*1024){fileSize.textContent=(sizeInBytes/1024).toFixed(2)+" KB";}else if(sizeInBytes<1024*1024*1024){fileSize.textContent=(sizeInBytes/(1024*1024)).toFixed(2)+" MB";}else{fileSize.textContent=(sizeInBytes/(1024*1024*1024)).toFixed(2)+" GB";}
listItem.appendChild(fileSize);const removeButton=document.createElement("button");removeButton.textContent="X";removeButton.addEventListener("click",()=>{files.splice(files.indexOf(file),1);filelist.removeChild(listItem);updateButtons();});listItem.appendChild(removeButton);filelist.appendChild(listItem);files.push(file);});};const updateButtons=()=>{if(files.length>0){uploadButton.disabled=false;clearButton.disabled=false;}else{uploadButton.disabled=true;clearButton.disabled=true;}};clearButton.addEventListener("click",()=>{files=[];filelist.innerHTML="";updateButtons();});const dots=document.createElement("span");dots.textContent=".";let dotCount=0;uploadButton.addEventListener("click",()=>{const urlLengthValue=urlLength.value;const expiryTimeValue=expiryTime.value;let currentIndex=0;const updateItemStatus=(index,message)=>{const listItem=filelist.children[index];const statusElement=listItem.children[2];statusElement.textContent=message;};const uploadFile=()=>{if(currentIndex>=files.length){files=[];return;}
const file=files[currentIndex];const formData=new FormData();formData.append("file",file);formData.append("url_len",urlLengthValue);formData.append("expiry",expiryTimeValue);updateItemStatus(currentIndex,"uploading...");fetch("https://filehole.org/",{method:"POST",body:formData,}).then((response)=>response.text()).then((data)=>{data=data.trim();const url=document.createElement("a");url.href=data;url.target="_blank";url.textContent=data;const listItem=filelist.children[currentIndex];const removeButton=listItem.children[2];listItem.replaceChild(url,removeButton);const copyButton=document.createElement("button");copyButton.textContent="copy to clipboard";copyButton.addEventListener("click",(event)=>{event.stopPropagation();navigator.clipboard.writeText(data);});listItem.appendChild(copyButton);formData.delete("file");currentIndex++;uploadFile();}).catch((error)=>{console.error(error);updateItemStatus(currentIndex,"upload failed");});};uploadFile();});</script>
</body>
</html>