diff --git a/README.md b/README.md index 506518d..81ccb64 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,10 @@ ![booru-koe](https://count.getloli.com/@demo?theme=booru-koe) +##### booru-lewd + +![booru-lewd](https://count.getloli.com/@demo?theme=booru-lewd) + ##### booru-lisu ![booru-lisu](https://count.getloli.com/@demo?theme=booru-lisu) @@ -141,6 +145,10 @@ ![kyun](https://count.getloli.com/@demo?theme=kyun) +##### love-and-deepspace + +![love-and-deepspace](https://count.getloli.com/@demo?theme=love-and-deepspace) + ##### minecraft ![minecraft](https://count.getloli.com/@demo?theme=minecraft) diff --git a/assets/script.js b/assets/script.js index 896af9a..8a33542 100644 --- a/assets/script.js +++ b/assets/script.js @@ -11,6 +11,7 @@ scale: document.getElementById('scale'), pixelated: document.getElementById('pixelated'), darkmode: document.getElementById('darkmode'), + num: document.getElementById('num') }; btn.addEventListener('click', throttle(handleButtonClick, 500)); @@ -24,7 +25,7 @@ moreTheme.addEventListener('click', scrollToThemes); function handleButtonClick() { - const { name, theme, padding, offset, scale, pixelated, darkmode } = elements; + const { name, theme, padding, offset, scale, pixelated, darkmode, num } = elements; const nameValue = name.value.trim(); if (!nameValue) { @@ -42,6 +43,10 @@ darkmode: darkmode.value || 'auto' }; + if (num.value > 0) { + params.num = num.value; + } + const query = new URLSearchParams(params).toString(); const imgSrc = `${__global_data.site}/@${nameValue}?${query}`; @@ -58,7 +63,7 @@ img.onerror = async () => { try { - const res = await fetch(imgSrc); + const res = await fetch(img.src); if (!res.ok) { const { message } = await res.json(); alert(message); @@ -191,7 +196,7 @@ btn.addEventListener('click', handleClick); })(); -// Prevent gesture +// Prevent safari gesture (() => { document.addEventListener('gesturestart', e => e.preventDefault()); })(); diff --git a/assets/style.less b/assets/style.less index 3f8249c..eeac11e 100644 --- a/assets/style.less +++ b/assets/style.less @@ -58,6 +58,10 @@ input[type="checkbox"][role="switch"] { position: relative; transition: 0.3s; + &:active:after { + width: 2.34em; + } + &:after { content: ""; position: absolute; @@ -80,7 +84,7 @@ input[type="checkbox"][role="switch"] { justify-content: space-between; align-items: center; padding: 0 12.5%; - font-size: 0.54em; + font-size: 10px; &::before, &::after { @@ -108,10 +112,6 @@ input[type="checkbox"][role="switch"] { left: calc(100% - 0.1em); transform: translateX(-100%); } - - &:active:after { - width: 2.34em; - } } } @@ -153,6 +153,14 @@ h5 { margin: 1.5em 0 0.6em; } +table { + tr { + .caption { + margin: 1em 0 0; + } + } +} + .back-to-top { position: fixed; z-index: 2; diff --git a/index.js b/index.js index 5931d81..749b733 100644 --- a/index.js +++ b/index.js @@ -32,7 +32,8 @@ app.get(["/@:name", "/get/@:name"], }), query: z.object({ theme: z.string().default("moebooru"), - padding: z.coerce.number().min(0).max(32).default(7), + num: z.coerce.number().min(0).max(1000000000000000).default(0), // a carry-safe integer, less than `2^53-1`, and aesthetically pleasing in decimal. + padding: z.coerce.number().min(0).max(16).default(7), offset: z.coerce.number().min(-500).max(500).default(0), scale: z.coerce.number().min(0.1).max(2).default(1), pixelated: z.enum(["0", "1"]).default("1"), @@ -41,7 +42,7 @@ app.get(["/@:name", "/get/@:name"], }), async (req, res) => { const { name } = req.params; - let { theme = "moebooru", ...rest } = req.query; + let { theme = "moebooru", num = 0, ...rest } = req.query; // This helps with GitHub's image cache res.set({ @@ -49,7 +50,7 @@ app.get(["/@:name", "/get/@:name"], "cache-control": "max-age=0, no-cache, no-store, must-revalidate", }); - const data = await getCountByName(name); + const data = await getCountByName(name, num); if (name === "demo") { res.set("cache-control", "max-age=31536000"); @@ -70,7 +71,7 @@ app.get(["/@:name", "/get/@:name"], console.log( data, - `theme: ${theme}`, + { theme, ...req.query }, `ip: ${req.headers['x-forwarded-for'] || req.connection.remoteAddress}`, `ref: ${req.get("Referrer") || null}`, `ua: ${req.get("User-Agent") || null}` @@ -129,11 +130,13 @@ async function pushDB() { } } -async function getCountByName(name) { +async function getCountByName(name, num) { const defaultCount = { name, num: 0 }; if (name === "demo") return { name, num: "0123456789" }; + if (num > 0) { return { name, num } }; + try { if (!(name in __cache_counter)) { const counter = (await db.getNum(name)) || defaultCount; diff --git a/utils/themify.js b/utils/themify.js index 94047db..0628846 100644 --- a/utils/themify.js +++ b/utils/themify.js @@ -6,18 +6,26 @@ const mimeType = require('mime-types') const sizeOf = require('image-size') const themePath = path.resolve(__dirname, '../assets/theme') +const imgExts = ['.jpg', '.jpeg', '.png', '.gif', '.webp'] const themeList = {} fs.readdirSync(themePath).forEach(theme => { + const currentThemePath = path.resolve(themePath, theme) + // skip non-directory + if (!fs.statSync(currentThemePath).isDirectory()) return + if (!(theme in themeList)) themeList[theme] = {} - const imgList = fs.readdirSync(path.resolve(themePath, theme)) + const imgList = fs.readdirSync(currentThemePath) imgList.forEach(img => { - const imgPath = path.resolve(themePath, theme, img) - const num = path.parse(img).name + // skip non-image files + if (!imgExts.includes(path.extname(img).toLowerCase())) return + + const imgPath = path.resolve(currentThemePath, img) + const char = path.parse(img).name const { width, height } = sizeOf(imgPath) - themeList[theme][num] = { + themeList[theme][char] = { width, height, data: convertToDatauri(imgPath) diff --git a/views/index.pug b/views/index.pug index d54e4e4..990516a 100644 --- a/views/index.pug +++ b/views/index.pug @@ -101,7 +101,7 @@ html td: input#offset(type='number', value='0', min='-500', max='500', step='1', oninput='this.value = this.value.replace(/[^0-9|\-]/g, "")') tr td: code scale - td Set the image scale, between 0.1-2, default is + td Set the image scale, between 0.1-2, default is code 1 td: input#scale(type='number', value='1', min='0.1', max='2', step='0.1', oninput='this.value = this.value.replace(/[^0-9|\.]/g, "")') tr @@ -119,6 +119,14 @@ html option(value="auto", selected) auto option(value="1") yes option(value="0") no + tr + td(colspan=3) + h4.caption Unusual Options + tr + td: code num + td Set counter display number, 0 for disable, default is + code 0 + td: input#num(type='number', value='0', min='0', max='1000000000000000', step='1', oninput='this.value = this.value.replace(/[^0-9]/g, "")') button#get(onclick='_evt_push("click", "normal", "get_counter")') Generate