Created
June 4, 2022 08:06
-
-
Save gullinbursti/8745fc8d4613c86af897628a1030bb5b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// gallery-injector-v5 | |
// strip out any bs html / etc | |
(()=> { | |
// empty page footer | |
const footer = document.querySelector('.page-wrap > footer'); | |
if (footer) { | |
footer.classList.remove('Footer'); | |
footer.innerHTML = ''; | |
} | |
// take out security floater | |
const oneTrust = document.querySelector('#onetrust-consent-sdk'); | |
if (oneTrust) { | |
oneTrust.remove(); | |
} | |
})(); | |
// remove all added extractor elements | |
(()=> { | |
// remove css | |
const css = Array.from(document.head.children).filter((el)=> (el.getAttribute('data-id') === 'vsco-extractor')).pop(); | |
if (css) { | |
css.remove(); | |
} | |
// remove injected elements | |
Array.from(document.querySelectorAll('.vsco-extractor')).forEach((el)=> { el.remove(); }); | |
})(); | |
// add img btns + info to/of gallery thumbs | |
(()=> { | |
// not mapped yet | |
const MONTH_NAMES = ['JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC']; | |
// minium w/h for a jumbo & standard dimensions | |
const SIZE_JUMBO_THESHOLD = 3024; //4032; | |
const SIZE_STD_THRESHOLD = 2048; //1538; | |
const LOAD_SCROLL_FREQ = 1666; // 3 1/3 sec | |
// sort array [[w, h], ...] ASC using width first, then height | |
const imgDimSort = (dims)=> ([... new Set(dims.sort((dim1, dim2)=> ((dim1.height - dim2.height))).sort((dim1, dim2)=> ((dim1.width - dim2.width))).map((el)=>(el.toString()))) ].map((el)=>(el.split(',')))); | |
// flip-flops hidden class on non-jumbo sizes | |
const toggleJumbos = ()=> { | |
btnJumbosToggle.selected = !btnJumbosToggle.selected; | |
Array.from(document.querySelectorAll('.MediaThumbnail')).filter((thumb)=> ((!thumb.classList.contains('jumbo-img')))).forEach((thumb)=> { | |
thumb.classList.toggle('is-hidden'); | |
//thumb.querySelector('.MediaImage > div').classList.toggle('shrink-down'); | |
}); | |
}; | |
//const grid = document.querySelector('.root > .page-wrap'); | |
const pageWrapper = document.querySelector('.root > .page-wrap'); | |
const grid = pageWrapper.querySelector('main section > .grid'); | |
const cols = Array.from(grid.parentElement.querySelectorAll('.grid > div')).map((el)=> ((Array.from(el.querySelectorAll('figure.MediaThumbnail'))))); | |
const thumbs = cols.flat(); | |
// cycles the scroll down loading | |
let scrollLoad = null; | |
let spinLoad = null; | |
let reviewScroller = null; | |
let dimJumbos = []; | |
// big ol' data obj, not quite in use yet... | |
let gridThumbs = { | |
load : { | |
prev : Array.from(document.querySelectorAll('.grid .MediaThumbnail')), | |
curr : Array.from(document.querySelectorAll('.grid .MediaThumbnail')), | |
isLoading : false, | |
blurred : false | |
}, | |
disp : { | |
img : { | |
small : [], | |
standard : [], | |
jumbo : [], | |
sizes : [] | |
}, | |
vid : { | |
enabled : [], | |
disabled : [] | |
} | |
} | |
}; | |
let runTimes = { | |
commenced : Date.now(), | |
completed : 0, | |
elapsed : 0.0 | |
}; | |
// setup grid data / ui | |
const galleryCheck = ()=> { | |
if (scrollLoad !== null) { | |
clearInterval(scrollLoad); | |
scrollLoad = null; | |
} | |
if (spinLoad !== null) { | |
clearInterval(spinLoad); | |
spinLoad = null; | |
} | |
if (reviewScroller !== null) { | |
clearInterval(reviewScroller); | |
reviewScroller = null; | |
} | |
// make sure we on gallery or search url | |
if (location.pathname.match(/\/search\/|gallery$/)) { | |
// grsb any thumbs on screen b4 loading & find load btn | |
//const updThumbs = Array.from(document.querySelectorAll('.grid .MediaThumbnail')); | |
let loadBtn = document.querySelector('section > div > button'); | |
let spinner = document.querySelector('section div > svg'); | |
//const { load } = ; | |
let { prev, curr, force } = gridThumbs.load; | |
let isLoading = (loadBtn !== null || spinner !== null || (prev.length < curr.length) || force); | |
// append on main obj, replace thumbs | |
gridThumbs = { ...gridThumbs, | |
load : { ...gridThumbs.load, prev, curr, isLoading, | |
//blurred : false, | |
//isLoading : (loadBtn !== null) | |
// prev : curr, | |
// curr : updThumbs, | |
//isLoading : ((loadBtn !== null) || (curr.length < updThumbs.length)) | |
// isLoading : (curr.length < updThumbs.length) | |
} | |
}; | |
if (!pageWrapper.contains(dashPanel)) { | |
pageWrapper.insertAdjacentElement('afterBegin', dashPanel); | |
} | |
// start the timer; | |
runTimes = { ...runTimes, | |
commenced : Date.now() | |
}; | |
// load btn found, so click it | |
if (loadBtn) { | |
// scroll to it & click dat bitch | |
loadBtn.scrollIntoView(); | |
loadBtn.click(); | |
// scroll to bottom | |
} else { | |
//window.scrollTo(0, grid.offsetTop + grid.scrollHeight); | |
window.scrollTo(0, 60 + grid.scrollHeight); | |
} | |
// initial delay based on # of thumbs | |
const delay = Math.max(10, 33 * ((prev.length === curr.length) << 0)); | |
// inital delay | |
//setTimeout(()=> { | |
const { curr : prev2 } = gridThumbs.load; | |
prev = prev2 | |
curr = Array.from(grid.parentElement.querySelectorAll('.grid > div')).map((el)=> ((Array.from(el.querySelectorAll('figure.MediaThumbnail'))))).flat();;//Array.from(document.querySelectorAll('.grid .MediaThumbnail')); | |
loadBtn = document.querySelector('section > div > button'); | |
//spinner = (!spinner) ? document.querySelector('section div > svg') : spinner; | |
spinner = document.querySelector('section div > svg'); | |
//const isLoading = ((loadBtn == null) && (prev.length < curr.length)); | |
isLoading = (force || ((spinner !== null) || (prev.length < curr.length)));////(spinner !== null || (prev.length < curr.length)); | |
// update thumbs ovj | |
gridThumbs = { ...gridThumbs, | |
load : { ...gridThumbs.load, prev, curr, isLoading } | |
}; | |
console.log('-->> gridThumbs.on-timeout', { ...gridThumbs.load }, { prev : prev.length, curr : curr.length, isLoading, loadBtn, spinner });// : document.querySelector('section > div > button'), spinner }); | |
// we're loading | |
if (isLoading) { | |
console.log('//// gridThumbs.isLoading', { ...gridThumbs.load }); | |
// search for spinner | |
spinLoad = setInterval(()=> { | |
spinner = document.querySelector('section > div:last-child > svg'); | |
}, 33) | |
// start scroll/pull dn loader dangerously w/ ass interval | |
scrollLoad = setInterval(()=> { | |
//spinner = (!spinner) ? document.querySelector('section > div:last-child > svg') : spinner; | |
const { curr : prev, blurred, force } = gridThumbs.load; | |
const curr = Array.from(grid.parentElement.querySelectorAll('.grid > div')).map((el)=> ((Array.from(el.querySelectorAll('figure.MediaThumbnail'))))).flat();//Array.from(document.querySelectorAll('.grid .MediaThumbnail')); | |
//isLoading = ((blurred && spinner === null && (prev.length === curr.length)) || (spinner !== null || (prev.length < curr.length))); | |
const isLoading = (force || ((spinner !== null) || (prev.length < curr.length))); | |
// upd data obj w/ thumb elements | |
gridThumbs = { ...gridThumbs, | |
load : { ...gridThumbs.load, prev, curr, isLoading, | |
force : (prev.length === curr.length) | |
} | |
}; | |
// spread dem load params for easy logging & compares | |
const { load } = gridThumbs; | |
// show me wat is the situation | |
console.log(':::: gridThumbs.length-check', { ...load }, { isLoading, prev : prev.length, curr : curr.length, loadBtn, spinner });// : document.querySelector('section > div > button'), spinner }); | |
// no more thumbs | |
if (!load.isLoading) { | |
console.log('!¡!¡!¡ gridThumbs.stoppedLoading', { ...load }, { isLoading }); | |
// if (Array.from(document.querySelectorAll('.grid .MediaThumbnail')).length >= 666) { // empergency cuttoff at 666 incase interval goes AWOL | |
// write final run times | |
const completed = Date.now(); | |
const { commenced } = runTimes; | |
const elapsed = ((((completed - commenced) * 0.01) << 0) * 0.1).toFixed(1); | |
runTimes = { ...runTimes, completed, elapsed }; | |
// wipe intervals | |
if (scrollLoad !== null) { | |
clearInterval(scrollLoad); | |
scrollLoad = null; | |
} | |
if (spinLoad !== null) { | |
clearInterval(spinLoad); | |
spinLoad = null; | |
} | |
// still going | |
} else { | |
// scroll back up 80px from bottom | |
setTimeout(()=> { window.scrollTo({ left : 0, top : window.scrollY - 110, behavior : 'smooth' }); }, 85); | |
} | |
// scroll to bottom | |
window.scrollTo(0, 60 + grid.scrollHeight); | |
// update stats | |
gridUpdate(); | |
}, LOAD_SCROLL_FREQ); | |
// not loading | |
} else { | |
// wipe intervals | |
if (scrollLoad !== null) { | |
clearInterval(scrollLoad); | |
scrollLoad = null; | |
} | |
if (spinLoad !== null) { | |
clearInterval(spinLoad); | |
spinLoad = null; | |
} | |
// update final stats | |
gridUpdate(); | |
} | |
//}, delay); | |
spinner = (!spinner) ? document.querySelector('section div > svg') : spinner; | |
// update stats | |
gridUpdate(); | |
console.log('||| gridThumbs.pre-timeout', { ...gridThumbs.load }, { loadBtn, spinner, isLoading, delay }); | |
// not on grid page | |
} else { | |
// kill interval with fire, orphan the ctrl panel if its still hanging on | |
if (scrollLoad !== null) { | |
clearInterval(scrollLoad); | |
scrollLoad = null; | |
} | |
if (spinLoad !== null) { | |
clearInterval(spinLoad); | |
spinLoad = null; | |
} | |
} | |
}; | |
const gridUpdate = ()=> { | |
const { commenced } = runTimes; | |
// dirty thumb grabbing for now unti data obj | |
const totThumbs = Array.from(document.querySelectorAll('.grid figure.MediaThumbnail')).length; | |
const totVids = Array.from(document.querySelectorAll('.grid video')).length; | |
const accVids = Array.from(document.querySelectorAll('.grid video')).filter((v)=> (v.currentSrc.length > 0)).length; | |
const totImgs = totThumbs - totVids; | |
//imgDate.innerHTML = `${Date().now().toLocaleString().split(',').shift()}`; | |
// get earliest date by poppin off last thumb from each grid column then sort their unix times (w/ fallbks) ASC & shift date from array | |
const startDate = new Date((totThumbs > 0) ? Array.from(document.querySelectorAll('.MasonryGridLayout-column')).map((col)=> (Object.values(col.lastChild).shift().return.pendingProps.media)).map((media)=> ((((media.captureDate || media.createdDate) || media.uploadDate) || Date.now()))).sort().reverse().pop() : Date.now()); | |
//firstDatestamp.innerHTML = `<<-- ${startDate.toLocaleString().split(',').shift()}`; | |
firstDatestamp.innerHTML = `<<-- ${(startDate.getDate() < 10) ? '0' : ''}${startDate.getDate()}-${MONTH_NAMES[startDate.getMonth()]}-${startDate.getFullYear()}`; | |
// 1st gen size holder | |
let imgDims = []; | |
// 1/10th seconds since start | |
const elapsed = ((((Date.now() - commenced) * 0.01) << 0) * 0.1).toFixed(1); | |
runTimes = { ...runTimes, elapsed }; | |
// totals html | |
gridStats.innerHTML = ` | |
<h6 class="vsco-extractor">Total : <span class="num-val">${totThumbs}</span></h6> | |
<div>Images : <span class="num-val">${totImgs}</span></div> | |
<div>Videos : <span class="num-val">${accVids}${(totVids > accVids) ? ` <span class="dim-val">(${totVids - accVids})</span>` : ''}</span></div> | |
<div>Elapsed : <span class="num-val">${elapsed}</span>s</div> | |
`; | |
// iterate over grid items w/o injection yet | |
Array.from(document.querySelectorAll('.grid .MediaThumbnail')).filter((thumb)=> ((!thumb.classList.contains('vsco-extractor')))).forEach((thumb)=> { | |
// add class as injection flag | |
thumb.classList.add('vsco-extractor'); | |
// stretch out dem obj props from the thumb | |
const { media, mediaIndex } = Object.values(thumb).shift().return.pendingProps; | |
const { id, description, descriptionAnchored, imageMeta, captureDate, createdDate, uploadDate, lastUpdated, durationSec, posterUrl, playbackUrl, responsiveUrl, width, height } = media; | |
const size = { width, height }; | |
const isVideo = (((typeof durationSec !== 'undefined') || typeof posterUrl !== 'undefined') || media.isVideo); | |
//const playbackUrl = (isVideo && thumb.querySelector('video source') && (thumb.querySelector('video').currentSrc.length > 0)) ? thumb.querySelector('video').currentSrc : null; | |
const currentSrc = (isVideo && thumb.querySelector('video').currentSrc.length > 0) ? thumb.querySelector('video').currentSrc : null; | |
// build some vars from props | |
const url = (currentSrc) ? currentSrc : (typeof responsiveUrl !== 'undefined') ? `https://${responsiveUrl}` : null; | |
const pubDate = new Date((((captureDate || createdDate) || uploadDate) || lastUpdated)); | |
const imgWrapper = thumb.querySelector((!isVideo && !currentSrc) ? 'a > .MediaImage' : 'div:first-child > div:first-child'); // thumb.querySelector('div video').parentElement; //vid | |
const gutter = thumb.querySelector('div:nth-child(2)'); | |
gutter.classList.add('gutter'); | |
// scaled image | |
const img = imgWrapper.querySelector('img'); | |
img.alt = `${(description.length > 0) ? description : ''}`; | |
//console.log('########:] thumb.imgWrapper', { isVideo, url, currentSrc, responsiveUrl, playbackUrl, imgWrapper }, { ...media }); | |
// add right-click to open full size if url | |
if (url) { | |
imgWrapper.addEventListener('contextmenu', (e)=> { | |
console.log('imgWrapper.contextmenu', e, { ...media }); | |
e.preventDefault(); | |
e.stopPropagation(); | |
window.open(url, '_blank'); | |
}); | |
// no url | |
} else { | |
imgWrapper.classList.add('media-disbled'); | |
} | |
/* | |
// some image stats / actions | |
//const imgWrapper = (!isVideo) ? thumb.querySelector('.MediaImage') : thumb.querySelector('div'); | |
//const mediaLink = (imgWrapper) ? imgWrapper.parentElement : document.createElement('a'); | |
//mediaLink.href = url; | |
//mediaLink.target = '_blank'; | |
if (imageMeta) { | |
const { make, model } = imageMeta; | |
const { shortName : preset } = media.preset; | |
mediaLink.addEventListener('contextmenu', (e)=> { | |
console.log('imgWrapper.contextmenu', e, { ...media }); | |
e.preventDefault(); | |
e.stopPropagation(); | |
window.open(url, '_blank'); | |
//alert(`${(description.length > 0) ? `${description}\n` : ''}${make} - ${model} // (${preset})`); | |
}); | |
} | |
*/ | |
// add this thumbs w/w to size arr | |
imgDims.push(size); | |
// contruct btn to full size img | |
const btnFullImg = document.createElement('button'); | |
btnFullImg.classList.add('vsco-extractor-btn'); | |
btnFullImg.classList.add('full-image-btn'); | |
// img excceds limit, style it special sticks out | |
if ((size.width << 0) >= SIZE_JUMBO_THESHOLD || (size.height << 0) >= SIZE_JUMBO_THESHOLD) { | |
thumb.classList.add('jumbo-img'); | |
btnFullImg.classList.add('jumbo-img-btn'); | |
// 1st gen bg thumb list | |
dimJumbos.push(thumb); | |
} else if ((size.width << 0) >= SIZE_STD_THRESHOLD || (size.height << 0) >= SIZE_STD_THRESHOLD) { | |
thumb.classList.add('std-img'); | |
} else { | |
thumb.classList.add('small-img'); | |
} | |
//console.log('[>> size ]', JSON.stringify(size, null, 2)); | |
//(#${mediaIndex + 1}) ${(new Date(pubDate)).toLocaleString().split(',').shift()}`; | |
// img btn props | |
btnFullImg.innerHTML = `${size.width} x ${size.height}`; | |
btnFullImg.disabled = (isVideo && thumb.querySelector('video').currentSrc.length === 0); | |
btnFullImg.onclick = (e)=> { e.target.blur(); window.open(url, '_blank'); }; | |
thumb.insertAdjacentElement('afterBegin', btnFullImg); | |
// img # and its date | |
const thumbInd = document.createElement('div'); | |
thumbInd.classList.add('vsco-extractor'); | |
thumbInd.classList.add('thumb-ind'); | |
thumbInd.innerHTML = `#${mediaIndex + 1}`; | |
gutter.insertAdjacentElement('afterBegin', thumbInd); | |
// private video | |
if (isVideo && !url) { | |
const vidPrivate = document.createElement('div'); | |
vidPrivate.classList.add('vsco-extractor'); | |
vidPrivate.classList.add('vid-private-ico'); | |
vidPrivate.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="#ffffff" d="M80 192V144C80 64.47 144.5 0 224 0C303.5 0 368 64.47 368 144V192H384C419.3 192 448 220.7 448 256V448C448 483.3 419.3 512 384 512H64C28.65 512 0 483.3 0 448V256C0 220.7 28.65 192 64 192H80zM144 192H304V144C304 99.82 268.2 64 224 64C179.8 64 144 99.82 144 144V192z"/></svg>`; | |
gutter.insertAdjacentElement('beforeEnd', vidPrivate); | |
} | |
// img size | |
const srcSize = document.createElement('div'); | |
srcSize.classList.add('vsco-extractor'); | |
srcSize.classList.add('src-size'); | |
srcSize.innerHTML = `${size.width} ᰽ ${size.height}`; | |
gutter.insertAdjacentElement('beforeEnd', srcSize); | |
// created / captured / uploaded timestamp | |
const imgTime = document.createElement('div'); | |
imgTime.classList.add('vsco-extractor'); | |
imgTime.classList.add('img-time'); | |
imgTime.innerHTML = `${(pubDate.getDate() < 10) ? '0' : ''}${pubDate.getDate()}-${MONTH_NAMES[pubDate.getMonth()]}-${pubDate.getFullYear()}`; | |
gutter.insertAdjacentElement('beforeEnd', imgTime); | |
}); | |
// pull stuff from data obj, but not yet for future | |
const { prev, curr, isLoading } = gridThumbs.load; | |
const { img } = gridThumbs.disp; | |
// write back to data obj something | |
gridThumbs = { ...gridThumbs, | |
disp : { ...gridThumbs.disp, | |
img : { ...img, jumbo : dimJumbos } | |
} | |
}; | |
// jumbo image toggler | |
btnJumbosToggle.innerHTML = `Toggle <span class="num-val">${dimJumbos.length}</span> Jumbo${(dimJumbos.length === 1) ? '' : 's'} <span class="btn-shortkey">(J)</span>`; | |
btnJumbosToggle.disabled = (dimJumbos.length === 0);//not ready fo dat state yet && !isLoading); | |
btnJumbosToggle.onclick = (!btnJumbosToggle.disabled) ? (e)=> { | |
e.preventDefault(); | |
e.target.blur(); | |
window.scrollTo(0, 425); | |
toggleJumbos(); | |
} : null; | |
// show me the size sorting, think it broke nagh | |
console.log('img dims ASC w,hd', imgDimSort(imgDims)); | |
}; | |
// define some css yo for the whole thing, maybe break off into a (()={})(); thing | |
const css = document.createElement('style'); | |
css.setAttribute('type', 'text/css'); | |
css.setAttribute('media', 'screen'); | |
css.setAttribute('data-id', 'vsco-extractor'); | |
css.innerHTML = ` | |
*, *::before, *::after { | |
box-sizing: border-box; | |
/*box-sizing: content-box;*/ | |
/*box-sizing: padding-box;*/ | |
} | |
*:focus { | |
outline: none; | |
} | |
button:hover { | |
cursor: pointer; | |
} | |
*:[disabled]. *:[disabled]:hover, *:disabled, *:disabled:hover { | |
cursor: not-allowed; | |
pointer-events: none; | |
} | |
.is-hidden { | |
display: none; | |
} | |
.media-disabled { | |
opacity: 0.5; | |
filter: brightness(25%); | |
} | |
.media-disabled, .media-disabled:hover { | |
cursor: not-allowed; | |
} | |
.shrink-down { | |
height: 0; | |
} | |
.num-val { | |
color: #ffff00; | |
font-weight: bold; | |
} | |
*:disabled .num-val { | |
opacity: 0.5; | |
filter: saturate(33%); | |
} | |
.num-val > .dim-val { | |
opacity: 0.5; | |
} | |
.btn-shortkey { | |
font-size: 0.7em; | |
opacity: 0.875; | |
line-height: normal; | |
} | |
.vsco-extractor { | |
font-family: Consolas, Monaco, "Courier New", Courier, monospace; | |
font-size: 12px; | |
} | |
.vsco-extractor h6 { | |
margin-bottom: 3px; | |
border-bottom: 1px solid rgba(192, 192, 192, 0.333);; | |
line-height: normal; | |
font-weight: bold; | |
font-size: 1.1em; | |
} | |
.vsco-extractor-btn { | |
margin: 3px 0; | |
padding: 4px; | |
background-color: #2f2f2f; | |
/*color: #8a8a8a;*/ | |
color: rgba(174, 153, 90, 0.75); | |
border: 1px solid #3a3a3a; | |
font-size: 0.7em; | |
line-height: normal; | |
transition: background-color 0.25s ease-in 0s, color 0.25s ease-in 0.125s, border-color 0.25s ease-in 0s; | |
} | |
.vsco-extractor-btn:hover { | |
background-color: #424242; | |
color: rgba(174, 153, 90, 1.0); | |
border: 1px solid #626262; | |
cursor: pointer; | |
} | |
.vsco-extractor-btn:active, .vsco-extractor-btn:hover:active { | |
background-color: #6f6f6f; | |
color: #2f2f20; | |
border: 1px solid #535353; | |
cursor: grabbing; | |
} | |
.vsco-extractor-btn[disabled], .vsco-extractor-btn:disabled, .vsco-extractor-btn[disabled]:hover, .vsco-extractor-btn:disabled:hover { | |
background-color: rgba(192, 192, 192, 0.25); | |
color: rgba(0, 0, 0, 0.875); | |
border: 1px solid rgba(58, 58, 58, 0.0); | |
cursor: not-allowed; | |
} | |
.dash-panel { | |
position: fixed; | |
top: 0; | |
right: 0; | |
width: auto; | |
min-width: 105px; | |
margin-top:70px; | |
padding: 7px; | |
border: 1px solid rgba(80, 80, 80, 0.5); | |
border-right: none; | |
background-color: rgba(13, 13, 13, 0.75); | |
text-align: right; | |
font-size: 0.9em; | |
z-index: 1001; | |
} | |
.dash-panel .grid-stats { | |
color: rgba(0, 255, 255, 0.875); | |
font-size: 0.8em; | |
line-height: 1.333em; | |
text-shadow: 0 0 5px rgba(0, 0, 0, 1.0); | |
} | |
.dash-panel .first-datestamp { | |
margin: 4px 3px; | |
font-size: 0.6em; | |
color: #b6b6c0; | |
} | |
.dash-panel .nav-buttons { | |
display: flex; | |
flex-flow: column wrap; | |
justify-content: center; | |
margin-top: 4px; | |
border-top: 1px solid rgba(192, 192, 192, 0.333); | |
} | |
.dash-panel .nav-buttons > button { | |
margin-top: 4px; | |
} | |
.vsco-extractor .full-image-btn { | |
position: absolute; | |
left: 0; | |
width: 100%; | |
padding: 3px 0 4px 0; | |
background-color: rgba(192, 220, 220, 1.0); | |
opacity: 0.5; | |
color: rgba(255, 255, 255, 0.875); | |
font-size: 1em; | |
font-weight: bold; | |
border: 1px solid rgba(80, 80, 80, 0.25); | |
text-shadow: 0 0 3px rgba(0, 0, 0, 1.0); | |
filter: brightness(100%); | |
transition: filter 0.125s, ease-in 0s, opacity 0.125s, ease-in 0s; | |
z-index: 101; | |
} | |
.vsco-extractor .full-image-btn:hover { | |
opacity: 0.667; | |
filter: brightness(85%); | |
transition: opacity 0.333s ease-out 0s, filter 0.333s, ease-out 0.125s; | |
} | |
.vsco-extractor .jumbo-img-btn { | |
background-color: rgba(255, 0, 255, 0.875); | |
border: 1px solid rgba(255, 0, 255, 0.5); | |
border-bottom: 1px dotted rgba(0, 0, 0, 1.0); | |
color: #ffff00; | |
opacity: 0.667;; | |
transition: border-color 0.125s ease-in 0s, opacity 0.125s ease-in 0s; | |
} | |
.vsco-extractor .jumbo-img-btn:hover { | |
opacity: 0.75; | |
/*filter: brightness(115%);*/ | |
border: 2px solid rgba(255, 0, 255, 1.0); | |
transition: border-color 0.625s ease-out 0.125, opacity 0.125s ease-out 0.125s; | |
} | |
/* *** overrides *** */ | |
body, footer { | |
background-color: rgba(24, 26, 28, 1.00); | |
} | |
#root .page-wrap { | |
position: relative; | |
} | |
footer { | |
background-color: rgba(24, 26, 28, 0.00); | |
} | |
header { | |
filter: invert(1); | |
opacity: 0.875; | |
} | |
.MediaThumbnail { | |
position: relative; | |
transition: height 0.5s linear 0s; | |
} | |
.MediaThumbnail .MediaImage { | |
border: 1px dashed rgba(0, 0, 0, 0.50); | |
} | |
.MediaThumbnail.std-img .MediaImage { | |
border: 1px dashed rgba(0, 160, 128, 0.5); | |
transition: border-style 0.5s ease 0.125s, border-color 0.125s ease 0s; | |
} | |
.MediaThumbnail.std-img .MediaImage:hover { | |
border: 1px dotted rgba(0, 160, 128, 0.75); | |
} | |
.MediaThumbnail.jumbo-img .MediaImage { | |
border: 1px dashed rgba(255, 0, 255, 0.75); | |
transition: border-style 0.5s ease 0.125s, border-color 0.125s ease 0s; | |
} | |
.MediaThumbnail.jumbo-img .MediaImage:hover { | |
border: 1px dotted rgba(255, 0, 255, 1.0); | |
} | |
.MediaThumbnail .MediaImage > div { | |
height: auto; | |
transition: background-color 0.25s ease 0s; | |
} | |
.MediaThumbnail .MediaImage img { | |
opacity: 1; | |
filter: brightness(100%); | |
transition: opacity 0.333s easeOut 0.125s, filter 0.25s easeOut 0.125s; | |
} | |
.MediaThumbnail .MediaImage img:hover { | |
opacity: 0.875; | |
filter: brightness(120%); | |
transition: opacity 0.125s easeIn 0s, filter 0.1s easeIn 0s; | |
} | |
.MediaThumbnail.jumbo-img .MediaImage img:hover { | |
filter: hue-rotate(var(--value, 320deg)); | |
} | |
.MediaThumbnail .MediaImage > div.shrink-down { | |
height: 0; | |
transition: height 0.1s linear 0s; | |
} | |
.MediaThumbnail .MediaImage { | |
border-bottom: none; | |
cursor: default; | |
} | |
.MediaThumbnail .MediaImage:hover { | |
border-bottom: none; | |
cursor: context-menu; | |
} | |
figure .gutter { | |
display: flex; | |
flex-flow: row nowrap; | |
justify-content: center; | |
align-items: center; | |
align-content: flex-start; | |
margin-bottom: 20px; | |
min-height: 20px; | |
background-color: rgba(0, 0, 0, 0.5); | |
} | |
figure .gutter > * { | |
flex: 1 0 auto; | |
margin: auto; | |
padding: 4px; | |
width: fit-content; | |
font-size: 0.75em; | |
line-height: normal; | |
color: #dedede; | |
} | |
.gutter *:first-child { | |
opacity: 0.5; | |
} | |
.gutter .vid-private-ico { | |
padding-left: 8px; | |
opacity: 0.875; | |
} | |
.gutter .vid-private-ico > svg { | |
width: 9px; | |
height: 9px; | |
} | |
.gutter .src-size { | |
flex: 3 0 auto; | |
padding: 0 40px; | |
font-size: 1.2em; | |
font-weight: bold; | |
text-shadow: 0 0 2px rgba(0, 0, 0, 1.0); | |
} | |
.gutter > *:last-child { | |
font-weight: bold; | |
color: #ffff00; | |
} | |
.std-img .gutter { | |
background-color: rgba(0, 160, 128, 0.33); | |
} | |
.std-img .gutter .src-resize { | |
background-color: rgba(0, 160, 128, 0.5); | |
border-left: rgba(0, 160, 128, 0.33); | |
border-right: rgba(0, 160, 128, 0.33); | |
color: #00e09d; | |
} | |
.jumbo-img .gutter { | |
background-color: rgba(255, 0, 255, 0.33); | |
} | |
.jumbo-img .gutter .src-resize { | |
background-color: rgba(255, 0, 255, 0.5); | |
border-left: rgba(255, 0, 255, 0.33); | |
border-right: rgba(255, 0, 255, 0.33); | |
color: #ff00ff; | |
filter: saturate(33%); | |
} | |
`; | |
document.head.appendChild(css); | |
// base data / elements | |
const nowDate = new Date(); | |
const profileName = location.pathname.split('/').slice(1).shift(); | |
const txtGallery = document.querySelector('main nav > a:first-child'); | |
const txtCollection = document.querySelector('main nav > a:last-Child'); | |
// construct control panel skafolding | |
const dashPanel = document.createElement('div'); | |
dashPanel.classList.add('vsco-extractor'); | |
dashPanel.classList.add('dash-panel'); | |
// stats element | |
const gridStats = document.createElement('div'); | |
gridStats.classList.add('grid-stats'); | |
gridStats.innerHTML = ` | |
<h6 class="totals">Total : <span class="num-val">0</span></h6> | |
<div>Images : <span class="num-val">0</span></div> | |
<div>Videos : <span class="num-val">0</span></div> | |
<div>Elapsed : <span class="num-val">0.0</span>s</div> | |
`; | |
// earliest date | |
const firstDatestamp = document.createElement('div'); | |
firstDatestamp.classList.add('first-datestamp'); | |
firstDatestamp.innerHTML = `<<-- ${(nowDate.getDate() < 10) ? '0' : ''}${nowDate.getDate()}-${MONTH_NAMES[nowDate.getMonth()]}-${nowDate.getFullYear()}`; | |
// action btns | |
const navButtons = document.createElement('div'); | |
navButtons.classList.add('nav-buttons'); | |
// on/off jumbo imgs | |
const btnJumbosToggle = document.createElement('button'); | |
btnJumbosToggle.classList.add('vsco-extractor-btn'); | |
btnJumbosToggle.classList.add('jumbos-toggle-btn'); | |
btnJumbosToggle.disabled = true; | |
btnJumbosToggle.innerHTML = 'Toggle <span class="num-val">0</span> Jumbos <span class="btn-shortkey">(J)</span>'; | |
// apply on thumbs / load | |
const btnGridLoad = document.createElement('button'); | |
btnGridLoad.classList.add('vsco-extractor-btn'); | |
btnGridLoad.classList.add('grid-load-btn'); | |
btnGridLoad.innerHTML = 'Load Gallery <span class="btn-shortkey">(L)</span>'; | |
// hard url to collection | |
const btnCollection = document.createElement('button'); | |
btnCollection.classList.add('vsco-extractor-btn'); | |
btnCollection.classList.add('collection-btn'); | |
btnCollection.innerHTML = 'Collection <span class="num-val">…</span> <span class="btn-shortkey">(C)</span>'; | |
btnCollection.disabled = true; | |
// adopt the ctrl panel | |
navButtons.appendChild(btnGridLoad); | |
navButtons.appendChild(btnCollection); | |
dashPanel.appendChild(gridStats); | |
dashPanel.appendChild(firstDatestamp); | |
dashPanel.appendChild(btnJumbosToggle); | |
dashPanel.appendChild(navButtons); | |
pageWrapper.insertAdjacentElement('afterBegin', dashPanel); | |
// grid start | |
btnGridLoad.onclick = (e)=> { | |
e.target.blur(); | |
galleryCheck(); | |
}; | |
// collection page | |
btnCollection.disabled = (txtGallery.innerHTML == txtCollection.innerHTML); | |
btnCollection.onclick = (e)=> { | |
e.target.blur(); | |
location.href = `https://${location.host}/${profileName}/collection`; | |
}; | |
// init with stats | |
gridUpdate(); | |
fetch(`https://vsco.co/api/2.0/sites?subdomain=${location.pathname.split('/').slice(1).shift()}`, { | |
method : 'GET', | |
withCredentials : true, | |
credentials : 'include', | |
headers : { | |
'Content-Type' : 'application/json', | |
'Authorization' : 'Bearer 7356455548d0a1d886db010883388d08be84d0c9' | |
} | |
}).then((response)=> (response.text())).then((response)=> { | |
// console.log('fetch', { sites : JSON.parse(response).sites[0] } ); | |
const { sites } = JSON.parse(response); | |
// sites.pop(); | |
//console.log('fetch', { sites : sites[0] } ); | |
const { user_id : userID, has_collection : isCollection, site_collection_id : collectionID } = sites[0]; | |
console.log('collection info', { isCollection, collectionID } ); | |
if (isCollection) { | |
fetch(`https://vsco.co/api/2.0/collections/${collectionID}/reposts?page=0&size=1`, { | |
method : 'GET', | |
withCredentials : true, | |
credentials : 'include', | |
headers : { | |
'Content-Type' : 'application/json', | |
'Authorization' : 'Bearer 7356455548d0a1d886db010883388d08be84d0c9' | |
} | |
}).then((response)=> (response.text())).then((response)=> { | |
// console.log('fetch', { sites : JSON.parse(response).sites[0] } ); | |
const { count } = JSON.parse(response); | |
console.log('collection count', { count }); | |
btnCollection.innerHTML = `Collection <span class="num-val">${count}</span> <span class="btn-shortkey">(C)</span>`; | |
btnCollection.disabled = false; | |
}); | |
} else { | |
btnCollection.innerHTML = `Collection <span class="num-val">0</span> <span class="btn-shortkey">(C)</span>`; | |
} | |
}); | |
/* | |
document.addEventListener('DOMContentLoaded', (e)=> { | |
console.log('=:=:=:=:=:=:=:=:= document.DOMContentLoaded -->', e, { ...gridThumbs.load }); | |
}); | |
window.document.addEventListener('load', (e)=> { | |
gridThumbs = { ...gridThumbs, | |
load : { ...gridThumbs.load, | |
blurred : false | |
} | |
} | |
console.log('=:=:=:=:=:=:=:=:= window.LOAD -->', e, { ...gridThumbs.load }); | |
}); | |
*/ | |
// browser active | |
window.addEventListener('focus', (e)=> { | |
const { prev, curr, isLoading } = gridThumbs.load; | |
gridThumbs = { ...gridThumbs, | |
load : { ...gridThumbs.load, | |
blurred : false, | |
force : true | |
} | |
}; | |
// jump to bottom if loading | |
if (isLoading) { | |
window.scrollTo(0, 60 + grid.offsetHeight); | |
//setTimeout(()=> { galleryCheck(); }, 125); | |
} | |
console.log('=+=+=+=+=+=+=+= window.focus', e, { ...gridThumbs.load }); | |
}); | |
// browser non-active | |
window.addEventListener('blur', (e)=> { | |
const { prev, curr, isLoading } = gridThumbs.load; | |
e.preventDefault(); | |
e.stopPropagation(); | |
gridThumbs = { ...gridThumbs, | |
load : { ...gridThumbs.load, | |
blurred : true, | |
force : true | |
} | |
}; | |
console.log('=-=-=-=-=-=-=-= window.blur', e, { ...gridThumbs.load }); | |
}); | |
// handle single key | |
window.addEventListener('keypress', (e)=> { | |
console.log('window.keypress', e); | |
const { isLoading } = gridThumbs.load; | |
//e.preventDefault(); | |
//e.stopPropagation(); | |
const { key, altKey } = e; | |
if (key === 'C') { | |
location.href = `https://${location.host}/${profileName}/collection`; | |
} else if (key === 'J') { | |
if (!btnJumbosToggle.disabled) { | |
window.scrollTo(0, 425); | |
toggleJumbos(); | |
} | |
} else if (key === 'L') { | |
galleryCheck(); | |
} else if (key.toUpperCase() === 'Z') { | |
// not currently loading | |
if (!isLoading) { | |
// not in action | |
if (!reviewScroller) { | |
reviewScroller = setInterval(()=> { | |
console.log('reviewScroller', { reviewScroller, scrollY : window.scrollY, adjY : (window.scrollY - 244) , scrollHeight : grid.scrollHeight, isBottom : ((window.scrollY - (244 * 0)) >= grid.scrollHeight) }) | |
// auto stop at top / bottom | |
//if ((window.scrollY <= 0) || (grid.clientHeight - window.scrollY <= 0 )) { | |
//if ((window.scrollY <= 0) || (window.scrollY >= grid.scrollHeight)) { | |
if ((window.scrollY > 0) && (window.scrollY < grid.scrollHeight)) { | |
// scroll up/dn ½ screen | |
window.scrollTo({ | |
top : window.scrollY + ((window.innerHeight * (1/3)) * (1 * (key === 'Z') ? 1 : -1)), | |
left : 0, | |
behavior : 'smooth' | |
}); | |
} else { | |
if (reviewScroller) { | |
clearInterval(reviewScroller); | |
reviewScroller = null; | |
} | |
} | |
}, 999); | |
// wipe it out | |
} else { | |
if (reviewScroller) { | |
clearInterval(reviewScroller); | |
reviewScroller = null; | |
} | |
} | |
} | |
} | |
}); | |
})(); | |
// scroll to top if starting / bottom if prev load | |
window.scrollTo({ top : (Array.from(document.querySelectorAll('.grid .MediaThumbnail')).length <= 14) ? 200 : 60 + document.querySelector('main section > .grid').scrollHeight, left : 0, behavior : 'smooth' }); | |
// --=--=--=--=--=--=--=--=--=--=--=--=--=--=-- // | |
// gallery-injector-v5 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment