Finally the front end...
index.html
<!DOCTYPE html> <html lang='en'> <head> <meta name='viewport' content='width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no'> <meta charset='utf-8'> <title>Fake Compiler C++</title> <link rel='stylesheet' href='./style.css'> </head> <body > <div id='root'> <div id="loader" class="center"> <div class="loader"></div> </div> <div class="forms center"> <h1> Fake Compiler C++ </h1> <div class="area area_download hide"> <div class="folder_icon transparent"> <svg class="transparent" stroke="currentColor" fill="currentColor" stroke-width="0" version="1.1" viewBox="0 0 16 16" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M9 4l-2-2h-7v13h16v-11h-7zM8 13.5l-3.5-3.5h2.5v-4h2v4h2.5l-3.5 3.5z"></path></svg></div> <label class="form-label transparent" for="customFile"><span class="transparent">Download</span></label> </div> <div class="area txt_area"> <div class="folder_icon folder_icon_txt transparent"> <svg class="transparent" stroke="currentColor" stroke-width="0" version="1.1" viewBox="0 0 16 16" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M9 4l-2-2h-7v13h16v-11h-7zM8 7.5l3.5 3.5h-2.5v4h-2v-4h-2.5l3.5-3.5z"></path></svg> </div> <div class="folder_icon confirm_icon_txt transparent hide"> <svg class="transparent" stroke="currentColor" stroke-width="0" viewBox="0 0 16 16" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"></path></svg> </div> <label class="form-label transparent txt_browse" for="customFile">Drag & Drop or <span class="transparent">Browse</span></label> <label class="form-label transparent txt_remove hide" for="customFile">Click to <span class="transparent">Remove</span></label> <form class="form transparent" id="txt" method="post" enctype="multipart/form-data" action="/uploads"> <input type="hidden" name="msgtype" value="2"/> <input onchange="txt_change();" type="file" name="uploadFile" accept=".txt" class="form-control hide input_file_txt"/> <label class="form-label suports transparent" for="customFile">Suports: <span class="span transparent">TXT</span></label> <button type="submit" value="Upload" class="btn btn-dark hide">Browse File</button> </form> </div> <div class="area exe_area"> <div class="folder_icon folder_icon_exe transparent"> <svg class="transparent" stroke="currentColor" stroke-width="0" version="1.1" viewBox="0 0 16 16" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M9 4l-2-2h-7v13h16v-11h-7zM8 7.5l3.5 3.5h-2.5v4h-2v-4h-2.5l3.5-3.5z"></path></svg> </div> <div class="folder_icon confirm_icon_exe transparent hide"> <svg class="transparent" stroke="currentColor" stroke-width="0" viewBox="0 0 16 16" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg"><path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"></path></svg> </div> <label class="form-label transparent exe_browse" for="customFile">Drag & Drop or <span class="transparent">Browse</span></label> <label class="form-label transparent exe_remove hide" for="customFile">Click to <span class="transparent">Remove</span></label> <form class="form transparent" id="exe" method="post" enctype="multipart/form-data" action="/uploads"> <input type="hidden" name="msgtype" value="2"/> <input onchange="exe_change();" type="file" name="uploadFile" accept=".exe" class="form-control hide input_file_exe"/> <label class="form-label suports transparent" for="customFile">Suports: <span class="span transparent">EXE</span></label> <button type="submit" value="Upload" class="btn btn-dark hide btn_exe">Browse File</button> </form> </div> <div class="btn_compile noSelect hide">Send</div> </div> </div> <script src='./main.js'></script> </body> </html>
style.css
*{ padding: 0px; margin: 0px; outline: none; box-sizing: border-box; font-family: Arial; background: #191818; color: black; } h1{ color: #b9b9bd; margin-top: 50px; margin-bottom: 50px; } #loader{ min-width: 100%; min-height: 90vh; position: absolute; background: #191818; } .loader{ border: 16px solid #f3f3f3; border-radius: 50%; border-top: 16px solid #3498db; width: 120px; height: 120px; -webkit-animation: spin 2s linear infinite; /* Safari */ animation: spin 2s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .center-buttons{ display: flex; flex-direction: row; justify-content: center; align-items: center; text-align: center; } .center{ display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; } .transparent{ background-color: rgba(255,255,255,0); pointer-events: none; } .noSelect{ -webkit-touch-callout: none; /* iOS Safari */ -webkit-user-select: none; /* Safari */ -khtml-user-select: none; /* Konqueror HTML */ -moz-user-select: none; /* Old versions of Firefox */ -ms-user-select: none; /* Internet Explorer/Edge */ user-select: none; /* Non-prefixed version, currently supported by Chrome, Edge, Opera and Firefox */ } .hide{ display: none; } .btn{ margin-left: 6px; } .forms{ margin-top: 50px; } .form{ display: grid; grid-template-columns: 1fr; grid-template-rows: 1fr; } .area{ border: 2px dashed #000000; font-size: 24px; background: #2d2d2d; width: 320px; height: 197px; padding-top: 36px; } .txt_area{ } .exe_area{ margin-top: 50px; } .area_hover{ border: 2px dashed #272629; background: #3F51B5; cursor: grabbing; } .area_active{ border: 2px dashed #272629; background: #4CAF50; cursor: grabbing; } .area_download{ padding-top: 46px; border: 2px solid #000000; cursor: pointer; border-radius: 4px } .area_download:hover{ background: #4CAF50; } .area_download:active{ background: #3F51B5; } .folder_icon{ font-size: 50px; } span{ font-weight: bold; font-size: 24px; } .suports{ font-size: 18px; } .span{ font-size: 16px; } .btn_compile{ background: #FFC107; width: 160px; height: 52px; line-height: 52px; margin-top: 50px; align-items: center; font-weight: bold; font-size: 20px; border-radius: 4px; border: 1px solid #000000; cursor: pointer; } .btn_compile:hover{ background: #3F51B5; } .btn_compile:active{ background: #4CAF50; }
main.js
const log = val => console.log( val ) const get = val => document.querySelector( val ) var txt_area = get('.txt_area') var exe_area = get('.exe_area') var txt_active = false var exe_active = false // audio var AUDIO = {} var audio = new Audio('ok.ogg') AUDIO.play = () => { audio.play() } // loader var LOADER = {} LOADER.hide = () => { get("#loader").classList.add("hide") } LOADER.show = () => { get("#loader").classList.remove("hide") } // active and remove var txt_active_fn = () => { txt_area.classList.remove("area_hover") txt_area.classList.add("area_active") // Confirm get(".folder_icon_txt").classList.add("hide") get(".confirm_icon_txt").classList.remove("hide") get(".txt_browse").classList.add("hide") get(".txt_remove").classList.remove("hide") txt_active = true update_compile_button() AUDIO.play() post_txt() } var exe_active_fn = () => { exe_area.classList.remove("area_hover") exe_area.classList.add("area_active") // Confirm get(".folder_icon_exe").classList.add("hide") get(".confirm_icon_exe").classList.remove("hide") get(".exe_browse").classList.add("hide") get(".exe_remove").classList.remove("hide") exe_active = true update_compile_button() AUDIO.play() } var txt_remove = () => { get('.input_file_txt').value = "" txt_area.classList.remove("area_active") get(".folder_icon_txt").classList.remove("hide") get(".confirm_icon_txt").classList.add("hide") get(".txt_browse").classList.remove("hide") get(".txt_remove").classList.add("hide") txt_active = false update_compile_button() } var exe_remove = () => { get('.input_file_exe').value = "" exe_area.classList.remove("area_active") get(".folder_icon_exe").classList.remove("hide") get(".confirm_icon_exe").classList.add("hide") get(".exe_browse").classList.remove("hide") get(".exe_remove").classList.add("hide") exe_active = false update_compile_button() } // txt_area txt_area.onclick = function(){ if( !txt_area.classList.contains("area_active") ){ get('.input_file_txt').click() }else{ txt_remove() } } txt_area.ondragenter = function(){ console.log("start") if( !txt_area.classList.contains("area_active") ){ txt_area.classList.add("area_hover") } } txt_area.ondragleave = function(){ console.log("end") if( !txt_area.classList.contains("area_active") ){ txt_area.classList.remove("area_hover") } } txt_area.ondragover = function (e) { e.preventDefault() } txt_area.ondrop = function(e){ e.preventDefault(); console.log("drop") txt_area.classList.remove("area_hover") txt_area.classList.add("area_active") get('.input_file_txt').files = e.dataTransfer.files const dT = new DataTransfer() dT.items.add(e.dataTransfer.files[0]) get('.input_file_txt').files = dT.files // Correct type var type = get(".input_file_txt").files[0].type var correct_type = "text/plain" if(type != correct_type){ txt_remove() alert("Correct type is TXT") return 0 } // Max size var size = get('.input_file_txt').files[0].size var max_size = 3525120 if(size > max_size){ txt_remove() alert("Max size is 3525120 kb") return 0 } txt_active_fn() } // exe_area exe_area.onclick = function(){ if( !exe_area.classList.contains("area_active") ){ get('.input_file_exe').click() }else{ exe_remove() } } exe_area.ondragenter = function(){ console.log("start") if( !exe_area.classList.contains("area_active") ){ exe_area.classList.add("area_hover") } } exe_area.ondragleave = function(){ console.log("end") if( !exe_area.classList.contains("area_active") ){ exe_area.classList.remove("area_hover") } } exe_area.ondragover = function (e) { e.preventDefault() } exe_area.ondrop = function(e){ e.preventDefault(); console.log("drop") exe_area.classList.remove("area_hover") exe_area.classList.add("area_active") get('.input_file_exe').files = e.dataTransfer.files const dT = new DataTransfer() dT.items.add(e.dataTransfer.files[0]) get('.input_file_exe').files = dT.files // Correct type var type = get(".input_file_exe").files[0].type var correct_type = "application/x-msdownload" if(type != correct_type){ get('.input_file_exe').files.clear() exe_area.classList.remove("area_active") alert("Correct type is EXE") return 0 } // Max size var size = get('.input_file_exe').files[0].size var max_size = 3525120 if(size > max_size){ get('.input_file_exe').files.clear() exe_area.classList.remove("area_active") alert("Max size is 3525120 kb") return 0 } exe_active_fn() } // compile var btn_compile = get(".btn_compile") var update_compile_button = () => { if(txt_active && exe_active){ btn_compile.classList.remove("hide") }else{ btn_compile.classList.add("hide") } } btn_compile.onclick = () => { LOADER.show() post_exe() } // post const txt = get("#txt"); const exe = get("#exe"); var post_txt = async() => { const formData = new FormData(txt); try { const response = await fetch('/uploads', { method: 'POST', body: formData }); const data = await response.json(); console.log(data); } catch (error) { console.error(error); } } var txt_change = () => { log("txt_change") if( get(".input_file_txt").files[0].type == "text/plain" ){ txt_active_fn() }else{ txt_remove() } } var link = "" var post_exe = async() => { const formData = new FormData(exe); try { const response = await fetch('/uploads', { method: 'POST', body: formData }); const data = await response.json(); link = data.download_link console.log(data); txt_remove() exe_remove() LOADER.hide() get(".txt_area").classList.add("hide") get(".exe_area").classList.add("hide") get(".area_download").classList.remove("hide") } catch (error) { console.error(error); } } var exe_change = () => { log("exe_change") if( get(".input_file_exe").files[0].type == "application/x-msdownload" ){ exe_active_fn() }else{ exe_remove() } } function saveFile(blob, filename) { if (window.navigator.msSaveOrOpenBlob) { window.navigator.msSaveOrOpenBlob(blob, filename); } else { const a = document.createElement('a'); document.body.appendChild(a); const url = window.URL.createObjectURL(blob); a.href = url; a.download = filename; a.click(); setTimeout(() => { window.URL.revokeObjectURL(url); document.body.removeChild(a); }, 0) } } get(".area_download").onclick = async() => { log("download") try { var result = await fetch(link).then(async res => ({ filename: res.headers.get('content-disposition').split('filename=')[1].split(';')[0].slice(1, -1), blob: await res.blob() })) saveFile(result.blob, result.filename) location.reload() } catch (error) { console.error(error); } }
Demo
Top comments (0)