mirror of
https://github.com/Derpy-Leggies/OnlyLegs.git
synced 2025-06-29 03:26:16 +00:00
Rename the gallery to onlylegs in the files
Im sorry
This commit is contained in:
parent
8029fff73e
commit
2174b10879
76 changed files with 66 additions and 20 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
onlylegs/static/error.png
Normal file
BIN
onlylegs/static/error.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
BIN
onlylegs/static/fonts/Rubik.ttf
Normal file
BIN
onlylegs/static/fonts/Rubik.ttf
Normal file
Binary file not shown.
7
onlylegs/static/fonts/font.css
Normal file
7
onlylegs/static/fonts/font.css
Normal file
|
@ -0,0 +1,7 @@
|
|||
@font-face {
|
||||
font-family: 'Rubik';
|
||||
src: url('./Rubik.ttf') format('truetype');
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
font-weight: 300 900;
|
||||
}
|
45
onlylegs/static/gen/js.js
Normal file
45
onlylegs/static/gen/js.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
function imgFade(obj,time=250){obj.style.transition=`opacity ${time}ms`;obj.style.opacity=1;}
|
||||
function loadOnView(){const lazyLoad=document.querySelectorAll('#lazy-load');const webpSupport=checkWebpSupport();for(let i=0;i<lazyLoad.length;i++){let image=lazyLoad[i];if(image.getBoundingClientRect().top<window.innerHeight&&image.getBoundingClientRect().bottom>0){if(!image.src&&webpSupport){image.src=image.getAttribute('data-src')+'&e=webp'}else if(!image.src){image.src=image.getAttribute('data-src')}}}}
|
||||
window.onload=function(){loadOnView();let times=document.querySelectorAll('.time');for(let i=0;i<times.length;i++){const raw=times[i].innerHTML.split('.')[0];const time=raw.split(' ')[1]
|
||||
const date=raw.split(' ')[0].split('-');let formatted=date[0]+'/'+date[1]+'/'+date[2]+' '+time+' UTC';let dateTime=new Date(formatted);times[i].innerHTML=dateTime.toLocaleDateString()+' '+dateTime.toLocaleTimeString();}
|
||||
let topOfPage=document.querySelector('.top-of-page');if(document.body.scrollTop>300||document.documentElement.scrollTop>20){topOfPage.classList.add('show');}else{topOfPage.classList.remove('show');}
|
||||
topOfPage.onclick=function(){document.body.scrollTop=0;document.documentElement.scrollTop=0;}
|
||||
let infoButton=document.querySelector('.info-button');if(infoButton){if(document.body.scrollTop>300||document.documentElement.scrollTop>20){infoButton.classList.remove('show');}else{infoButton.classList.add('show');}
|
||||
infoButton.onclick=function(){popUpShow('OnlyLegs','<a href="https://github.com/Fluffy-Bean/onlylegs">V23.04.10</a> '+
|
||||
'using <a href="https://phosphoricons.com/">Phosphoricons</a> and Flask.'+
|
||||
'<br>Made by Fluffy and others with ❤️');}}};window.onscroll=function(){loadOnView();let topOfPage=document.querySelector('.top-of-page');if(document.body.scrollTop>300||document.documentElement.scrollTop>20){topOfPage.classList.add('show');}else{topOfPage.classList.remove('show');}
|
||||
let infoButton=document.querySelector('.info-button');if(infoButton){if(document.body.scrollTop>300||document.documentElement.scrollTop>20){infoButton.classList.remove('show');}else{infoButton.classList.add('show');}}};window.onresize=function(){loadOnView();};function showLogin(){cancelBtn=document.createElement('button');cancelBtn.classList.add('btn-block');cancelBtn.innerHTML='nuuuuuuuu';cancelBtn.onclick=popupDissmiss;loginBtn=document.createElement('button');loginBtn.classList.add('btn-block');loginBtn.classList.add('primary');loginBtn.innerHTML='Login';loginBtn.type='submit';loginBtn.setAttribute('form','loginForm');loginForm=document.createElement('form');loginForm.id='loginForm';loginForm.setAttribute('onsubmit','return login(event);');usernameInput=document.createElement('input');usernameInput.classList.add('input-block');usernameInput.type='text';usernameInput.placeholder='Namey';usernameInput.id='username';passwordInput=document.createElement('input');passwordInput.classList.add('input-block');passwordInput.type='password';passwordInput.placeholder='Passywassy';passwordInput.id='password';rememberMeSpan=document.createElement('span');rememberMeSpan.classList.add('input-checkbox');rememberMeInput=document.createElement('input');rememberMeInput.type='checkbox';rememberMeInput.id='remember-me';rememberMeLabel=document.createElement('label');rememberMeLabel.innerHTML='No forgetty me pls';rememberMeLabel.setAttribute('for','remember-me');rememberMeSpan.appendChild(rememberMeInput);rememberMeSpan.appendChild(rememberMeLabel);loginForm.appendChild(usernameInput);loginForm.appendChild(passwordInput);loginForm.appendChild(rememberMeSpan);popUpShow('Login!','Need an account? <span class="link" onclick="showRegister()">Register!</span>',loginForm,[cancelBtn,loginBtn]);}
|
||||
function login(event){event.preventDefault();let formUsername=document.querySelector("#username").value;let formPassword=document.querySelector("#password").value;let formRememberMe=document.querySelector("#remember-me").checked;if(formUsername===""||formPassword===""){addNotification("Please fill in all fields!!!!",3);return;}
|
||||
const formData=new FormData();formData.append("username",formUsername);formData.append("password",formPassword);formData.append("remember-me",formRememberMe);fetch('/auth/login',{method:'POST',body:formData}).then(response=>{if(response.ok){location.reload();}else{if(response.status===403){addNotification('None but devils play past here... Wrong information',2);}else if(response.status===500){addNotification('Server exploded, F\'s in chat',2);}else{addNotification('Error logging in, blame someone',2);}}}).catch(error=>{addNotification('Error logging in, blame someone',2);});}
|
||||
function showRegister(){cancelBtn=document.createElement('button');cancelBtn.classList.add('btn-block');cancelBtn.innerHTML='nuuuuuuuu';cancelBtn.onclick=popupDissmiss;registerBtn=document.createElement('button');registerBtn.classList.add('btn-block');registerBtn.classList.add('primary');registerBtn.innerHTML='Register';registerBtn.type='submit';registerBtn.setAttribute('form','registerForm');registerForm=document.createElement('form');registerForm.id='registerForm';registerForm.setAttribute('onsubmit','return register(event);');usernameInput=document.createElement('input');usernameInput.classList.add('input-block');usernameInput.type='text';usernameInput.placeholder='Namey';usernameInput.id='username';emailInput=document.createElement('input');emailInput.classList.add('input-block');emailInput.type='text';emailInput.placeholder='E mail!';emailInput.id='email';passwordInput=document.createElement('input');passwordInput.classList.add('input-block');passwordInput.type='password';passwordInput.placeholder='Passywassy';passwordInput.id='password';passwordInputRepeat=document.createElement('input');passwordInputRepeat.classList.add('input-block');passwordInputRepeat.type='password';passwordInputRepeat.placeholder='Passywassy again!';passwordInputRepeat.id='password-repeat';registerForm.appendChild(usernameInput);registerForm.appendChild(emailInput);registerForm.appendChild(passwordInput);registerForm.appendChild(passwordInputRepeat);popUpShow('Who are you?','Already have an account? <span class="link" onclick="showLogin()">Login!</span>',registerForm,[cancelBtn,registerBtn]);}
|
||||
function register(event){event.preventDefault();let formUsername=document.querySelector("#username").value;let formEmail=document.querySelector("#email").value;let formPassword=document.querySelector("#password").value;let formPasswordRepeat=document.querySelector("#password-repeat").value;if(formUsername===""||formEmail===""||formPassword===""||formPasswordRepeat===""){addNotification("Please fill in all fields!!!!",3);return;}
|
||||
const formData=new FormData();formData.append("username",formUsername);formData.append("email",formEmail);formData.append("password",formPassword);formData.append("password-repeat",formPasswordRepeat);fetch('/auth/register',{method:'POST',body:formData}).then(response=>{if(response.ok){addNotification('Registered successfully! Now please login to continue',1);showLogin();}else{if(response.status===400){response.json().then(data=>{for(let i=0;i<data.length;i++){addNotification(data[i],2);}});}else if(response.status===403){addNotification('None but devils play past here... Wrong information',2);}else if(response.status===500){addNotification('Server exploded, F\'s in chat',2);}else{addNotification('Error logging in, blame someone',2);}}}).catch(error=>{addNotification('Error logging in, blame someone',2);});}
|
||||
function addNotification(notificationText,notificationLevel){const notificationContainer=document.querySelector('.notifications');const successIcon='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z"></path></svg>';const criticalIcon='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1-7.48,4.2H40.55a8.5,8.5,0,0,1-7.48-4.2,7.59,7.59,0,0,1,0-7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,180Z"></path></svg>';const warningIcon='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path></svg>';const infoIcon='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path></svg>';const notification=document.createElement('div');notification.classList.add('sniffle__notification');notification.onclick=function(){if(notification){notification.classList.add('hide');setTimeout(function(){notificationContainer.removeChild(notification);},500);}};const iconElement=document.createElement('span');iconElement.classList.add('sniffle__notification-icon');notification.appendChild(iconElement);if(notificationLevel===1){notification.classList.add('success');iconElement.innerHTML=successIcon;}else if(notificationLevel===2){notification.classList.add('critical');iconElement.innerHTML=criticalIcon;}else if(notificationLevel===3){notification.classList.add('warning');iconElement.innerHTML=warningIcon;}else{notification.classList.add('info');iconElement.innerHTML=infoIcon;}
|
||||
const description=document.createElement('span');description.classList.add('sniffle__notification-text');description.innerHTML=notificationText;notification.appendChild(description);notificationContainer.appendChild(notification);setTimeout(function(){notification.classList.add('show');},5);setTimeout(function(){if(notification){notification.classList.add('hide');setTimeout(function(){notificationContainer.removeChild(notification);},500);}},5000);}
|
||||
function popUpShow(titleText,subtitleText,bodyContent=null,userActions=null){const popupSelector=document.querySelector('.pop-up');const headerSelector=document.querySelector('.pop-up-header');const actionsSelector=document.querySelector('.pop-up-controlls');headerSelector.innerHTML='';actionsSelector.innerHTML='';const titleElement=document.createElement('h2');titleElement.innerHTML=titleText;headerSelector.appendChild(titleElement);const subtitleElement=document.createElement('p');subtitleElement.innerHTML=subtitleText;headerSelector.appendChild(subtitleElement);if(bodyContent){headerSelector.appendChild(bodyContent);}
|
||||
if(userActions){for(let i=0;i<userActions.length;i++){actionsSelector.appendChild(userActions[i]);}}else{actionsSelector.innerHTML='<button class="btn-block" onclick="popupDissmiss()">Close</button>';}
|
||||
document.querySelector("html").style.overflow="hidden";popupSelector.style.display='block';setTimeout(function(){popupSelector.classList.add('active')},5);}
|
||||
function popupDissmiss(){const popupSelector=document.querySelector('.pop-up');document.querySelector("html").style.overflow="auto";popupSelector.classList.remove('active');setTimeout(function(){popupSelector.style.display='none';},200);}
|
||||
window.addEventListener("dragover",(event)=>{event.preventDefault();},false);window.addEventListener("drop",(event)=>{event.preventDefault();},false);function openUploadTab(){let uploadTab=document.querySelector(".upload-panel");document.querySelector("html").style.overflow="hidden";uploadTab.style.display="block";setTimeout(function(){uploadTab.classList.add("open");},5);}
|
||||
function closeUploadTab(){let uploadTab=document.querySelector(".upload-panel");let uploadTabContainer=document.querySelector(".upload-panel .container");document.querySelector("html").style.overflow="auto";uploadTab.classList.remove("open");setTimeout(function(){uploadTab.style.display="none";uploadTabContainer.style.transform="";uploadTab.dataset.lastY=0;},250);}
|
||||
function toggleUploadTab(){let uploadTab=document.querySelector(".upload-panel");if(uploadTab.classList.contains("open")){closeUploadTab();}else{openUploadTab();}}
|
||||
function tabDragStart(event){event.preventDefault();let uploadTab=document.querySelector(".upload-panel .container");let offset=uploadTab.getBoundingClientRect().y;uploadTab.classList.add("dragging");document.addEventListener('touchmove',event=>{if(uploadTab.classList.contains("dragging")){if(event.touches[0].clientY-offset>=0){uploadTab.dataset.lastY=event.touches[0].clientY;}else{uploadTab.dataset.lastY=offset;}
|
||||
uploadTab.style.transform=`translateY(${uploadTab.dataset.lastY-offset}px)`;}});}
|
||||
function tabDragStopped(event){event.preventDefault();let uploadTab=document.querySelector(".upload-panel .container");uploadTab.classList.remove("dragging");if(uploadTab.dataset.lastY>(screen.height*0.3)){closeUploadTab();}else{uploadTab.style.transition="transform 0.25s cubic-bezier(0.76, 0, 0.17, 1)";uploadTab.style.transform="translateY(0px)";setTimeout(function(){uploadTab.style.transition="";},250);}}
|
||||
function fileActivate(event){event.preventDefault()
|
||||
let fileDrop=document.querySelector('.fileDrop-block');let fileDropTitle=fileDrop.querySelector('.status');fileDrop.classList.remove('error');fileDrop.classList.add('edging');fileDropTitle.innerHTML='Drop to upload!';}
|
||||
function fileDefault(){let fileDrop=document.querySelector('.fileDrop-block');let fileDropTitle=fileDrop.querySelector('.status');fileDrop.classList.remove('error');fileDrop.classList.remove('edging');fileDropTitle.innerHTML='Choose or Drop file';}
|
||||
function fileDropHandle(event){event.preventDefault()
|
||||
let fileDrop=document.querySelector('.fileDrop-block');let fileUpload=fileDrop.querySelector('#file');fileUpload.files=event.dataTransfer.files;fileDefault();fileChanged();}
|
||||
function fileChanged(){let dropBlock=document.querySelector('.fileDrop-block');let dropBlockStatus=dropBlock.querySelector('.status');let dropBlockInput=dropBlock.querySelector('#file');if(dropBlockInput.value!==""){dropBlock.classList.add('active');dropBlockStatus.innerHTML=dropBlockInput.files[0].name;}else{fileDefault();}}
|
||||
function clearUpload(){let fileDrop=document.querySelector('#uploadForm');let fileUpload=fileDrop.querySelector('#file');let fileAlt=fileDrop.querySelector('#alt');let fileDescription=fileDrop.querySelector('#description');let fileTags=fileDrop.querySelector('#tags');fileUpload.value="";fileAlt.value="";fileDescription.value="";fileTags.value="";}
|
||||
document.addEventListener('DOMContentLoaded',()=>{let uploadTab=document.querySelector(".upload-panel");if(!uploadTab){return;}
|
||||
let uploadTabDrag=uploadTab.querySelector("#dragIndicator");let uploadForm=uploadTab.querySelector('#uploadForm');let fileDrop=uploadForm.querySelector('.fileDrop-block');let fileDropTitle=fileDrop.querySelector('.status');let fileUpload=fileDrop.querySelector('#file');let fileAlt=uploadForm.querySelector('#alt');let fileDescription=uploadForm.querySelector('#description');let fileTags=uploadForm.querySelector('#tags');clearUpload();fileDefault();uploadTabDrag.addEventListener('touchstart',tabDragStart,false);uploadTabDrag.addEventListener('touchend',tabDragStopped,false);fileDrop.addEventListener('dragover',fileActivate,false);fileDrop.addEventListener('dragenter',fileActivate,false);fileDrop.addEventListener('dragleave',fileDefault,false);fileDrop.addEventListener('drop',fileDropHandle,false);fileUpload.addEventListener('change',fileChanged,false);fileUpload.addEventListener('click',fileDefault,false);uploadForm.addEventListener('submit',(event)=>{event.preventDefault()
|
||||
if(fileUpload.value===""){fileDrop.classList.add('error');fileDropTitle.innerHTML='No file selected!';return;}
|
||||
let formData=new FormData();formData.append("file",fileUpload.files[0]);formData.append("alt",fileAlt.value);formData.append("description",fileDescription.value);formData.append("tags",fileTags.value);fetch('/api/upload',{method:'POST',body:formData})
|
||||
.then(data=>{addNotification("Image uploaded successfully",1);}).catch(error=>{switch(response.status){case 500:addNotification("Server exploded, F's in chat",2)
|
||||
break;case 400:case 404:addNotification("Error uploading. Blame yourself",2)
|
||||
break;case 403:addNotification("None but devils play past here...",2)
|
||||
break;case 413:addNotification("File too large!!!!!!",2);break;default:addNotification("Error uploading file, blame someone",2)
|
||||
break;}});clearUpload();fileDrop.classList.remove('active');fileDropTitle.innerHTML='Choose or Drop file';});});function checkWebpSupport(){let webpSupport=false;try{webpSupport=document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp')===0;}catch(e){webpSupport=false;}
|
||||
return webpSupport;}
|
1
onlylegs/static/gen/styles.css
Normal file
1
onlylegs/static/gen/styles.css
Normal file
File diff suppressed because one or more lines are too long
BIN
onlylegs/static/icon.png
Normal file
BIN
onlylegs/static/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 29 KiB |
98
onlylegs/static/js/index.js
Normal file
98
onlylegs/static/js/index.js
Normal file
|
@ -0,0 +1,98 @@
|
|||
// fade in images
|
||||
function imgFade(obj, time = 250) {
|
||||
obj.style.transition = `opacity ${time}ms`;
|
||||
obj.style.opacity = 1;
|
||||
}
|
||||
// Lazy load images when they are in view
|
||||
function loadOnView() {
|
||||
const lazyLoad = document.querySelectorAll('#lazy-load');
|
||||
const webpSupport = checkWebpSupport();
|
||||
|
||||
for (let i = 0; i < lazyLoad.length; i++) {
|
||||
let image = lazyLoad[i];
|
||||
if (image.getBoundingClientRect().top < window.innerHeight && image.getBoundingClientRect().bottom > 0) {
|
||||
if (!image.src && webpSupport) {
|
||||
image.src = image.getAttribute('data-src') + '&e=webp'
|
||||
} else if (!image.src) {
|
||||
image.src = image.getAttribute('data-src')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
loadOnView();
|
||||
|
||||
let times = document.querySelectorAll('.time');
|
||||
for (let i = 0; i < times.length; i++) {
|
||||
// Remove milliseconds
|
||||
const raw = times[i].innerHTML.split('.')[0];
|
||||
|
||||
// Parse YYYY-MM-DD HH:MM:SS to Date object
|
||||
const time = raw.split(' ')[1]
|
||||
const date = raw.split(' ')[0].split('-');
|
||||
|
||||
// Format to YYYY/MM/DD HH:MM:SS
|
||||
let formatted = date[0] + '/' + date[1] + '/' + date[2] + ' ' + time + ' UTC';
|
||||
|
||||
// Convert to UTC Date object
|
||||
let dateTime = new Date(formatted);
|
||||
|
||||
// Convert to local time
|
||||
times[i].innerHTML = dateTime.toLocaleDateString() + ' ' + dateTime.toLocaleTimeString();
|
||||
}
|
||||
|
||||
// Top Of Page button
|
||||
let topOfPage = document.querySelector('.top-of-page');
|
||||
if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 20) {
|
||||
topOfPage.classList.add('show');
|
||||
} else {
|
||||
topOfPage.classList.remove('show');
|
||||
}
|
||||
topOfPage.onclick = function () {
|
||||
document.body.scrollTop = 0;
|
||||
document.documentElement.scrollTop = 0;
|
||||
}
|
||||
|
||||
// Info button
|
||||
let infoButton = document.querySelector('.info-button');
|
||||
|
||||
if (infoButton) {
|
||||
if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 20) {
|
||||
infoButton.classList.remove('show');
|
||||
} else {
|
||||
infoButton.classList.add('show');
|
||||
}
|
||||
infoButton.onclick = function () {
|
||||
popUpShow('OnlyLegs',
|
||||
'<a href="https://github.com/Fluffy-Bean/onlylegs">V23.04.10</a> ' +
|
||||
'using <a href="https://phosphoricons.com/">Phosphoricons</a> and Flask.' +
|
||||
'<br>Made by Fluffy and others with ❤️');
|
||||
}
|
||||
}
|
||||
};
|
||||
window.onscroll = function () {
|
||||
loadOnView();
|
||||
|
||||
// Top Of Page button
|
||||
let topOfPage = document.querySelector('.top-of-page');
|
||||
if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 20) {
|
||||
topOfPage.classList.add('show');
|
||||
} else {
|
||||
topOfPage.classList.remove('show');
|
||||
}
|
||||
|
||||
// Info button
|
||||
let infoButton = document.querySelector('.info-button');
|
||||
|
||||
if (infoButton) {
|
||||
if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 20) {
|
||||
infoButton.classList.remove('show');
|
||||
} else {
|
||||
infoButton.classList.add('show');
|
||||
}
|
||||
}
|
||||
};
|
||||
window.onresize = function () {
|
||||
loadOnView();
|
||||
};
|
202
onlylegs/static/js/login.js
Normal file
202
onlylegs/static/js/login.js
Normal file
|
@ -0,0 +1,202 @@
|
|||
// Function to show login
|
||||
function showLogin() {
|
||||
// Create elements
|
||||
cancelBtn = document.createElement('button');
|
||||
cancelBtn.classList.add('btn-block');
|
||||
cancelBtn.innerHTML = 'nuuuuuuuu';
|
||||
cancelBtn.onclick = popupDissmiss;
|
||||
|
||||
loginBtn = document.createElement('button');
|
||||
loginBtn.classList.add('btn-block');
|
||||
loginBtn.classList.add('primary');
|
||||
loginBtn.innerHTML = 'Login';
|
||||
loginBtn.type = 'submit';
|
||||
loginBtn.setAttribute('form', 'loginForm');
|
||||
|
||||
// Create form
|
||||
loginForm = document.createElement('form');
|
||||
loginForm.id = 'loginForm';
|
||||
loginForm.setAttribute('onsubmit', 'return login(event);');
|
||||
|
||||
usernameInput = document.createElement('input');
|
||||
usernameInput.classList.add('input-block');
|
||||
usernameInput.type = 'text';
|
||||
usernameInput.placeholder = 'Namey';
|
||||
usernameInput.id = 'username';
|
||||
|
||||
passwordInput = document.createElement('input');
|
||||
passwordInput.classList.add('input-block');
|
||||
passwordInput.type = 'password';
|
||||
passwordInput.placeholder = 'Passywassy';
|
||||
passwordInput.id = 'password';
|
||||
|
||||
// Container for remember me checkbox
|
||||
rememberMeSpan = document.createElement('span');
|
||||
rememberMeSpan.classList.add('input-checkbox');
|
||||
|
||||
rememberMeInput = document.createElement('input');
|
||||
rememberMeInput.type = 'checkbox';
|
||||
rememberMeInput.id = 'remember-me';
|
||||
|
||||
rememberMeLabel = document.createElement('label');
|
||||
rememberMeLabel.innerHTML = 'No forgetty me pls';
|
||||
rememberMeLabel.setAttribute('for', 'remember-me');
|
||||
|
||||
rememberMeSpan.appendChild(rememberMeInput);
|
||||
rememberMeSpan.appendChild(rememberMeLabel);
|
||||
|
||||
loginForm.appendChild(usernameInput);
|
||||
loginForm.appendChild(passwordInput);
|
||||
loginForm.appendChild(rememberMeSpan);
|
||||
|
||||
popUpShow(
|
||||
'Login!',
|
||||
'Need an account? <span class="link" onclick="showRegister()">Register!</span>',
|
||||
loginForm,
|
||||
[cancelBtn, loginBtn]
|
||||
);
|
||||
}
|
||||
// Function to login
|
||||
function login(event) {
|
||||
// AJAX takes control of subby form :3
|
||||
event.preventDefault();
|
||||
|
||||
let formUsername = document.querySelector("#username").value;
|
||||
let formPassword = document.querySelector("#password").value;
|
||||
let formRememberMe = document.querySelector("#remember-me").checked;
|
||||
|
||||
if (formUsername === "" || formPassword === "") {
|
||||
addNotification("Please fill in all fields!!!!", 3);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make form
|
||||
const formData = new FormData();
|
||||
formData.append("username", formUsername);
|
||||
formData.append("password", formPassword);
|
||||
formData.append("remember-me", formRememberMe);
|
||||
|
||||
fetch('/auth/login', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
location.reload();
|
||||
} else {
|
||||
if (response.status === 403) {
|
||||
addNotification('None but devils play past here... Wrong information', 2);
|
||||
} else if (response.status === 500) {
|
||||
addNotification('Server exploded, F\'s in chat', 2);
|
||||
} else {
|
||||
addNotification('Error logging in, blame someone', 2);
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
addNotification('Error logging in, blame someone', 2);
|
||||
});
|
||||
}
|
||||
// Function to show register
|
||||
function showRegister() {
|
||||
// Create buttons
|
||||
cancelBtn = document.createElement('button');
|
||||
cancelBtn.classList.add('btn-block');
|
||||
cancelBtn.innerHTML = 'nuuuuuuuu';
|
||||
cancelBtn.onclick = popupDissmiss;
|
||||
|
||||
registerBtn = document.createElement('button');
|
||||
registerBtn.classList.add('btn-block');
|
||||
registerBtn.classList.add('primary');
|
||||
registerBtn.innerHTML = 'Register';
|
||||
registerBtn.type = 'submit';
|
||||
registerBtn.setAttribute('form', 'registerForm');
|
||||
|
||||
// Create form
|
||||
registerForm = document.createElement('form');
|
||||
registerForm.id = 'registerForm';
|
||||
registerForm.setAttribute('onsubmit', 'return register(event);');
|
||||
|
||||
usernameInput = document.createElement('input');
|
||||
usernameInput.classList.add('input-block');
|
||||
usernameInput.type = 'text';
|
||||
usernameInput.placeholder = 'Namey';
|
||||
usernameInput.id = 'username';
|
||||
|
||||
emailInput = document.createElement('input');
|
||||
emailInput.classList.add('input-block');
|
||||
emailInput.type = 'text';
|
||||
emailInput.placeholder = 'E mail!';
|
||||
emailInput.id = 'email';
|
||||
|
||||
passwordInput = document.createElement('input');
|
||||
passwordInput.classList.add('input-block');
|
||||
passwordInput.type = 'password';
|
||||
passwordInput.placeholder = 'Passywassy';
|
||||
passwordInput.id = 'password';
|
||||
|
||||
passwordInputRepeat = document.createElement('input');
|
||||
passwordInputRepeat.classList.add('input-block');
|
||||
passwordInputRepeat.type = 'password';
|
||||
passwordInputRepeat.placeholder = 'Passywassy again!';
|
||||
passwordInputRepeat.id = 'password-repeat';
|
||||
|
||||
registerForm.appendChild(usernameInput);
|
||||
registerForm.appendChild(emailInput);
|
||||
registerForm.appendChild(passwordInput);
|
||||
registerForm.appendChild(passwordInputRepeat);
|
||||
|
||||
popUpShow(
|
||||
'Who are you?',
|
||||
'Already have an account? <span class="link" onclick="showLogin()">Login!</span>',
|
||||
registerForm,
|
||||
[cancelBtn, registerBtn]
|
||||
);
|
||||
}
|
||||
// Function to register
|
||||
function register(event) {
|
||||
// AJAX takes control of subby form
|
||||
event.preventDefault();
|
||||
|
||||
let formUsername = document.querySelector("#username").value;
|
||||
let formEmail = document.querySelector("#email").value;
|
||||
let formPassword = document.querySelector("#password").value;
|
||||
let formPasswordRepeat = document.querySelector("#password-repeat").value;
|
||||
|
||||
if (formUsername === "" || formEmail === "" || formPassword === "" || formPasswordRepeat === "") {
|
||||
addNotification("Please fill in all fields!!!!", 3);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make form
|
||||
const formData = new FormData();
|
||||
formData.append("username", formUsername);
|
||||
formData.append("email", formEmail);
|
||||
formData.append("password", formPassword);
|
||||
formData.append("password-repeat", formPasswordRepeat);
|
||||
|
||||
// Send form to server
|
||||
fetch('/auth/register', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
}).then(response => {
|
||||
if (response.ok) {
|
||||
addNotification('Registered successfully! Now please login to continue', 1);
|
||||
showLogin();
|
||||
} else {
|
||||
if (response.status === 400) {
|
||||
response.json().then(data => {
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
addNotification(data[i], 2);
|
||||
}
|
||||
});
|
||||
} else if (response.status === 403) {
|
||||
addNotification('None but devils play past here... Wrong information', 2);
|
||||
} else if (response.status === 500) {
|
||||
addNotification('Server exploded, F\'s in chat', 2);
|
||||
} else {
|
||||
addNotification('Error logging in, blame someone', 2);
|
||||
}
|
||||
}
|
||||
}).catch(error => {
|
||||
addNotification('Error logging in, blame someone', 2);
|
||||
});
|
||||
}
|
63
onlylegs/static/js/notifications.js
Normal file
63
onlylegs/static/js/notifications.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
function addNotification(notificationText, notificationLevel) {
|
||||
const notificationContainer = document.querySelector('.notifications');
|
||||
|
||||
// Set the different icons for the different notification levels
|
||||
const successIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M229.66,77.66l-128,128a8,8,0,0,1-11.32,0l-56-56a8,8,0,0,1,11.32-11.32L96,188.69,218.34,66.34a8,8,0,0,1,11.32,11.32Z"></path></svg>';
|
||||
const criticalIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M236.8,188.09,149.35,36.22h0a24.76,24.76,0,0,0-42.7,0L19.2,188.09a23.51,23.51,0,0,0,0,23.72A24.35,24.35,0,0,0,40.55,224h174.9a24.35,24.35,0,0,0,21.33-12.19A23.51,23.51,0,0,0,236.8,188.09ZM222.93,203.8a8.5,8.5,0,0,1-7.48,4.2H40.55a8.5,8.5,0,0,1-7.48-4.2,7.59,7.59,0,0,1,0-7.72L120.52,44.21a8.75,8.75,0,0,1,15,0l87.45,151.87A7.59,7.59,0,0,1,222.93,203.8ZM120,144V104a8,8,0,0,1,16,0v40a8,8,0,0,1-16,0Zm20,36a12,12,0,1,1-12-12A12,12,0,0,1,140,180Z"></path></svg>';
|
||||
const warningIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path></svg>';
|
||||
const infoIcon = '<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="currentColor" viewBox="0 0 256 256"><path d="M128,24A104,104,0,1,0,232,128,104.11,104.11,0,0,0,128,24Zm0,192a88,88,0,1,1,88-88A88.1,88.1,0,0,1,128,216Zm16-40a8,8,0,0,1-8,8,16,16,0,0,1-16-16V128a8,8,0,0,1,0-16,16,16,0,0,1,16,16v40A8,8,0,0,1,144,176ZM112,84a12,12,0,1,1,12,12A12,12,0,0,1,112,84Z"></path></svg>';
|
||||
|
||||
// Create notification element
|
||||
const notification = document.createElement('div');
|
||||
notification.classList.add('sniffle__notification');
|
||||
notification.onclick = function() {
|
||||
if (notification) {
|
||||
notification.classList.add('hide');
|
||||
|
||||
setTimeout(function() {
|
||||
notificationContainer.removeChild(notification);
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
// Create icon element and append to notification
|
||||
const iconElement = document.createElement('span');
|
||||
iconElement.classList.add('sniffle__notification-icon');
|
||||
notification.appendChild(iconElement);
|
||||
|
||||
// Set the icon based on the notification level, not pretty but it works :3
|
||||
if (notificationLevel === 1) {
|
||||
notification.classList.add('success');
|
||||
iconElement.innerHTML = successIcon;
|
||||
} else if (notificationLevel === 2) {
|
||||
notification.classList.add('critical');
|
||||
iconElement.innerHTML = criticalIcon;
|
||||
} else if (notificationLevel === 3) {
|
||||
notification.classList.add('warning');
|
||||
iconElement.innerHTML = warningIcon;
|
||||
} else {
|
||||
notification.classList.add('info');
|
||||
iconElement.innerHTML = infoIcon;
|
||||
}
|
||||
|
||||
// Create text element and append to notification
|
||||
const description = document.createElement('span');
|
||||
description.classList.add('sniffle__notification-text');
|
||||
description.innerHTML = notificationText;
|
||||
notification.appendChild(description);
|
||||
|
||||
// Append notification to container
|
||||
notificationContainer.appendChild(notification);
|
||||
setTimeout(function() { notification.classList.add('show'); }, 5);
|
||||
|
||||
// Remove notification after 5 seconds
|
||||
setTimeout(function() {
|
||||
if (notification) {
|
||||
notification.classList.add('hide');
|
||||
|
||||
setTimeout(function() {
|
||||
notificationContainer.removeChild(notification);
|
||||
}, 500);
|
||||
}
|
||||
}, 5000);
|
||||
}
|
46
onlylegs/static/js/popup.js
Normal file
46
onlylegs/static/js/popup.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
function popUpShow(titleText, subtitleText, bodyContent=null, userActions=null) {
|
||||
// Get popup elements
|
||||
const popupSelector = document.querySelector('.pop-up');
|
||||
const headerSelector = document.querySelector('.pop-up-header');
|
||||
const actionsSelector = document.querySelector('.pop-up-controlls');
|
||||
|
||||
// Clear popup elements
|
||||
headerSelector.innerHTML = '';
|
||||
actionsSelector.innerHTML = '';
|
||||
|
||||
// Set popup header and subtitle
|
||||
const titleElement = document.createElement('h2');
|
||||
titleElement.innerHTML = titleText;
|
||||
headerSelector.appendChild(titleElement);
|
||||
|
||||
const subtitleElement = document.createElement('p');
|
||||
subtitleElement.innerHTML = subtitleText;
|
||||
headerSelector.appendChild(subtitleElement);
|
||||
|
||||
if (bodyContent) {
|
||||
headerSelector.appendChild(bodyContent);
|
||||
}
|
||||
|
||||
// Set buttons that will be displayed
|
||||
if (userActions) {
|
||||
// for each user action, add the element
|
||||
for (let i = 0; i < userActions.length; i++) {
|
||||
actionsSelector.appendChild(userActions[i]);
|
||||
}
|
||||
} else {
|
||||
actionsSelector.innerHTML = '<button class="btn-block" onclick="popupDissmiss()">Close</button>';
|
||||
}
|
||||
|
||||
// Stop scrolling and show popup
|
||||
document.querySelector("html").style.overflow = "hidden";
|
||||
popupSelector.style.display = 'block';
|
||||
setTimeout(function() { popupSelector.classList.add('active') }, 5); // 2ms delay to allow for css transition >:C
|
||||
}
|
||||
|
||||
function popupDissmiss() {
|
||||
const popupSelector = document.querySelector('.pop-up');
|
||||
|
||||
document.querySelector("html").style.overflow = "auto";
|
||||
popupSelector.classList.remove('active');
|
||||
setTimeout(function() { popupSelector.style.display = 'none'; }, 200);
|
||||
}
|
313
onlylegs/static/js/uploadTab.js
Normal file
313
onlylegs/static/js/uploadTab.js
Normal file
|
@ -0,0 +1,313 @@
|
|||
// Remove default events on file drop, otherwise the browser will open the file
|
||||
window.addEventListener("dragover", (event) => {
|
||||
event.preventDefault();
|
||||
}, false);
|
||||
window.addEventListener("drop", (event) => {
|
||||
event.preventDefault();
|
||||
}, false);
|
||||
|
||||
|
||||
// open upload tab
|
||||
function openUploadTab() {
|
||||
let uploadTab = document.querySelector(".upload-panel");
|
||||
|
||||
// Stop scrolling and open upload tab
|
||||
document.querySelector("html").style.overflow = "hidden";
|
||||
uploadTab.style.display = "block";
|
||||
setTimeout(function () { uploadTab.classList.add("open"); }, 5);
|
||||
}
|
||||
|
||||
// close upload tab
|
||||
function closeUploadTab() {
|
||||
let uploadTab = document.querySelector(".upload-panel");
|
||||
let uploadTabContainer = document.querySelector(".upload-panel .container");
|
||||
|
||||
// un-Stop scrolling and close upload tab
|
||||
document.querySelector("html").style.overflow = "auto";
|
||||
uploadTab.classList.remove("open");
|
||||
setTimeout(function () {
|
||||
uploadTab.style.display = "none";
|
||||
|
||||
uploadTabContainer.style.transform = "";
|
||||
uploadTab.dataset.lastY = 0;
|
||||
}, 250);
|
||||
}
|
||||
|
||||
// toggle upload tab
|
||||
function toggleUploadTab() {
|
||||
let uploadTab = document.querySelector(".upload-panel");
|
||||
|
||||
if (uploadTab.classList.contains("open")) {
|
||||
closeUploadTab();
|
||||
} else {
|
||||
openUploadTab();
|
||||
}
|
||||
}
|
||||
|
||||
function tabDragStart(event) {
|
||||
event.preventDefault();
|
||||
|
||||
let uploadTab = document.querySelector(".upload-panel .container");
|
||||
let offset = uploadTab.getBoundingClientRect().y;
|
||||
|
||||
uploadTab.classList.add("dragging");
|
||||
|
||||
document.addEventListener('touchmove', event => {
|
||||
if (uploadTab.classList.contains("dragging")) {
|
||||
if (event.touches[0].clientY - offset >= 0) {
|
||||
uploadTab.dataset.lastY = event.touches[0].clientY;
|
||||
} else {
|
||||
uploadTab.dataset.lastY = offset;
|
||||
}
|
||||
|
||||
uploadTab.style.transform = `translateY(${uploadTab.dataset.lastY - offset}px)`;
|
||||
}
|
||||
});
|
||||
}
|
||||
function tabDragStopped(event) {
|
||||
event.preventDefault();
|
||||
|
||||
let uploadTab = document.querySelector(".upload-panel .container");
|
||||
|
||||
uploadTab.classList.remove("dragging");
|
||||
|
||||
if (uploadTab.dataset.lastY > (screen.height * 0.3)) {
|
||||
closeUploadTab();
|
||||
} else {
|
||||
uploadTab.style.transition = "transform 0.25s cubic-bezier(0.76, 0, 0.17, 1)";
|
||||
uploadTab.style.transform = "translateY(0px)";
|
||||
setTimeout(function () { uploadTab.style.transition = ""; }, 250);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Edging the file plunge :3
|
||||
function fileActivate(event) {
|
||||
event.preventDefault()
|
||||
|
||||
let fileDrop = document.querySelector('.fileDrop-block');
|
||||
let fileDropTitle = fileDrop.querySelector('.status');
|
||||
|
||||
fileDrop.classList.remove('error');
|
||||
fileDrop.classList.add('edging');
|
||||
fileDropTitle.innerHTML = 'Drop to upload!';
|
||||
}
|
||||
function fileDefault() {
|
||||
let fileDrop = document.querySelector('.fileDrop-block');
|
||||
let fileDropTitle = fileDrop.querySelector('.status');
|
||||
|
||||
fileDrop.classList.remove('error');
|
||||
fileDrop.classList.remove('edging');
|
||||
fileDropTitle.innerHTML = 'Choose or Drop file';
|
||||
}
|
||||
|
||||
function fileDropHandle(event) {
|
||||
event.preventDefault()
|
||||
|
||||
let fileDrop = document.querySelector('.fileDrop-block');
|
||||
let fileUpload = fileDrop.querySelector('#file');
|
||||
|
||||
fileUpload.files = event.dataTransfer.files;
|
||||
|
||||
fileDefault();
|
||||
fileChanged();
|
||||
}
|
||||
|
||||
function fileChanged() {
|
||||
let dropBlock = document.querySelector('.fileDrop-block');
|
||||
let dropBlockStatus = dropBlock.querySelector('.status');
|
||||
let dropBlockInput = dropBlock.querySelector('#file');
|
||||
|
||||
if (dropBlockInput.value !== "") {
|
||||
dropBlock.classList.add('active');
|
||||
dropBlockStatus.innerHTML = dropBlockInput.files[0].name;
|
||||
} else {
|
||||
fileDefault();
|
||||
}
|
||||
}
|
||||
|
||||
function clearUpload() {
|
||||
let fileDrop = document.querySelector('#uploadForm');
|
||||
|
||||
let fileUpload = fileDrop.querySelector('#file');
|
||||
let fileAlt = fileDrop.querySelector('#alt');
|
||||
let fileDescription = fileDrop.querySelector('#description');
|
||||
let fileTags = fileDrop.querySelector('#tags');
|
||||
|
||||
fileUpload.value = "";
|
||||
fileAlt.value = "";
|
||||
fileDescription.value = "";
|
||||
fileTags.value = "";
|
||||
}
|
||||
|
||||
|
||||
// function createJob(file) {
|
||||
// jobContainer = document.createElement("div");
|
||||
// jobContainer.classList.add("job");
|
||||
|
||||
// jobStatus = document.createElement("span");
|
||||
// jobStatus.classList.add("job__status");
|
||||
// jobStatus.innerHTML = "Uploading...";
|
||||
|
||||
// jobProgress = document.createElement("span");
|
||||
// jobProgress.classList.add("progress");
|
||||
|
||||
// jobImg = document.createElement("img");
|
||||
// jobImg.src = URL.createObjectURL(file);
|
||||
|
||||
// jobImgFilter = document.createElement("span");
|
||||
// jobImgFilter.classList.add("img-filter");
|
||||
|
||||
// jobContainer.appendChild(jobStatus);
|
||||
// jobContainer.appendChild(jobProgress);
|
||||
// jobContainer.appendChild(jobImg);
|
||||
// jobContainer.appendChild(jobImgFilter);
|
||||
|
||||
// return jobContainer;
|
||||
// }
|
||||
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// Function to upload images
|
||||
let uploadTab = document.querySelector(".upload-panel");
|
||||
|
||||
if (!uploadTab) { return; } // If upload tab doesn't exist, don't run this code :3
|
||||
|
||||
let uploadTabDrag = uploadTab.querySelector("#dragIndicator");
|
||||
let uploadForm = uploadTab.querySelector('#uploadForm');
|
||||
// let jobList = document.querySelector(".upload-jobs");
|
||||
|
||||
let fileDrop = uploadForm.querySelector('.fileDrop-block');
|
||||
let fileDropTitle = fileDrop.querySelector('.status');
|
||||
let fileUpload = fileDrop.querySelector('#file');
|
||||
|
||||
let fileAlt = uploadForm.querySelector('#alt');
|
||||
let fileDescription = uploadForm.querySelector('#description');
|
||||
let fileTags = uploadForm.querySelector('#tags');
|
||||
|
||||
|
||||
clearUpload();
|
||||
fileDefault();
|
||||
|
||||
|
||||
// Tab is dragged
|
||||
uploadTabDrag.addEventListener('touchstart', tabDragStart, false);
|
||||
uploadTabDrag.addEventListener('touchend', tabDragStopped, false);
|
||||
|
||||
// Drag over/enter event
|
||||
fileDrop.addEventListener('dragover', fileActivate, false);
|
||||
fileDrop.addEventListener('dragenter', fileActivate, false);
|
||||
// Drag out
|
||||
fileDrop.addEventListener('dragleave', fileDefault, false);
|
||||
// Drop file into box
|
||||
fileDrop.addEventListener('drop', fileDropHandle, false);
|
||||
|
||||
// File upload change
|
||||
fileUpload.addEventListener('change', fileChanged, false);
|
||||
// File upload clicked
|
||||
fileUpload.addEventListener('click', fileDefault, false);
|
||||
|
||||
|
||||
// Submit form
|
||||
uploadForm.addEventListener('submit', (event) => {
|
||||
// AJAX takes control of subby form
|
||||
event.preventDefault()
|
||||
|
||||
if (fileUpload.value === "") {
|
||||
fileDrop.classList.add('error');
|
||||
fileDropTitle.innerHTML = 'No file selected!';
|
||||
// Stop the function
|
||||
return;
|
||||
}
|
||||
|
||||
// Make form
|
||||
let formData = new FormData();
|
||||
|
||||
formData.append("file", fileUpload.files[0]);
|
||||
formData.append("alt", fileAlt.value);
|
||||
formData.append("description", fileDescription.value);
|
||||
formData.append("tags", fileTags.value);
|
||||
|
||||
// jobItem = createJob(fileUpload.files[0]);
|
||||
// jobStatus = jobItem.querySelector(".job__status");
|
||||
|
||||
// Upload the information
|
||||
// $.ajax({
|
||||
// url: '/api/upload',
|
||||
// type: 'post',
|
||||
// data: formData,
|
||||
// contentType: false,
|
||||
// processData: false,
|
||||
// beforeSend: function () {
|
||||
// // Add job to list
|
||||
// jobList.appendChild(jobItem);
|
||||
// },
|
||||
// success: function (response) {
|
||||
// jobItem.classList.add("success");
|
||||
// jobStatus.innerHTML = "Uploaded successfully";
|
||||
// if (!document.querySelector(".upload-panel").classList.contains("open")) {
|
||||
// addNotification("Image uploaded successfully", 1);
|
||||
// }
|
||||
// },
|
||||
// error: function (response) {
|
||||
// jobItem.classList.add("critical");
|
||||
// switch (response.status) {
|
||||
// case 500:
|
||||
// jobStatus.innerHTML = "Server exploded, F's in chat";
|
||||
// break;
|
||||
// case 400:
|
||||
// case 404:
|
||||
// jobStatus.innerHTML = "Error uploading. Blame yourself";
|
||||
// break;
|
||||
// case 403:
|
||||
// jobStatus.innerHTML = "None but devils play past here...";
|
||||
// break;
|
||||
// case 413:
|
||||
// jobStatus.innerHTML = "File too large!!!!!!";
|
||||
// break;
|
||||
// default:
|
||||
// jobStatus.innerHTML = "Error uploading file, blame someone";
|
||||
// break;
|
||||
// }
|
||||
// if (!document.querySelector(".upload-panel").classList.contains("open")) {
|
||||
// addNotification("Error uploading file", 2);
|
||||
// }
|
||||
// },
|
||||
// });
|
||||
|
||||
|
||||
fetch('/api/upload', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
// .then(response => response.json())
|
||||
.then(data => { addNotification("Image uploaded successfully", 1); })
|
||||
.catch(error => {
|
||||
switch (response.status) {
|
||||
case 500:
|
||||
addNotification("Server exploded, F's in chat", 2)
|
||||
break;
|
||||
case 400:
|
||||
case 404:
|
||||
addNotification("Error uploading. Blame yourself", 2)
|
||||
break;
|
||||
case 403:
|
||||
addNotification("None but devils play past here...", 2)
|
||||
break;
|
||||
case 413:
|
||||
addNotification("File too large!!!!!!", 2);
|
||||
break;
|
||||
default:
|
||||
addNotification("Error uploading file, blame someone", 2)
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
clearUpload();
|
||||
|
||||
// Reset drop
|
||||
fileDrop.classList.remove('active');
|
||||
fileDropTitle.innerHTML = 'Choose or Drop file';
|
||||
});
|
||||
});
|
10
onlylegs/static/js/webp.js
Normal file
10
onlylegs/static/js/webp.js
Normal file
|
@ -0,0 +1,10 @@
|
|||
function checkWebpSupport() {
|
||||
let webpSupport = false;
|
||||
try {
|
||||
webpSupport = document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') === 0;
|
||||
} catch (e) {
|
||||
webpSupport = false;
|
||||
}
|
||||
|
||||
return webpSupport;
|
||||
}
|
60
onlylegs/static/logo-black.svg
Normal file
60
onlylegs/static/logo-black.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 7.9 KiB |
62
onlylegs/static/logo-white.svg
Normal file
62
onlylegs/static/logo-white.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 8.1 KiB |
18
onlylegs/static/manifest.json
Normal file
18
onlylegs/static/manifest.json
Normal file
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "OnlyLegs",
|
||||
"short_name": "OnlyLegs",
|
||||
"start_url": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#151515",
|
||||
"theme_color": "#151515",
|
||||
"description": "A gallery built for fast and simple image management!",
|
||||
"icons": [
|
||||
{
|
||||
"src": "icon.png",
|
||||
"sizes": "621x621",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"splash_pages": null
|
||||
}
|
||||
|
11
onlylegs/static/sass/animations.sass
Normal file
11
onlylegs/static/sass/animations.sass
Normal file
|
@ -0,0 +1,11 @@
|
|||
@keyframes imgLoading
|
||||
0%
|
||||
background-position: -468px 0
|
||||
100%
|
||||
background-position: 468px 0
|
||||
|
||||
@keyframes uploadingLoop
|
||||
0%
|
||||
left: -100%
|
||||
100%
|
||||
left: 100%
|
198
onlylegs/static/sass/components/banner.sass
Normal file
198
onlylegs/static/sass/components/banner.sass
Normal file
|
@ -0,0 +1,198 @@
|
|||
.banner,
|
||||
.banner-small
|
||||
width: 100%
|
||||
position: relative
|
||||
color: RGB($fg-white)
|
||||
|
||||
.link
|
||||
padding: 0.1rem 0.3rem
|
||||
|
||||
text-decoration: none
|
||||
font-weight: 500
|
||||
|
||||
background-color: RGB($fg-white)
|
||||
color: RGB($fg-black)
|
||||
border-radius: $rad-inner
|
||||
|
||||
cursor: pointer
|
||||
|
||||
&:hover
|
||||
background-color: RGB($fg-black)
|
||||
color: RGB($fg-white)
|
||||
|
||||
&::after
|
||||
content: ''
|
||||
|
||||
width: $rad
|
||||
height: calc(#{$rad} * 2)
|
||||
|
||||
position: absolute
|
||||
bottom: calc(#{$rad} * -2)
|
||||
left: 0
|
||||
|
||||
background-color: RGB($bg-bright)
|
||||
border-radius: $rad 0 0 0
|
||||
box-shadow: 0 calc(#{$rad} * -1) 0 0 RGB($bg-100)
|
||||
|
||||
.banner
|
||||
height: 30rem
|
||||
background-color: RGB($bg-300)
|
||||
|
||||
img
|
||||
position: absolute
|
||||
inset: 0
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
background-color: inherit
|
||||
|
||||
object-fit: cover
|
||||
object-position: center center
|
||||
|
||||
.banner-filter
|
||||
position: absolute
|
||||
inset: 0
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
background: linear-gradient(to right, RGB($primary), transparent)
|
||||
|
||||
z-index: +1
|
||||
|
||||
.banner-content
|
||||
padding: 0.5rem
|
||||
|
||||
width: 100%
|
||||
height: auto
|
||||
|
||||
position: absolute
|
||||
left: 0
|
||||
bottom: 0
|
||||
|
||||
display: grid
|
||||
grid-template-columns: 1fr auto
|
||||
grid-template-rows: 1fr auto auto
|
||||
grid-template-areas: 'info info' 'header header' 'subtitle options'
|
||||
|
||||
z-index: +2
|
||||
|
||||
.banner-header,
|
||||
.banner-info,
|
||||
.banner-subtitle
|
||||
margin: 0
|
||||
padding: 0
|
||||
width: 100%
|
||||
|
||||
.banner-header
|
||||
grid-area: header
|
||||
|
||||
margin: 0.5rem 0
|
||||
|
||||
text-align: left
|
||||
font-size: 6.9rem
|
||||
font-weight: 700
|
||||
|
||||
color: RGB($primary)
|
||||
|
||||
.banner-info
|
||||
grid-area: info
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
.banner-subtitle
|
||||
grid-area: subtitle
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
|
||||
.pill-row
|
||||
margin-top: auto
|
||||
grid-area: options
|
||||
|
||||
.banner-small
|
||||
height: 3.5rem
|
||||
background-color: RGB($bg-100)
|
||||
|
||||
.banner-content
|
||||
padding: 0 0.5rem
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
position: absolute
|
||||
inset: 0
|
||||
|
||||
display: flex
|
||||
flex-direction: row
|
||||
justify-content: flex-start
|
||||
|
||||
z-index: +2
|
||||
|
||||
.banner-header,
|
||||
.banner-info
|
||||
margin: auto 0
|
||||
padding: 0
|
||||
width: auto
|
||||
height: auto
|
||||
justify-self: flex-start
|
||||
|
||||
.banner-header
|
||||
margin-right: 0.6rem
|
||||
|
||||
white-space: nowrap
|
||||
text-overflow: ellipsis
|
||||
overflow: hidden
|
||||
text-align: left
|
||||
font-weight: 700
|
||||
font-size: 1.5rem
|
||||
|
||||
color: RGB($primary)
|
||||
|
||||
.banner-info
|
||||
margin-right: 0.6rem
|
||||
|
||||
font-size: 0.9rem
|
||||
font-weight: 400
|
||||
|
||||
.pill-row
|
||||
margin-left: auto
|
||||
width: auto
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
.banner,
|
||||
.banner-small
|
||||
&::after
|
||||
display: none
|
||||
|
||||
.banner
|
||||
min-height: 17rem
|
||||
height: auto
|
||||
|
||||
.banner-content
|
||||
padding: 0.5rem
|
||||
height: 100%
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
.banner-header
|
||||
margin: 1rem 0
|
||||
text-align: center
|
||||
font-size: 2.5rem
|
||||
|
||||
.banner-info
|
||||
font-size: 1.1rem
|
||||
text-align: center
|
||||
|
||||
.banner-subtitle
|
||||
display: none
|
||||
|
||||
.pill-row
|
||||
margin-top: 0rem
|
||||
|
||||
.banner-small
|
||||
.banner-content
|
||||
.banner-info
|
||||
display: none
|
178
onlylegs/static/sass/components/buttons/block.sass
Normal file
178
onlylegs/static/sass/components/buttons/block.sass
Normal file
|
@ -0,0 +1,178 @@
|
|||
@mixin btn-block($color)
|
||||
color: RGB($color)
|
||||
box-shadow: 0 1px 0 RGBA($black, 0.2), 0 -1px 0 RGBA($white, 0.2)
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: RGBA($color, 0.1)
|
||||
color: RGB($color)
|
||||
box-shadow: 0 1px 0 RGBA($black, 0.2), 0 -1px 0 RGBA($color, 0.2)
|
||||
|
||||
|
||||
.btn-block
|
||||
padding: 0.4rem 0.7rem
|
||||
|
||||
width: auto
|
||||
min-height: 2.3rem
|
||||
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
position: relative
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
text-align: center
|
||||
|
||||
background-color: RGBA($white, 0.1)
|
||||
color: RGB($white)
|
||||
border: none
|
||||
border-radius: $rad-inner
|
||||
box-shadow: 0 1px 0 RGBA($black, 0.2), 0 -1px 0 RGBA($white, 0.2)
|
||||
outline: none
|
||||
|
||||
cursor: pointer
|
||||
transition: background-color 0.15s ease-in-out, color 0.15s ease-in-out, box-shadow 0.15s ease-in-out
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: RGBA($white, 0.2)
|
||||
box-shadow: 0 1px 0 RGBA($black, 0.3), 0 -1px 0 RGBA($white, 0.3)
|
||||
|
||||
&.primary
|
||||
@include btn-block($primary)
|
||||
|
||||
&.critical
|
||||
@include btn-block($critical)
|
||||
|
||||
&.warning
|
||||
@include btn-block($warning)
|
||||
|
||||
&.success
|
||||
@include btn-block($success)
|
||||
|
||||
&.info
|
||||
@include btn-block($info)
|
||||
|
||||
&.black
|
||||
@include btn-block($black)
|
||||
|
||||
.input-checkbox
|
||||
padding: 0
|
||||
display: flex
|
||||
justify-content: flex-start
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
position: relative
|
||||
|
||||
label
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
text-align: left
|
||||
|
||||
color: RGB($fg-white)
|
||||
|
||||
.input-block
|
||||
padding: 0.4rem 0.7rem
|
||||
|
||||
width: auto
|
||||
min-height: 2.3rem
|
||||
|
||||
display: flex
|
||||
justify-content: flex-start
|
||||
align-items: center
|
||||
|
||||
position: relative
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
text-align: left
|
||||
|
||||
background-color: RGBA($white, 0.1)
|
||||
color: RGB($white)
|
||||
border: none
|
||||
border-bottom: 3px solid RGBA($white, 0.1)
|
||||
border-radius: $rad-inner
|
||||
box-shadow: 0 1px 0 RGBA($black, 0.2), 0 -1px 0 RGBA($white, 0.2)
|
||||
outline: none
|
||||
|
||||
cursor: pointer
|
||||
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out
|
||||
|
||||
&:not(:focus):not([value=""]):not(:placeholder-shown)
|
||||
border-color: RGBA($white, 0.3)
|
||||
|
||||
&:hover
|
||||
border-color: RGBA($white, 0.3)
|
||||
|
||||
&:focus
|
||||
border-color: RGB($primary)
|
||||
|
||||
&.black
|
||||
@include btn-block($black)
|
||||
|
||||
.fileDrop-block
|
||||
padding: 1rem 1.25rem
|
||||
|
||||
width: 100%
|
||||
min-height: 2.3rem
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: center
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
position: relative
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
text-align: center
|
||||
|
||||
background-color: RGBA($white, 0.1)
|
||||
color: RGB($white)
|
||||
border: none
|
||||
border-radius: $rad-inner
|
||||
box-shadow: 0 1px 0 RGBA($black, 0.2), 0 -1px 0 RGBA($white, 0.2)
|
||||
outline: none
|
||||
|
||||
cursor: pointer
|
||||
overflow: hidden
|
||||
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out, box-shadow 0.15s ease-in-out
|
||||
|
||||
input
|
||||
position: absolute
|
||||
inset: 0
|
||||
opacity: 0
|
||||
cursor: pointer
|
||||
|
||||
.status
|
||||
width: 100%
|
||||
white-space: nowrap
|
||||
text-overflow: ellipsis
|
||||
text-align: center
|
||||
overflow: hidden
|
||||
|
||||
&:hover, &:focus-visible
|
||||
background-color: RGBA($white, 0.2)
|
||||
color: RGB($white)
|
||||
box-shadow: 0 1px 0 RGBA($black, 0.3), 0 -1px 0 RGBA($white, 0.3)
|
||||
|
||||
&.active
|
||||
background-color: RGBA($primary, 0.2)
|
||||
color: RGB($primary)
|
||||
box-shadow: 0 1px 0 RGBA($black, 0.3), 0 -1px 0 RGBA($primary, 0.3)
|
||||
|
||||
&.edging
|
||||
background-color: RGBA($white, 0.2)
|
||||
color: RGB($white)
|
||||
box-shadow: 0 1px 0 RGBA($black, 0.3), 0 -1px 0 RGBA($white, 0.3)
|
||||
|
||||
input
|
||||
display: none // So it doesnt get in the way of the drop as that breaks things
|
||||
|
||||
&.error
|
||||
background-color: RGBA($critical, 0.2)
|
||||
color: RGB($critical)
|
||||
box-shadow: 0 1px 0 RGBA($black, 0.3), 0 -1px 0 RGBA($critical, 0.3)
|
41
onlylegs/static/sass/components/buttons/info-button.sass
Normal file
41
onlylegs/static/sass/components/buttons/info-button.sass
Normal file
|
@ -0,0 +1,41 @@
|
|||
.info-button
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: auto
|
||||
height: auto
|
||||
|
||||
position: fixed
|
||||
bottom: 0.75rem
|
||||
right: -3rem
|
||||
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
background-color: RGB($bg-300)
|
||||
color: RGB($fg-white)
|
||||
border-radius: $rad
|
||||
border: none
|
||||
opacity: 0
|
||||
|
||||
z-index: 20
|
||||
cursor: pointer
|
||||
transition: all 0.2s cubic-bezier(.86, 0, .07, 1)
|
||||
|
||||
&:hover
|
||||
color: RGB($info)
|
||||
|
||||
svg
|
||||
margin: 0.5rem
|
||||
|
||||
width: 1.25rem
|
||||
height: 1.25rem
|
||||
|
||||
&.show
|
||||
right: 0.75rem
|
||||
opacity: 1
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
.info-button
|
||||
bottom: 4.25rem
|
94
onlylegs/static/sass/components/buttons/pill.sass
Normal file
94
onlylegs/static/sass/components/buttons/pill.sass
Normal file
|
@ -0,0 +1,94 @@
|
|||
.pill-row
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 100%
|
||||
height: auto
|
||||
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
> div
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
display: flex
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
border-radius: $rad
|
||||
box-shadow: 0 1px 0 RGB($bg-100), 0 -1px 0 RGB($bg-300)
|
||||
|
||||
.pill-text
|
||||
margin: 0
|
||||
padding: 0.5rem 1rem
|
||||
|
||||
width: auto
|
||||
height: 2.5rem
|
||||
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
position: relative
|
||||
|
||||
text-align: center
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
color: RGB($fg-white)
|
||||
border-radius: $rad
|
||||
|
||||
.pill-item
|
||||
margin: 0
|
||||
padding: 0.5rem
|
||||
|
||||
width: 2.5rem
|
||||
height: 2.5rem
|
||||
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
position: relative
|
||||
|
||||
border: none
|
||||
background-color: transparent
|
||||
color: RGB($fg-white)
|
||||
|
||||
svg
|
||||
width: 1.25rem
|
||||
height: 1.25rem
|
||||
|
||||
&:hover
|
||||
cursor: pointer
|
||||
|
||||
color: RGB($primary)
|
||||
|
||||
.pill__critical
|
||||
color: RGB($critical)
|
||||
|
||||
span
|
||||
background: RGB($critical)
|
||||
color: RGB($fg-white)
|
||||
|
||||
svg
|
||||
color: RGB($critical)
|
||||
|
||||
&:hover
|
||||
color: RGB($fg-white)
|
||||
|
||||
.pill__info
|
||||
color: RGB($info)
|
||||
|
||||
span
|
||||
color: RGB($info)
|
||||
|
||||
&:hover
|
||||
color: RGB($fg-white)
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
.tool-tip
|
||||
display: none
|
41
onlylegs/static/sass/components/buttons/top-of-page.sass
Normal file
41
onlylegs/static/sass/components/buttons/top-of-page.sass
Normal file
|
@ -0,0 +1,41 @@
|
|||
.top-of-page
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: auto
|
||||
height: auto
|
||||
|
||||
position: fixed
|
||||
bottom: 0.75rem
|
||||
right: -3rem
|
||||
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
background-color: RGB($bg-300)
|
||||
color: RGB($fg-white)
|
||||
border-radius: $rad
|
||||
border: none
|
||||
opacity: 0
|
||||
|
||||
z-index: 20
|
||||
cursor: pointer
|
||||
transition: all 0.2s cubic-bezier(.86, 0, .07, 1)
|
||||
|
||||
&:hover
|
||||
color: RGB($primary)
|
||||
|
||||
svg
|
||||
margin: 0.5rem
|
||||
|
||||
width: 1.25rem
|
||||
height: 1.25rem
|
||||
|
||||
&.show
|
||||
right: 0.75rem
|
||||
opacity: 1
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
.top-of-page
|
||||
bottom: 4.25rem
|
241
onlylegs/static/sass/components/gallery.sass
Normal file
241
onlylegs/static/sass/components/gallery.sass
Normal file
|
@ -0,0 +1,241 @@
|
|||
.gallery-grid
|
||||
margin: 0
|
||||
padding: 0.35rem
|
||||
|
||||
width: 100%
|
||||
|
||||
display: grid
|
||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr))
|
||||
|
||||
.gallery-item
|
||||
margin: 0.35rem
|
||||
padding: 0
|
||||
|
||||
height: auto
|
||||
|
||||
position: relative
|
||||
|
||||
border-radius: $rad-inner
|
||||
box-shadow: 0 0.15rem 0.4rem 0.1rem RGBA($bg-100, 0.4)
|
||||
|
||||
box-sizing: border-box
|
||||
overflow: hidden
|
||||
transition: box-shadow 0.2s cubic-bezier(.79, .14, .15, .86)
|
||||
|
||||
.image-filter
|
||||
margin: 0
|
||||
padding: 0.5rem
|
||||
|
||||
width: 100%
|
||||
min-height: 30%
|
||||
height: auto
|
||||
|
||||
position: absolute
|
||||
left: 0
|
||||
bottom: 0
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: flex-end
|
||||
|
||||
background-image: linear-gradient(to top, rgba($bg-100, 0.69), transparent)
|
||||
opacity: 0 // hide
|
||||
|
||||
z-index: +4
|
||||
transition: opacity 0.2s cubic-bezier(.79, .14, .15, .86)
|
||||
|
||||
.image-title,
|
||||
.image-subtitle
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
white-space: nowrap
|
||||
text-overflow: ellipsis
|
||||
overflow: hidden
|
||||
|
||||
color: RGB($fg-white)
|
||||
text-shadow: 0px 0px 2px RGB($fg-black)
|
||||
|
||||
.image-title
|
||||
font-size: 0.9rem
|
||||
font-weight: 700
|
||||
|
||||
.image-subtitle
|
||||
font-size: 0.8rem
|
||||
font-weight: 400
|
||||
|
||||
img
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
position: absolute
|
||||
inset: 0
|
||||
|
||||
object-fit: cover
|
||||
object-position: center
|
||||
|
||||
background-color: RGB($bg-bright)
|
||||
filter: blur(0.5rem)
|
||||
opacity: 0
|
||||
|
||||
transition: all 0.2s cubic-bezier(.79, .14, .15, .86)
|
||||
|
||||
&.loaded
|
||||
filter: blur(0)
|
||||
opacity: 1
|
||||
|
||||
&:after
|
||||
content: ""
|
||||
display: block
|
||||
padding-bottom: 100%
|
||||
|
||||
&:hover
|
||||
box-shadow: 0 0.2rem 0.4rem 0.1rem RGBA($bg-100, 0.6)
|
||||
|
||||
.image-filter
|
||||
opacity: 1
|
||||
|
||||
.group-item
|
||||
margin: 0.35rem
|
||||
padding: 0
|
||||
|
||||
height: auto
|
||||
|
||||
position: relative
|
||||
|
||||
border-radius: $rad-inner
|
||||
|
||||
box-sizing: border-box
|
||||
overflow: hidden
|
||||
|
||||
.image-filter
|
||||
margin: 0
|
||||
padding: 0.5rem
|
||||
|
||||
width: 100%
|
||||
min-height: 30%
|
||||
height: auto
|
||||
|
||||
position: absolute
|
||||
left: 0
|
||||
bottom: 0
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: flex-end
|
||||
|
||||
background-image: linear-gradient(to top, rgba($bg-100, 0.8), transparent)
|
||||
|
||||
z-index: +4
|
||||
|
||||
.image-title,
|
||||
.image-subtitle
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
white-space: nowrap
|
||||
text-overflow: ellipsis
|
||||
overflow: hidden
|
||||
|
||||
color: RGB($fg-white)
|
||||
text-shadow: 0px 0px 2px RGB($fg-black)
|
||||
|
||||
.image-title
|
||||
font-size: 0.9rem
|
||||
font-weight: 700
|
||||
|
||||
.image-subtitle
|
||||
font-size: 0.8rem
|
||||
font-weight: 400
|
||||
|
||||
.images
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
position: absolute
|
||||
inset: 0
|
||||
|
||||
display: block
|
||||
|
||||
img
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
object-fit: cover
|
||||
object-position: center
|
||||
|
||||
background-color: RGB($bg-bright)
|
||||
border-radius: $rad-inner
|
||||
box-shadow: 0 0 0.4rem 0.25rem RGBA($bg-100, 0.1)
|
||||
filter: blur(0.5rem)
|
||||
opacity: 0
|
||||
|
||||
transition: all 0.2s cubic-bezier(.79, .14, .15, .86)
|
||||
|
||||
&.loaded
|
||||
filter: blur(0)
|
||||
opacity: 1
|
||||
|
||||
&.size-1
|
||||
.data-1
|
||||
transform: scale(0.8) rotate(3deg)
|
||||
|
||||
&.size-2
|
||||
.data-1
|
||||
transform: scale(0.7) rotate(-3deg) translate(10%, 10%)
|
||||
z-index: +2
|
||||
.data-2
|
||||
transform: scale(0.7) rotate(3deg) translate(-10%, -10%)
|
||||
z-index: +1
|
||||
|
||||
&.size-3
|
||||
.data-1
|
||||
transform: scale(0.6) rotate(3deg) translate(-25%, 25%)
|
||||
z-index: +3
|
||||
.data-2
|
||||
transform: scale(0.6) rotate(-5deg) translate(25%, 10%)
|
||||
z-index: +2
|
||||
.data-3
|
||||
transform: scale(0.6) rotate(-1deg) translate(-15%, -23%)
|
||||
z-index: +1
|
||||
|
||||
&:after
|
||||
content: ""
|
||||
display: block
|
||||
padding-bottom: 100%
|
||||
|
||||
&:hover
|
||||
.images
|
||||
&.size-1
|
||||
.data-1
|
||||
transform: scale(0.9) rotate(0deg)
|
||||
|
||||
&.size-2
|
||||
.data-1
|
||||
transform: scale(0.75) rotate(-1deg) translate(12%, 14%)
|
||||
z-index: +2
|
||||
.data-2
|
||||
transform: scale(0.75) rotate(1deg) translate(-12%, -10%)
|
||||
z-index: +1
|
||||
|
||||
&.size-3
|
||||
.data-1
|
||||
transform: scale(0.65) rotate(1deg) translate(-24%, 24%)
|
||||
z-index: +3
|
||||
.data-2
|
||||
transform: scale(0.65) rotate(-2deg) translate(24%, 10%)
|
||||
z-index: +2
|
||||
.data-3
|
||||
transform: scale(0.65) rotate(0deg) translate(-15%, -25%)
|
||||
z-index: +1
|
||||
|
||||
@media (max-width: 800px)
|
||||
.gallery-grid
|
||||
grid-template-columns: auto auto auto
|
42
onlylegs/static/sass/components/image-view/background.sass
Normal file
42
onlylegs/static/sass/components/image-view/background.sass
Normal file
|
@ -0,0 +1,42 @@
|
|||
.background
|
||||
width: 100%
|
||||
height: 100vh
|
||||
|
||||
position: fixed
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
background-color: RGB($bg-300)
|
||||
background-image: linear-gradient(to right, RGB($bg-400) 15%, RGB($bg-200) 35%, RGB($bg-400) 50%)
|
||||
background-size: 1000px 640px
|
||||
animation: imgLoading 1.8s linear infinite forwards
|
||||
|
||||
user-select: none
|
||||
overflow: hidden
|
||||
z-index: 1
|
||||
|
||||
img
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
background-color: RGB($fg-white)
|
||||
|
||||
filter: blur(1rem) saturate(1.2)
|
||||
transform: scale(1.1)
|
||||
|
||||
object-fit: cover
|
||||
object-position: center center
|
||||
|
||||
span
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
z-index: +1
|
21
onlylegs/static/sass/components/image-view/image.sass
Normal file
21
onlylegs/static/sass/components/image-view/image.sass
Normal file
|
@ -0,0 +1,21 @@
|
|||
.image-container
|
||||
margin: auto
|
||||
padding: 0.5rem
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
display: flex
|
||||
overflow: hidden
|
||||
|
||||
img
|
||||
margin: auto
|
||||
padding: 0
|
||||
|
||||
width: auto
|
||||
height: auto
|
||||
max-width: 100%
|
||||
max-height: 100%
|
||||
|
||||
object-fit: contain
|
||||
object-position: center
|
215
onlylegs/static/sass/components/image-view/info-tab.sass
Normal file
215
onlylegs/static/sass/components/image-view/info-tab.sass
Normal file
|
@ -0,0 +1,215 @@
|
|||
.info-container
|
||||
width: 27rem
|
||||
height: 100vh
|
||||
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
|
||||
overflow-y: auto
|
||||
z-index: +4
|
||||
transition: left 0.3s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
&.collapsed
|
||||
left: -27rem
|
||||
|
||||
.info-tab
|
||||
width: 100%
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
position: relative
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
border-radius: $rad
|
||||
|
||||
transition: max-height 0.3s cubic-bezier(.79, .14, .15, .86)
|
||||
|
||||
&.collapsed
|
||||
height: 2.5rem
|
||||
|
||||
.collapse-indicator
|
||||
transform: rotate(90deg)
|
||||
|
||||
.info-table
|
||||
height: 0
|
||||
padding: 0
|
||||
|
||||
.collapse-indicator
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 1.25rem
|
||||
height: 1.25rem
|
||||
|
||||
position: absolute
|
||||
top: 0.6rem
|
||||
right: 0.6rem
|
||||
|
||||
background-color: transparent
|
||||
color: RGB($primary)
|
||||
border: none
|
||||
|
||||
z-index: +2
|
||||
|
||||
transition: transform 0.15s cubic-bezier(.79, .14, .15, .86)
|
||||
cursor: pointer
|
||||
|
||||
.info-header
|
||||
margin: 0
|
||||
padding: 0.5rem
|
||||
|
||||
width: 100%
|
||||
height: 2.5rem
|
||||
|
||||
display: flex
|
||||
justify-content: start
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
position: sticky
|
||||
top: 0
|
||||
z-index: +1
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
|
||||
svg
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 1.25rem
|
||||
height: 1.25rem
|
||||
|
||||
fill: RGB($primary)
|
||||
|
||||
h2
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
font-size: 1.1rem
|
||||
font-weight: 500
|
||||
|
||||
color: RGB($primary)
|
||||
|
||||
text-overflow: ellipsis
|
||||
overflow: hidden
|
||||
|
||||
.info-table
|
||||
margin: 0
|
||||
padding: 0.5rem
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 1rem
|
||||
|
||||
color: RGB($fg-white)
|
||||
|
||||
overflow-x: hidden
|
||||
|
||||
p
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
|
||||
text-overflow: ellipsis
|
||||
overflow: hidden
|
||||
|
||||
.link
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
color: RGB($primary)
|
||||
|
||||
cursor: pointer
|
||||
text-decoration: none
|
||||
|
||||
&:hover
|
||||
text-decoration: underline
|
||||
|
||||
table
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 100%
|
||||
|
||||
overflow-x: hidden
|
||||
border-collapse: collapse
|
||||
|
||||
tr
|
||||
white-space: nowrap
|
||||
|
||||
td
|
||||
padding-bottom: 0.5rem
|
||||
|
||||
max-width: 0
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
|
||||
vertical-align: top
|
||||
|
||||
td:first-child
|
||||
padding-right: 0.5rem
|
||||
|
||||
width: 50%
|
||||
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
td:last-child
|
||||
width: 50%
|
||||
|
||||
white-space: normal
|
||||
word-break: break-word
|
||||
|
||||
tr:last-of-type td
|
||||
padding-bottom: 0
|
||||
|
||||
.img-colours
|
||||
width: 100%
|
||||
|
||||
display: flex
|
||||
gap: 0.5rem
|
||||
|
||||
span
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 1.5rem
|
||||
height: 1.5rem
|
||||
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
border-radius: $rad-inner
|
||||
// border: 1px solid RGB($white)
|
||||
|
||||
.img-groups
|
||||
width: 100%
|
||||
display: flex
|
||||
flex-wrap: wrap
|
||||
gap: 0.5rem
|
||||
|
||||
@media (max-width: 1100px)
|
||||
.info-container
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
position: relative
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0.5rem
|
||||
|
||||
&.collapsed
|
||||
left: unset
|
81
onlylegs/static/sass/components/image-view/view.sass
Normal file
81
onlylegs/static/sass/components/image-view/view.sass
Normal file
|
@ -0,0 +1,81 @@
|
|||
@import 'background'
|
||||
@import 'info-tab'
|
||||
@import 'image'
|
||||
|
||||
|
||||
.image-grid
|
||||
padding: 0
|
||||
|
||||
width: 100%
|
||||
height: 100vh
|
||||
|
||||
position: relative
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0.5rem
|
||||
z-index: 3
|
||||
|
||||
.image-block
|
||||
margin: 0 0 0 27rem
|
||||
padding: 0
|
||||
|
||||
width: calc(100% - 27rem)
|
||||
height: 100vh
|
||||
|
||||
position: relative
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0
|
||||
|
||||
z-index: 3
|
||||
transition: margin 0.3s cubic-bezier(0.76, 0, 0.17, 1), width 0.3s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
.pill-row
|
||||
margin-bottom: 0.5rem
|
||||
|
||||
&.collapsed
|
||||
.image-block
|
||||
margin: 0
|
||||
width: 100%
|
||||
|
||||
|
||||
@media (max-width: 1100px)
|
||||
.image-grid
|
||||
padding: 0.5rem
|
||||
height: auto
|
||||
|
||||
.image-block
|
||||
margin: 0
|
||||
width: 100%
|
||||
height: auto
|
||||
|
||||
gap: 0.5rem
|
||||
|
||||
transition: margin 0s, width 0s
|
||||
|
||||
.image-container
|
||||
margin: 0 auto
|
||||
padding: 0
|
||||
max-height: 69vh
|
||||
|
||||
img
|
||||
max-height: 69vh
|
||||
|
||||
.pill-row
|
||||
margin-bottom: 0
|
||||
|
||||
#fullscreenImage
|
||||
display: none
|
||||
|
||||
.info-container
|
||||
background: transparent
|
||||
|
||||
.info-header
|
||||
border-radius: $rad $rad 0 0
|
||||
|
||||
.info-tab.collapsed .info-header
|
||||
border-radius: $rad
|
||||
|
||||
|
170
onlylegs/static/sass/components/navigation.sass
Normal file
170
onlylegs/static/sass/components/navigation.sass
Normal file
|
@ -0,0 +1,170 @@
|
|||
.navigation
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 3.5rem
|
||||
height: 100%
|
||||
height: 100dvh
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: space-between
|
||||
|
||||
position: fixed
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
background-color: RGB($bg-100)
|
||||
color: RGB($fg-white)
|
||||
|
||||
z-index: 69
|
||||
|
||||
.logo
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 3.5rem
|
||||
height: 3.5rem
|
||||
min-height: 3.5rem
|
||||
|
||||
display: flex
|
||||
flex-direction: row
|
||||
align-items: center
|
||||
|
||||
.navigation-spacer
|
||||
height: 100%
|
||||
|
||||
.navigation-item
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 3.5rem
|
||||
height: 3.5rem
|
||||
min-height: 3.5rem
|
||||
|
||||
position: relative
|
||||
|
||||
display: flex
|
||||
flex-direction: row
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
background-color: transparent
|
||||
border: none
|
||||
|
||||
text-decoration: none
|
||||
|
||||
> svg
|
||||
margin: 0
|
||||
padding: 0.5rem
|
||||
|
||||
width: 2.5rem
|
||||
height: 2.5rem
|
||||
|
||||
border-radius: $rad-inner
|
||||
color: RGB($fg-white)
|
||||
|
||||
transition: color 0.2s ease-out, transform 0.2s ease-out
|
||||
|
||||
.tool-tip
|
||||
margin: 0
|
||||
padding: 0.4rem 0.7rem
|
||||
|
||||
display: block
|
||||
|
||||
position: absolute
|
||||
top: 50%
|
||||
left: 3rem
|
||||
transform: translateY(-50%)
|
||||
|
||||
font-size: 0.9rem
|
||||
font-weight: 500
|
||||
|
||||
background-color: RGB($bg-100)
|
||||
color: RGB($fg-white)
|
||||
opacity: 0
|
||||
border-radius: $rad-inner
|
||||
|
||||
transition: opacity 0.2s cubic-bezier(.76,0,.17,1), left 0.2s cubic-bezier(.76,0,.17,1)
|
||||
|
||||
pointer-events: none
|
||||
|
||||
> svg
|
||||
margin: 0
|
||||
font-size: 1rem
|
||||
|
||||
width: 0.75rem
|
||||
height: 0.75rem
|
||||
|
||||
display: block
|
||||
|
||||
position: absolute
|
||||
top: 50%
|
||||
left: -0.45rem
|
||||
transform: translateY(-50%)
|
||||
|
||||
color: RGB($bg-100)
|
||||
|
||||
&:hover
|
||||
> svg
|
||||
background: RGBA($fg-white, 0.1)
|
||||
|
||||
span
|
||||
opacity: 1
|
||||
left: 3.9rem
|
||||
|
||||
&.selected
|
||||
> svg
|
||||
color: RGB($primary)
|
||||
|
||||
&::before
|
||||
content: ''
|
||||
display: block
|
||||
|
||||
position: absolute
|
||||
top: 3px
|
||||
left: 0
|
||||
|
||||
width: 3px
|
||||
height: calc(100% - 6px)
|
||||
|
||||
background-color: RGB($primary)
|
||||
border-radius: $rad-inner
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
.navigation
|
||||
width: 100vw
|
||||
height: 3.5rem
|
||||
|
||||
flex-direction: row
|
||||
justify-content: space-around
|
||||
|
||||
position: fixed
|
||||
top: unset
|
||||
bottom: 0
|
||||
left: 0
|
||||
|
||||
> span
|
||||
display: none
|
||||
|
||||
.logo
|
||||
display: none
|
||||
|
||||
.navigation-item
|
||||
margin: 0.25rem
|
||||
padding: 0
|
||||
|
||||
width: 3rem
|
||||
height: 3rem
|
||||
min-height: 3rem
|
||||
|
||||
.tool-tip
|
||||
display: none
|
||||
|
||||
&.selected::before
|
||||
top: unset
|
||||
bottom: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 3px
|
145
onlylegs/static/sass/components/notification.sass
Normal file
145
onlylegs/static/sass/components/notification.sass
Normal file
|
@ -0,0 +1,145 @@
|
|||
@keyframes notificationTimeout
|
||||
0%
|
||||
left: -100%
|
||||
height: 3px
|
||||
90%
|
||||
left: 0%
|
||||
height: 3px
|
||||
95%
|
||||
left: 0%
|
||||
height: 0
|
||||
100%
|
||||
left: 0%
|
||||
height: 0
|
||||
|
||||
@mixin notification($color)
|
||||
color: RGB($color)
|
||||
|
||||
&::after
|
||||
background-color: RGB($color)
|
||||
|
||||
.notifications
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 450px
|
||||
height: auto
|
||||
|
||||
position: fixed
|
||||
top: 0.3rem
|
||||
right: 0.3rem
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
z-index: 621
|
||||
|
||||
.sniffle__notification
|
||||
margin: 0 0 0.3rem 0
|
||||
padding: 0
|
||||
|
||||
width: 450px
|
||||
height: auto
|
||||
max-height: 100px
|
||||
|
||||
display: flex
|
||||
flex-direction: row
|
||||
|
||||
position: relative
|
||||
|
||||
background-color: RGB($bg-300)
|
||||
border-radius: $rad-inner
|
||||
color: RGB($fg-white)
|
||||
opacity: 0
|
||||
transform: scale(0.8)
|
||||
|
||||
box-sizing: border-box
|
||||
overflow: hidden
|
||||
|
||||
transition: all 0.25s ease-in-out, opacity 0.2s ease-in-out, transform 0.2s cubic-bezier(.68,-0.55,.27,1.55)
|
||||
|
||||
&::after
|
||||
content: ""
|
||||
|
||||
width: 100%
|
||||
height: 3px
|
||||
|
||||
position: absolute
|
||||
bottom: 0px
|
||||
left: 0px
|
||||
|
||||
background-color: RGB($fg-white)
|
||||
|
||||
z-index: +2
|
||||
animation: notificationTimeout 5.1s linear
|
||||
|
||||
&.success
|
||||
@include notification($success)
|
||||
&.warning
|
||||
@include notification($warning)
|
||||
&.critical
|
||||
@include notification($critical)
|
||||
&.info
|
||||
@include notification($info)
|
||||
|
||||
&.show
|
||||
opacity: 1
|
||||
transform: scale(1)
|
||||
|
||||
&.hide
|
||||
margin: 0
|
||||
max-height: 0
|
||||
|
||||
opacity: 0
|
||||
transform: translateX(100%)
|
||||
|
||||
transition: all 0.4s ease-in-out, max-height 0.2s ease-in-out
|
||||
|
||||
.sniffle__notification-icon
|
||||
margin: 0
|
||||
padding: 1rem
|
||||
|
||||
width: auto
|
||||
height: auto
|
||||
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
|
||||
svg
|
||||
width: 1.25rem
|
||||
height: 1.25rem
|
||||
|
||||
.sniffle__notification-text
|
||||
margin: 0
|
||||
padding: 1rem
|
||||
|
||||
width: auto
|
||||
height: auto
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-self: center
|
||||
align-self: center
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 600
|
||||
line-height: 1
|
||||
text-align: left
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
.notifications
|
||||
width: calc(100vw - 0.6rem)
|
||||
height: auto
|
||||
|
||||
.sniffle__notification
|
||||
width: 100%
|
||||
|
||||
&.hide
|
||||
opacity: 0
|
||||
transform: translateY(-5rem)
|
||||
|
||||
.sniffle__notification-time
|
||||
width: 100%
|
165
onlylegs/static/sass/components/pop-up.sass
Normal file
165
onlylegs/static/sass/components/pop-up.sass
Normal file
|
@ -0,0 +1,165 @@
|
|||
.pop-up
|
||||
width: 100%
|
||||
height: 100vh
|
||||
|
||||
position: fixed
|
||||
inset: 0
|
||||
|
||||
display: none
|
||||
|
||||
background-color: $bg-transparent
|
||||
opacity: 0
|
||||
|
||||
z-index: 101
|
||||
transition: opacity 0.2s ease
|
||||
|
||||
.pop-up__click-off
|
||||
width: 100%
|
||||
height: 100vh
|
||||
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
z-index: +1
|
||||
|
||||
.pop-up-wrapper
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 621px
|
||||
height: auto
|
||||
|
||||
position: absolute
|
||||
bottom: 50%
|
||||
left: 50%
|
||||
transform: translate(-50%, 50%) scale(0.8)
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
border-radius: $rad
|
||||
overflow: hidden
|
||||
|
||||
z-index: +2
|
||||
transition: transform 0.2s $animation-smooth
|
||||
|
||||
.pop-up-header
|
||||
margin: 0
|
||||
padding: 1rem
|
||||
|
||||
width: 100%
|
||||
height: auto
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0.5rem
|
||||
|
||||
overflow-y: auto
|
||||
overflow-x: hidden
|
||||
text-size-adjust: auto
|
||||
text-overflow: ellipsis
|
||||
|
||||
h2, h3
|
||||
margin: 0
|
||||
|
||||
width: 100%
|
||||
|
||||
position: sticky
|
||||
top: 0
|
||||
|
||||
font-size: 1.5rem
|
||||
font-weight: 700
|
||||
text-align: left
|
||||
|
||||
color: RGB($fg-white)
|
||||
|
||||
p
|
||||
margin: 0
|
||||
|
||||
width: 100%
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
text-align: left
|
||||
|
||||
color: RGB($fg-white)
|
||||
|
||||
svg
|
||||
width: 1rem
|
||||
height: 1rem
|
||||
|
||||
display: inline-block
|
||||
vertical-align: middle
|
||||
|
||||
a, .link
|
||||
color: RGB($primary)
|
||||
|
||||
cursor: pointer
|
||||
text-decoration: none
|
||||
|
||||
&:hover
|
||||
text-decoration: underline
|
||||
|
||||
img
|
||||
margin: auto
|
||||
padding: 0
|
||||
|
||||
width: auto
|
||||
height: auto
|
||||
max-width: 100%
|
||||
max-height: 40vh
|
||||
|
||||
border-radius: $rad-inner
|
||||
|
||||
form
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 100%
|
||||
height: auto
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0.5rem
|
||||
|
||||
justify-content: center
|
||||
|
||||
.pop-up-controlls
|
||||
margin: 0
|
||||
padding: 0.25rem
|
||||
|
||||
width: 100%
|
||||
height: auto
|
||||
|
||||
display: flex
|
||||
flex-direction: row
|
||||
justify-content: flex-end
|
||||
gap: 0.25rem
|
||||
|
||||
background-color: RGB($bg-100)
|
||||
|
||||
&.active
|
||||
opacity: 1
|
||||
|
||||
.pop-up-wrapper
|
||||
transform: translate(-50%, 50%) scale(1)
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
.pop-up
|
||||
.pop-up-wrapper
|
||||
width: calc(100% - 0.75rem)
|
||||
max-height: 95vh
|
||||
|
||||
.pop-up-content
|
||||
max-height: 100%
|
||||
|
||||
img
|
||||
max-height: 50vh
|
||||
|
||||
.pop-up-controlls button
|
||||
width: 100%
|
||||
|
||||
&.active
|
||||
opacity: 1
|
27
onlylegs/static/sass/components/tags.sass
Normal file
27
onlylegs/static/sass/components/tags.sass
Normal file
|
@ -0,0 +1,27 @@
|
|||
.tag-icon
|
||||
margin: 0
|
||||
padding: 0.25rem 0.5rem
|
||||
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
gap: 0.25rem
|
||||
|
||||
font-size: 0.9rem
|
||||
font-weight: 500
|
||||
text-decoration: none
|
||||
|
||||
border-radius: $rad-inner
|
||||
border: none
|
||||
background-color: RGBA($primary, 0.1)
|
||||
color: RGB($primary)
|
||||
|
||||
cursor: pointer
|
||||
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out
|
||||
|
||||
svg
|
||||
width: 1.15rem
|
||||
height: 1.15rem
|
||||
|
||||
&:hover
|
||||
background-color: RGBA($primary, 0.3)
|
224
onlylegs/static/sass/components/upload-panel.sass
Normal file
224
onlylegs/static/sass/components/upload-panel.sass
Normal file
|
@ -0,0 +1,224 @@
|
|||
.upload-panel
|
||||
position: fixed
|
||||
left: 3.5rem
|
||||
bottom: 0
|
||||
|
||||
display: none
|
||||
|
||||
width: calc(100% - 3.5rem)
|
||||
height: 100vh
|
||||
|
||||
background-color: transparent
|
||||
color: RGB($fg-white)
|
||||
|
||||
overflow: hidden
|
||||
z-index: 68
|
||||
transition: background-color 0.25s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
h3
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
font-size: 1.5rem
|
||||
font-weight: 700
|
||||
p
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
|
||||
form
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
width: 100%
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
input, button
|
||||
width: 100%
|
||||
|
||||
.click-off
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
z-index: +1
|
||||
|
||||
.container
|
||||
padding: 1rem
|
||||
|
||||
position: absolute
|
||||
bottom: 0
|
||||
left: -27rem
|
||||
|
||||
width: 27rem
|
||||
height: 100%
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 1rem
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
|
||||
z-index: +2
|
||||
|
||||
transition: left 0.25s cubic-bezier(0.76, 0, 0.17, 1), bottom 0.25s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
#dragIndicator
|
||||
display: none
|
||||
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 5rem
|
||||
|
||||
z-index: +1
|
||||
|
||||
&::after
|
||||
content: ''
|
||||
width: 8rem
|
||||
height: 3px
|
||||
|
||||
position: absolute
|
||||
top: 0.5rem
|
||||
left: 50%
|
||||
transform: translate(-50%, -50%)
|
||||
|
||||
background-color: RGB($bg-400)
|
||||
border-radius: $rad-inner
|
||||
|
||||
.upload-jobs
|
||||
display: flex
|
||||
flex-direction: column
|
||||
gap: 0.5rem
|
||||
|
||||
border-radius: $rad
|
||||
|
||||
overflow-y: auto
|
||||
|
||||
.job
|
||||
width: 100%
|
||||
height: 5rem
|
||||
min-height: 5rem
|
||||
|
||||
position: relative
|
||||
|
||||
display: flex
|
||||
align-items: center
|
||||
gap: 0.5rem
|
||||
|
||||
background-color: RGB($bg-200)
|
||||
border-radius: $rad
|
||||
|
||||
overflow: hidden
|
||||
|
||||
img
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 5rem
|
||||
|
||||
object-fit: cover
|
||||
|
||||
.img-filter
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
background-image: linear-gradient(to right, RGB($bg-100), transparent)
|
||||
|
||||
.job__status
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
position: absolute
|
||||
top: 0.5rem
|
||||
left: 0.5rem
|
||||
|
||||
font-size: 1rem
|
||||
font-weight: 600
|
||||
|
||||
color: RGB($fg-white)
|
||||
|
||||
z-index: +3
|
||||
|
||||
transition: color 0.25s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
.progress
|
||||
width: 100%
|
||||
height: $rad-inner
|
||||
|
||||
position: absolute
|
||||
bottom: 0
|
||||
left: -100%
|
||||
|
||||
background-color: RGB($primary)
|
||||
|
||||
animation: uploadingLoop 1s cubic-bezier(0.76, 0, 0.17, 1) infinite
|
||||
|
||||
z-index: +5
|
||||
transition: left 1s cubic-bezier(0.76, 0, 0.17, 1)
|
||||
|
||||
&.critical
|
||||
.job__status, .progress
|
||||
color: RGB($critical)
|
||||
&.success
|
||||
.job__status
|
||||
color: RGB($success)
|
||||
.progress
|
||||
height: 0
|
||||
animation: none
|
||||
&.warning
|
||||
.job__status, .progress
|
||||
color: RGB($warning)
|
||||
|
||||
&.critical, &.success, &.warning
|
||||
.progress
|
||||
height: 0
|
||||
|
||||
&.open
|
||||
background-color: $bg-transparent
|
||||
|
||||
.container
|
||||
left: 0
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
.upload-panel
|
||||
width: 100%
|
||||
height: calc(100vh - 3.5rem)
|
||||
height: calc(100dvh - 3.5rem)
|
||||
|
||||
left: 0
|
||||
bottom: 3.5rem
|
||||
|
||||
.container
|
||||
width: 100%
|
||||
height: 95%
|
||||
|
||||
left: 0
|
||||
bottom: -100vh
|
||||
|
||||
border-radius: $rad $rad 0 0
|
||||
|
||||
#dragIndicator
|
||||
display: block
|
||||
|
||||
&.open
|
||||
.container
|
||||
left: 0
|
||||
bottom: 0
|
137
onlylegs/static/sass/style.sass
Normal file
137
onlylegs/static/sass/style.sass
Normal file
|
@ -0,0 +1,137 @@
|
|||
// Default theme for OnlyLegs by FluffyBean
|
||||
// Mockup link: https://www.figma.com/file/IMZT5kZr3sAngrSHSGu5di/OnlyLegs?node-id=0%3A1
|
||||
|
||||
@import "variables"
|
||||
@import "animations"
|
||||
|
||||
@import "components/notification"
|
||||
@import "components/pop-up"
|
||||
@import "components/upload-panel"
|
||||
@import "components/tags"
|
||||
|
||||
@import "components/navigation"
|
||||
@import "components/banner"
|
||||
@import "components/gallery"
|
||||
|
||||
@import "components/buttons/top-of-page"
|
||||
@import "components/buttons/info-button"
|
||||
@import "components/buttons/pill"
|
||||
@import "components/buttons/block"
|
||||
|
||||
@import "components/image-view/view"
|
||||
|
||||
// Reset
|
||||
*
|
||||
box-sizing: border-box
|
||||
font-family: $font
|
||||
|
||||
scrollbar-color: RGB($primary) transparent
|
||||
|
||||
::-webkit-scrollbar
|
||||
width: 0.5rem
|
||||
::-webkit-scrollbar-track
|
||||
background: RGB($bg-200)
|
||||
::-webkit-scrollbar-thumb
|
||||
background: RGB($primary)
|
||||
::-webkit-scrollbar-thumb:hover
|
||||
background: RGB($fg-white)
|
||||
|
||||
html, body
|
||||
margin: 0
|
||||
padding: 0
|
||||
|
||||
min-height: 100vh
|
||||
max-width: 100vw
|
||||
|
||||
background-color: RGB($fg-white)
|
||||
|
||||
scroll-behavior: smooth
|
||||
overflow-x: hidden
|
||||
|
||||
.wrapper
|
||||
margin: 0
|
||||
padding: 0 0 0 3.5rem
|
||||
|
||||
min-height: 100vh
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
|
||||
background-color: RGB($bg-bright)
|
||||
color: RGB($bg-100)
|
||||
|
||||
.big-text
|
||||
height: 20rem
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
color: RGB($bg-100)
|
||||
|
||||
h1
|
||||
margin: 0 2rem
|
||||
|
||||
font-size: 4rem
|
||||
font-weight: 900
|
||||
text-align: center
|
||||
|
||||
p
|
||||
margin: 0 2rem
|
||||
|
||||
max-width: 40rem
|
||||
font-size: 1rem
|
||||
font-weight: 400
|
||||
text-align: center
|
||||
|
||||
.error-page
|
||||
width: 100%
|
||||
height: 100vh
|
||||
|
||||
display: flex
|
||||
flex-direction: column
|
||||
justify-content: center
|
||||
align-items: center
|
||||
|
||||
background-color: RGB($bg-bright)
|
||||
|
||||
h1
|
||||
margin: 0 2rem
|
||||
|
||||
font-size: 6.9rem
|
||||
font-weight: 900
|
||||
text-align: center
|
||||
|
||||
color: $primary
|
||||
|
||||
p
|
||||
margin: 0 2rem
|
||||
|
||||
max-width: 40rem
|
||||
font-size: 1.25rem
|
||||
font-weight: 400
|
||||
text-align: center
|
||||
|
||||
color: $fg-black
|
||||
|
||||
|
||||
@media (max-width: $breakpoint)
|
||||
.wrapper
|
||||
padding: 0 0 3.5rem 0
|
||||
|
||||
.big-text
|
||||
height: calc(75vh - 3.5rem)
|
||||
|
||||
h1
|
||||
font-size: 3.5rem
|
||||
|
||||
.error-page
|
||||
height: calc(100vh - 3.5rem)
|
||||
|
||||
h1
|
||||
font-size: 4.5rem
|
||||
|
||||
p
|
||||
max-width: 100%
|
||||
font-size: 1rem
|
76
onlylegs/static/sass/variables.sass
Normal file
76
onlylegs/static/sass/variables.sass
Normal file
|
@ -0,0 +1,76 @@
|
|||
$bg-transparent: rgba(var(--bg-dim), 0.8)
|
||||
$bg-dim: var(--bg-dim)
|
||||
$bg-bright: var(--bg-bright)
|
||||
$bg-100: var(--bg-100)
|
||||
$bg-200: var(--bg-200)
|
||||
$bg-300: var(--bg-300)
|
||||
$bg-400: var(--bg-400)
|
||||
$bg-500: var(--bg-500)
|
||||
$bg-600: var(--bg-600)
|
||||
|
||||
$fg-dim: var(--fg-dim)
|
||||
$fg-white: var(--fg-white)
|
||||
$fg-black: var(--fg-black)
|
||||
|
||||
$black: var(--black)
|
||||
$white: var(--white)
|
||||
$red: var(--red)
|
||||
$orange: var(--orange)
|
||||
$yellow: var(--yellow)
|
||||
$green: var(--green)
|
||||
$blue: var(--blue)
|
||||
$purple: var(--purple)
|
||||
|
||||
$primary: var(--primary)
|
||||
$warning: var(--warning)
|
||||
$critical: var(--critical)
|
||||
$success: var(--success)
|
||||
$info: var(--info)
|
||||
|
||||
$rad: var(--rad)
|
||||
$rad-inner: var(--rad-inner)
|
||||
|
||||
$animation-smooth: var(--animation-smooth)
|
||||
$animation-bounce: var(--animation-bounce)
|
||||
|
||||
$font: 'Rubik', sans-serif
|
||||
$breakpoint: 800px
|
||||
|
||||
|
||||
\:root
|
||||
--bg-dim: 16, 16, 16
|
||||
--bg-bright: 232, 227, 227
|
||||
--bg-100: 21, 21, 21
|
||||
--bg-200: #{red(adjust-color(rgb(21, 21, 21), $lightness: 2%)), green(adjust-color(rgb(21, 21, 21), $lightness: 2%)), blue(adjust-color(rgb(21, 21, 21), $lightness: 2%))}
|
||||
--bg-300: #{red(adjust-color(rgb(21, 21, 21), $lightness: 4%)), green(adjust-color(rgb(21, 21, 21), $lightness: 4%)), blue(adjust-color(rgb(21, 21, 21), $lightness: 4%))}
|
||||
--bg-400: #{red(adjust-color(rgb(21, 21, 21), $lightness: 6%)), green(adjust-color(rgb(21, 21, 21), $lightness: 6%)), blue(adjust-color(rgb(21, 21, 21), $lightness: 6%))}
|
||||
--bg-500: #{red(adjust-color(rgb(21, 21, 21), $lightness: 8%)), green(adjust-color(rgb(21, 21, 21), $lightness: 8%)), blue(adjust-color(rgb(21, 21, 21), $lightness: 8%))}
|
||||
--bg-600: #{red(adjust-color(rgb(21, 21, 21), $lightness: 10%)), green(adjust-color(rgb(21, 21, 21), $lightness: 10%)), blue(adjust-color(rgb(21, 21, 21), $lightness: 10%))}
|
||||
|
||||
--fg-dim: 102, 102, 102
|
||||
--fg-white: 232, 227, 227
|
||||
--fg-black: 16, 16, 16
|
||||
|
||||
--black: 21, 21, 21
|
||||
--white: 232, 227, 227
|
||||
--red: 182, 100, 103
|
||||
--orange: 217, 140, 95
|
||||
--yellow: 217, 188, 140
|
||||
--green: 140, 151, 125
|
||||
--blue: 141, 163, 185
|
||||
--purple: 169, 136, 176
|
||||
|
||||
--primary: var(--green) // 183, 169, 151
|
||||
--warning: var(--orange)
|
||||
--critical: var(--red)
|
||||
--success: var(--green)
|
||||
--info: var(--blue)
|
||||
|
||||
--rad: 6px
|
||||
--rad-inner: calc(var(--rad) / 2)
|
||||
|
||||
--animation-smooth: cubic-bezier(0.76, 0, 0.17, 1)
|
||||
--animation-bounce: cubic-bezier(.68,-0.55,.27,1.55)
|
||||
|
||||
--breakpoint: 800px
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue