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:
parent
83b152c7b5
commit
cce66b19c4
5 changed files with 81 additions and 24 deletions
|
@ -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}` : ''}"
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
BIN
static/retro/buttons/yui.gif
Normal file
BIN
static/retro/buttons/yui.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
Loading…
Add table
Add a link
Reference in a new issue