1
0
Fork 0
mirror of https://github.com/mat-1/matdoesdev.git synced 2025-08-02 23:44:39 +00:00

add yui button and fix bugs with /buttons page

This commit is contained in:
mat 2024-10-01 20:42:15 +00:00
commit cce66b19c4
5 changed files with 81 additions and 24 deletions

View file

@ -27,7 +27,8 @@
<header> <header>
<nav> <nav>
<a href="/buttons" class:selected={selectedPage === 'buttons'}>Buttons</a> <!-- the # is necessary to make onhashchange work -->
<a href="/buttons#" class:selected={selectedPage === 'buttons'}>Buttons</a>
<!-- <a href="/buttons/sites" class:selected={selectedPage === 'sites'}>Sites</a> --> <!-- <a href="/buttons/sites" class:selected={selectedPage === 'sites'}>Sites</a> -->
<a <a
href="/buttons/degrees{$selectedPageName ? `#${$selectedPageName}` : ''}" href="/buttons/degrees{$selectedPageName ? `#${$selectedPageName}` : ''}"

View file

@ -1,13 +1,19 @@
<script lang="ts"> <script lang="ts">
import { onDestroy, onMount } from 'svelte' import { onDestroy, onMount } from 'svelte'
import { buttonIndexFromHash, buttonUrlFromIndex, data, pageIndexFromName } from './88x31' import {
buttonIndexFromHash,
buttonUrlFromIndex,
data,
downloadData,
pageIndexFromName,
} from './88x31'
import { writable } from 'svelte/store' import { writable } from 'svelte/store'
import { page } from '$app/stores' import { page } from '$app/stores'
import ButtonLink from './ButtonLink.svelte' import ButtonLink from './ButtonLink.svelte'
import ExternalLinkIcon from './ExternalLinkIcon.svelte' import ExternalLinkIcon from './ExternalLinkIcon.svelte'
import ExternalLink from './ExternalLink.svelte' import ExternalLink from './ExternalLink.svelte'
import type { UIEventHandler } from 'svelte/elements'
import { browser } from '$app/environment' import { browser } from '$app/environment'
import LoadingDots from '$lib/LoadingDots.svelte'
let searchQuery = writable('') let searchQuery = writable('')
let sort = writable('relevance') let sort = writable('relevance')
@ -40,7 +46,16 @@
}) })
let refs: HTMLDivElement[] = [] let refs: HTMLDivElement[] = []
onMount(() => { let buttonEntries: [number, string][] = []
onMount(async () => {
await downloadData()
if (!data) throw new Error("data should've been downloaded")
buttonEntries = [...data.buttons.entries()]
updateSearch()
updateFromHash()
buttonContainerObserver.observe(buttonsEl, { buttonContainerObserver.observe(buttonsEl, {
childList: true, childList: true,
}) })
@ -60,12 +75,12 @@
let matchingTextIndexes = new Set<number>() let matchingTextIndexes = new Set<number>()
let buttonEntries: [number, string][] = [...data.buttons.entries()]
searchQuery.subscribe(updateSearch) searchQuery.subscribe(updateSearch)
sort.subscribe(updateSearch) sort.subscribe(updateSearch)
function popularityScore(buttonIndex: number): number { function popularityScore(buttonIndex: number): number {
if (!data) return 0
const backlinks = new Set( const backlinks = new Set(
data.button_backlinks[buttonIndex].map((i) => data.pages[i].split('/')[0]) data.button_backlinks[buttonIndex].map((i) => data.pages[i].split('/')[0])
) )
@ -76,6 +91,8 @@
} }
function updateSearch() { function updateSearch() {
if (!data) return 0
const value = $searchQuery const value = $searchQuery
let sortValue = $sort let sortValue = $sort
@ -134,24 +151,32 @@
let selectedPageName = writable<string | null>(null) let selectedPageName = writable<string | null>(null)
$: selectedPageIndex = $selectedPageName === null ? null : pageIndexFromName($selectedPageName) $: selectedPageIndex = $selectedPageName === null ? null : pageIndexFromName($selectedPageName)
page.subscribe(async (page) => { function updateFromHash() {
// this is to work around a sveltekit bug that makes it click the hash twice, which clicks the wrong link the second time const hash = location.hash.slice(1)
await new Promise((r) => requestAnimationFrame(r)) console.log('updateFromHash', hash)
// hash
const hash = page.url.hash.slice(1)
// if the hash has a . then it's a page name // if the hash has a . then it's a page name
if (hash === '') { if (hash === '') {
selectedButtonHash.set(null) $selectedButtonHash = null
selectedPageName.set(null) $selectedPageName = null
} else if (hash.includes('.')) { } else if (hash.includes('.')) {
selectedButtonHash.set(null) $selectedButtonHash = null
selectedPageName.set(hash) $selectedPageName = null // force selectedPageIndex to be recalculated
$selectedPageName = hash
} else { } else {
selectedButtonHash.set(hash) $selectedButtonHash = null // force selectedButtonIndex to be recalculated
selectedPageName.set(null) $selectedButtonHash = hash
$selectedPageName = null
} }
}) }
// page.subscribe(async (page) => {
// // this is to work around a sveltekit bug that makes it click the hash twice, which clicks the wrong link the second time
// await new Promise((r) => requestAnimationFrame(r))
// // set
// updateFromHash()
// })
let cutOffButtonEntries = 500 let cutOffButtonEntries = 500
let isCurrentlyAdding = false let isCurrentlyAdding = false
@ -188,7 +213,7 @@
} }
</script> </script>
<svelte:window bind:scrollY /> <svelte:window bind:scrollY on:hashchange={updateFromHash} />
{#if selectedButtonIndex !== null} {#if selectedButtonIndex !== null}
<h1> <h1>
@ -254,7 +279,13 @@
<option value="random">Random</option> <option value="random">Random</option>
</select> </select>
<p><b>{buttonEntries.length.toLocaleString()}</b> buttons</p> {#if buttonEntries.length === 0}
<div class="loading-indicator">
<LoadingDots />
</div>
{:else}
<p><b>{buttonEntries.length.toLocaleString()}</b> buttons</p>
{/if}
<div class="compact-button-grid" bind:this={buttonsEl}> <div class="compact-button-grid" bind:this={buttonsEl}>
{#each buttonEntries.slice(0, cutOffButtonEntries) as [index, buttonHash] (buttonHash)} {#each buttonEntries.slice(0, cutOffButtonEntries) as [index, buttonHash] (buttonHash)}
@ -296,4 +327,9 @@
display: flex; display: flex;
gap: 1rem; gap: 1rem;
} }
.loading-indicator {
fill: #fff;
margin-top: 1em;
}
</style> </style>

View file

@ -19,9 +19,27 @@ interface Data {
backlink_buttons: number[][] backlink_buttons: number[][]
} }
const res = await fetch('https://matdoes.dev/buttons/88x31.cbor') export let data: Data = {
const buffer = await res.arrayBuffer() pages: [],
export const data: Data = decode(new Uint8Array(buffer)) buttons: [],
texts: [],
button_file_exts: [],
button_names: [],
button_links: [],
button_backlinks: [],
links: [],
link_buttons: [],
link_button_alts: [],
link_button_titles: [],
backlinks: [],
backlink_buttons: [],
}
export async function downloadData() {
const res = await fetch('https://matdoes.dev/buttons/88x31.cbor')
const buffer = await res.arrayBuffer()
data = decode(new Uint8Array(buffer))
}
export function buttonUrlFromIndex(index: number) { export function buttonUrlFromIndex(index: number) {
const hash = buttonHashFromIndex(index) const hash = buttonHashFromIndex(index)
@ -54,6 +72,7 @@ function binarySearch<T>(arr: T[], key: T): number | null {
} }
export function pageIndexFromName(name: string): number | null { export function pageIndexFromName(name: string): number | null {
console.log('pageIndexFromName', name, binarySearch(data.pages, name))
return binarySearch(data.pages, name) return binarySearch(data.pages, name)
} }

View file

@ -270,10 +270,11 @@
<Button href="//haylinmoore.com/" src="haylin.png" alt="haylin moore" /> <Button href="//haylinmoore.com/" src="haylin.png" alt="haylin moore" />
<Button href="//ezri.pet/" src="ezri.png" alt="ezri" /> <Button href="//ezri.pet/" src="ezri.png" alt="ezri" />
<Button <Button
href="//thomasricci.dev/" href="//thomasricci.dev"
src="rudrecciah.png" src="rudrecciah.png"
alt="thomas ricci aka rudrecciah" alt="thomas ricci aka rudrecciah"
/> />
<Button href="//zptr.cc" src="yui.gif" alt="yui aka zeroptr" />
<Button href="//archlinux.org" src="archbtw.png" alt="archbtw" /> <Button href="//archlinux.org" src="archbtw.png" alt="archbtw" />
<Button href="//github.com/mat-1" src="github.gif" alt="github" /> <Button href="//github.com/mat-1" src="github.gif" alt="github" />
<Button href="//ko-fi.com/matdoesdev" src="kofi.gif" alt="kofi" /> <Button href="//ko-fi.com/matdoesdev" src="kofi.gif" alt="kofi" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB