Compare commits

..

No commits in common. "70d011423b3a5d21c21fe73efa6b88ca271d9f70" and "1e057245efd360ee6ba23a55bcfa4eb72939ef22" have entirely different histories.

6 changed files with 39 additions and 93 deletions

View File

@ -1,17 +0,0 @@
<script lang="ts">
import Window from "./window.svelte";
export let x: string = "translate-x-none"
export let y: string = "translate-y-full"
export let targetY: string = "group-hover:-translate-y-[105%]"
export let targetX: string = "group-hover:-translate-x-2/3"
</script>
<div class="group">
<div class="absolute scale-0 transition-all [transition-duration:300ms] opacity-0 group-hover:scale-100 group-hover:opacity-100 {y} {x} {targetY} {targetX} transform-gpu">
<Window tooltip>
<slot name="tooltipContent">Hello world!</slot>
</Window>
</div>
<slot/>
</div>

View File

@ -11,7 +11,6 @@
export let center: boolean = false; export let center: boolean = false;
export let layered: boolean = false; export let layered: boolean = false;
export let style: string = ""; export let style: string = "";
export let tooltip: boolean = false;
const scaleKeyframes = [ const scaleKeyframes = [
"window-open", "window-open",
@ -47,9 +46,9 @@
on:click={(data) => {focusWindow(data.currentTarget)}} on:click={(data) => {focusWindow(data.currentTarget)}}
class=" class="
relative {layered ? "col-[1] row-[1]" : ""} flex flex-col {sticky ? 'md:sticky md:-top-9' : ''} {center ? "mx-auto" : ""} relative {layered ? "col-[1] row-[1]" : ""} flex flex-col {sticky ? 'md:sticky md:-top-9' : ''} {center ? "mx-auto" : ""}
max-w-screen-md xl:max-w-screen-lg 2xl:max-w-screen-xl {tooltip ? "min-w-fit" : "min-w-[30ch] lg:min-w-[40ch]"} w-full md:w-fit [height:fit-content] max-w-screen-md xl:max-w-screen-lg 2xl:max-w-screen-xl min-w-[30ch] lg:min-w-[40ch] w-full md:w-fit [height:fit-content]
bg-ralsei-black border-ralsei-white border-ridge {tooltip ? "border-[6px] border-t-[9px]" : "border-8 border-t-[12px]"} bg-ralsei-black border-ralsei-white border-ridge border-8 border-t-[12px]
animate-{chosenKeyframe} drop-shadow-[24px_24px_24px_rgba(1,1,1,0.8)] animate-{chosenKeyframe} drop-shadow-[35px_35px_35px_rgba(1,1,1,0.5)]
{style} {style}
" "
{id} {id}
@ -84,7 +83,7 @@
</div> </div>
{/if} {/if}
<div class=" <div class="
{removePadding ? "" : tooltip ? "p-1" : "p-2"} bg-gradient-to-tl {removePadding ? "" : "p-2"} bg-gradient-to-tl
to-ralsei-pink-neon/15 from-ralsei-pink-regular/20 to-ralsei-pink-neon/15 from-ralsei-pink-regular/20
"> ">
<slot /> <slot />

View File

@ -7,61 +7,31 @@ import { get, writable } from "svelte/store";
const visitCountFile = `${env.WEBSITE_DATA_DIR}/visitcount` const visitCountFile = `${env.WEBSITE_DATA_DIR}/visitcount`
const visitCount = writable(parseInt(existsSync(visitCountFile) ? readFileSync(visitCountFile).toString() : '0')); const visitCount = writable(parseInt(existsSync(visitCountFile) ? readFileSync(visitCountFile).toString() : '0'));
type Visitor = { since: number }
const lastVisitors = writable<Visitor[]>([]);
const MAX_VISITORS = 10
const VISITOR_EXPIRY_SECONDS = 60 * 30 // half an hour is reasonable
export const incrementVisitCount = (request: Request, cookies: Cookies) => { export const incrementVisitCount = (request: Request, cookies: Cookies) => {
let currentVisitCount = get(visitCount) let currentVisitCount = get(visitCount)
// check whether the request is from a bot or not (this doesnt need to be accurate we just want to filter out honest bots) // check whether the request is from a bot or not (this doesnt need to be accurate we just want to filter out honest bots)
if (isBot(request)) { return currentVisitCount } const ua = request.headers.get('user-agent')
const scopedCookies = scopeCookies(cookies, '/') const isBot = ua ? ua.toLowerCase().match(/(bot|crawl|spider|walk)/) !== null : true
// parse the last visit timestamp from cookies if it exists if (!isBot) {
const visitedTimestamp = parseInt(scopedCookies.get('visitedTimestamp') || "0") const scopedCookies = scopeCookies(cookies, '/')
// get unix timestamp // parse the last visit timestamp from cookies if it exists
const currentTime = Date.now() const visitedTimestamp = parseInt(scopedCookies.get('visitedTimestamp') || "0")
const timeSinceVisit = currentTime - visitedTimestamp // get unix timestamp
// check if this is the first time a client is visiting or if an hour has passed since they last visited const currentTime = new Date().getTime()
if (visitedTimestamp === 0 || timeSinceVisit > 1000 * 60 * 60 * 24) { const timeSinceVisit = currentTime - visitedTimestamp
// increment current and write to the store // check if this is the first time a client is visiting or if an hour has passed since they last visited
currentVisitCount += 1; visitCount.set(currentVisitCount) if (visitedTimestamp === 0 || timeSinceVisit > 1000 * 60 * 60 * 24) {
// update the cookie with the current timestamp // increment current and write to the store
scopedCookies.set('visitedTimestamp', currentTime.toString()) currentVisitCount += 1; visitCount.set(currentVisitCount)
// write the visit count to a file so we can load it later again // update the cookie with the current timestamp
writeFileSync(visitCountFile, currentVisitCount.toString()) scopedCookies.set('visitedTimestamp', currentTime.toString())
// write the visit count to a file so we can load it later again
writeFileSync(visitCountFile, currentVisitCount.toString())
}
} }
return currentVisitCount return currentVisitCount
} }
export const addLastVisitor = (request: Request, cookies: Cookies) => {
const currentTime = Date.now()
let visitors = get(lastVisitors).filter(
(value) => { return currentTime - value.since > 1000 * VISITOR_EXPIRY_SECONDS }
)
// check whether the request is from a bot or not (this doesnt need to be accurate we just want to filter out honest bots)
if (isBot(request)) { return visitors }
const scopedCookies = scopeCookies(cookies, '/')
// parse the last visit timestamp from cookies if it exists
const visitorTimestamp = parseInt(scopedCookies.get('visitorTimestamp') || "0")
// get unix timestamp
const timeSinceVisit = currentTime - visitorTimestamp
// check if this is the first time a client is visiting or if an hour has passed since they last visited
if (visitorTimestamp === 0 || timeSinceVisit > 1000 * VISITOR_EXPIRY_SECONDS) {
visitors.push({ since: currentTime })
if (visitors.length > MAX_VISITORS) { visitors.shift() }
// update the cookie with the current timestamp
scopedCookies.set('visitorTimestamp', currentTime.toString())
}
return visitors
}
const isBot = (request: Request) => {
const ua = request.headers.get('user-agent')
return ua ? ua.toLowerCase().match(/(bot|crawl|spider|walk|fetch|scrap|proxy|image)/) !== null : true
}
export const notifyDarkVisitors = (url: URL, request: Request) => { export const notifyDarkVisitors = (url: URL, request: Request) => {
fetch('https://api.darkvisitors.com/visits', { fetch('https://api.darkvisitors.com/visits', {
method: 'POST', method: 'POST',

View File

@ -2,7 +2,6 @@
import { browser } from '$app/environment'; import { browser } from '$app/environment';
import getTitle from '$lib/getTitle'; import getTitle from '$lib/getTitle';
import NavButton from '../components/navButton.svelte'; import NavButton from '../components/navButton.svelte';
import Tooltip from '../components/tooltip.svelte';
import Window from '../components/window.svelte'; import Window from '../components/window.svelte';
import '../styles/app.css'; import '../styles/app.css';
@ -158,12 +157,14 @@
<a class="hover:underline" href="https://xn--sr8hvo.ws">IndieWeb 🕸💍</a> <a class="hover:underline" href="https://xn--sr8hvo.ws">IndieWeb 🕸💍</a>
<a title="next site" class="hover:underline" href="https://xn--sr8hvo.ws/next"></a> <a title="next site" class="hover:underline" href="https://xn--sr8hvo.ws/next"></a>
</div> </div>
<Tooltip> <div class="group navbox">
<svelte:fragment slot="tooltipContent"> <div class="absolute transition-all opacity-0 group-hover:opacity-100 translate-y-2/3 -translate-x-1/3 group-hover:-translate-y-2/3 transform-gpu">
<img class="min-w-64" style="image-rendering: crisp-edges pixelated;" alt="visits" src="https://count.getloli.com/@yusdacrawebsite?name=yusdacrawebsitetest&theme=booru-lewd&padding=5&offset=0&align=center&scale=1&pixelated=1&darkmode=0&num={data.visitCount}"/> <Window style="!min-w-fit">
</svelte:fragment> <img class="min-w-64" style="image-rendering: crisp-edges pixelated;" alt="visits" src="https://count.getloli.com/@yusdacrawebsite?name=yusdacrawebsitetest&theme=booru-lewd&padding=5&offset=0&align=center&scale=1&pixelated=1&darkmode=0&num={data.visitCount}"/>
<div class="navbox"><p><span class="text-ralsei-green-light text-shadow-green">{data.visitCount}</span> visit(s)</p></div> </Window>
</Tooltip> </div>
<p><span class="text-ralsei-green-light text-shadow-green">{data.visitCount}</span> visit(s)</p>
</div>
{#if isRoute("entries")} {#if isRoute("entries")}
<div class="navbox !gap-1"> <div class="navbox !gap-1">
<a class="align-middle hover:underline" href="/entries/_rss">rss</a> <a class="align-middle hover:underline" href="/entries/_rss">rss</a>

View File

@ -1,6 +1,5 @@
<script> <script>
import { PUBLIC_BASE_URL } from '$env/static/public'; import { PUBLIC_BASE_URL } from '$env/static/public';
import Tooltip from '../components/tooltip.svelte';
import Window from '../components/window.svelte'; import Window from '../components/window.svelte';
export let data; export let data;
@ -11,14 +10,12 @@
<Window title="readme?" iconUri="/icons/question.png"> <Window title="readme?" iconUri="/icons/question.png">
<div class="flex flex-col prose prose-ralsei prose-img:m-0 leading-none"> <div class="flex flex-col prose prose-ralsei prose-img:m-0 leading-none">
<div class="flex flex-grow"> <div class="flex flex-grow">
<Tooltip x="-translate-x-[40%]" targetX="group-hover:-translate-x-[10%]"> <img
<svelte:fragment slot="tooltipContent">character from q.u.q. (good vn go read it NOW)</svelte:fragment> class="mt-1 ml-1 w-36 [height:9rem] u-photo"
<img src="/pfp.png"
class="mt-1 ml-1 w-36 [height:9rem] u-photo" alt="character from q.u.q."
src="/pfp.png" title="character from q.u.q. (good vn go read it NOW)"
alt="character from q.u.q." />
/>
</Tooltip>
<ul <ul
class="place-self-center m-0 leading-none marker:[content:'->'] [list-style-type:'->']" class="place-self-center m-0 leading-none marker:[content:'->'] [list-style-type:'->']"
> >

View File

@ -1,6 +1,5 @@
<script lang="ts"> <script lang="ts">
import Tooltip from '../../components/tooltip.svelte'; import Window from '../../components/window.svelte';
import Window from '../../components/window.svelte';
export let data; export let data;
$: hasPreviousPage = data.page > 1; $: hasPreviousPage = data.page > 1;
@ -44,18 +43,15 @@ import Window from '../../components/window.svelte';
<p class="text-sm font-monospace">--- posted by ...</p> <p class="text-sm font-monospace">--- posted by ...</p>
</div> </div>
</div> </div>
<div class="entry flex flex-wrap gap-1.5 p-1 items-center"> <div class="entry flex flex-wrap gap-1.5 p-1">
<p class="text-xl ms-2 align-middle">auth via:</p> <p class="text-xl ms-2">auth via:</p>
{#each ['discord', 'github'] as platform} {#each ['discord', 'github'] as platform}
<Tooltip x="" y="translate-y-[70%]" targetY="" targetX="">
<svelte:fragment slot="tooltipContent">post with {platform}</svelte:fragment>
<input <input
type="submit" type="submit"
value={platform} value={platform}
formaction="?/post_{platform}" formaction="?/post_{platform}"
class="text-lg text-ralsei-green-light leading-5 hover:underline motion-safe:hover:animate-squiggle w-fit p-0.5" class="text-lg text-ralsei-green-light leading-5 hover:underline motion-safe:hover:animate-squiggle w-fit p-0.5"
/> />
</Tooltip>
{/each} {/each}
</div> </div>
{#if data.sendRatelimited} {#if data.sendRatelimited}