diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 120dfaf..32e5e6b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,6 +5,6 @@ Got AI? Use them to make new items or whole new sections, then open a PR to add - Each item is one script, `gen/
//.js`, served as `//.webp` and `.gif` - `npm run gen` renders new scripts into `public/`, `npm run gen -- cat/blink` re-renders one you changed - `npm run dev` to preview, the site builds with `npm run build` into `dist` -- New section? Add its folder name to `sections` in `vite.config.js` +- New section? Add its folder name to `pending` in `vite.config.js`, it shows on `/test` until it moves up into `sections` - Improve items in place rather than renaming them, people hotlink the URLs - Everything you add is released under [CC0](LICENSE) diff --git a/scripts/gen.js b/scripts/gen.js index a5d52c1..2d2ae5d 100644 --- a/scripts/gen.js +++ b/scripts/gen.js @@ -1,5 +1,5 @@ // renders gen/
//.js into public//.{webp,gif} -// the section folder (bw, color, anime, manga, mini, minicolor) only picks where it shows in the gallery, it isn't part of the url +// the section folder (bw, color, ui, ...) only picks where it shows in the gallery, it isn't part of the url // npm run gen renders only what's missing (published files never change by accident) // npm run gen -- cat/blink renders only the named ones, even if they already exist // a file can export rim= to get a sticker border, white unless it also exports rimColor, so a shape that matches the page still shows diff --git a/test.html b/test.html new file mode 100644 index 0000000..da144b1 --- /dev/null +++ b/test.html @@ -0,0 +1 @@ + diff --git a/vite.config.js b/vite.config.js index 82ac522..280fcae 100644 --- a/vite.config.js +++ b/vite.config.js @@ -6,21 +6,24 @@ // tile images get ?v= so browsers drop old copies when a file changes, links stay clean for hotlinking // gets CC0 license data for every tile image, so image search can list them under creative commons // and the build writes sitemap.xml with the page and its tile images (google reads up to 1000 images per page) +// /test is index.html again but with only the pending sections, unlisted, for approving new ones before they go live import{readdirSync as rd,readFileSync as rf}from'fs' import{createHash}from'crypto' const site='https://vibegif.direct-img.link',cc0='https://creativecommons.org/publicdomain/zero/1.0/' const sections=['bw','color','anime','manga','mini','minicolor'] +const pending=['ui','uicolor','uianime'] // approved ones move up into sections const hidden=['cat/tail.gif'] // same drawing as cat/wag.gif, kept so old links still work const walk=d=>rd(d,{withFileTypes:true}).flatMap(e=>e.isDirectory()?walk(`${d}/${e.name}`):`${d}/${e.name}`) const dims=(b,x)=>x=='gif'?[b.readUInt16LE(6),b.readUInt16LE(8)]:[b.readUIntLE(24,3)+1,b.readUIntLE(27,3)+1] -const tiles=()=>{ - const sec={},g=Object.fromEntries(sections.map(s=>[s,{}])) +const tiles=(list=sections)=>{ + const sec={},g=Object.fromEntries(list.map(s=>[s,{}])) for(const f of walk('gen').filter(f=>f.endsWith('.js'))){const[,s,...r]=f.split('/');sec[r.join('/').slice(0,-3)]=s} for(const f of walk('public').filter(f=>/^public\/[^/]+\/.+\.(webp|gif)$/.test(f)).sort()){ const p=f.slice(7),x=p.split('.').pop(),id=p.slice(0,-x.length-1) - if(!hidden.includes(p))(g[sec[id]??sections[0]][id]??={})[x]=f + const s=g[sec[id]??sections[0]] + if(s&&!hidden.includes(p))(s[id]??={})[x]=f } - return sections.map(s=>Object.entries(g[s]).map(([id,fm])=>{ + return list.map(s=>Object.entries(g[s]).map(([id,fm])=>{ const x=fm.webp?'webp':'gif',b=rf(fm[x]),[w,h]=dims(b,x) return{id,fm,x,w,h,src:`/${id}.${x}?v=${createHash('md5').update(b).digest('hex').slice(0,8)}`} })) @@ -38,9 +41,12 @@ ${all.map(t=>`${site+t.src}`). ` -export default{plugins:[{name:'gallery', - transformIndexHtml:h=>{ - const s=tiles(),all=s.flat() +const test=h=>h.replace('max-image-preview:large','noindex').replace(/','') + .replace('vibegif ·','vibegif test ·').replace(/

.*<\/h1>/,'

gifs waiting for approval

').replace('feel free to hot link them','not on the main page yet') +export default{build:{rolldownOptions:{input:['index.html','test.html']}},plugins:[{name:'gallery', + transformIndexHtml:(h,{path})=>{ + const t=path=='/test.html',s=tiles(t?pending:sections),all=s.flat() + if(t)h=test(rf('index.html','utf8')) return h.replace('',s.map(ts=>ts.map(figure).join('\n')).filter(Boolean).join('\n
\n')) .replace('',ld(all)).replaceAll('',all.length) },