You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

52 lines
1.9 KiB

import { isBlurhashValid } from 'blurhash'
/**
* Stable, varied BlurHash strings for lazy media (no NIP-94 blurHash).
*
* Earlier we used a small set from the BlurHash reference corpus; several of those decode
* to very high average luminance (~0.7–0.85 on a 0–1 scale), so at 32×32 scaled up they
* read as “empty white” boxes — especially next to real colorful hashes from imeta.
*
* This list mixes medium-luma reference hashes with encodings of saturated solids and
* gradients (all validated). URL hashing still picks deterministically among them.
*/
const PLACEHOLDER_BLURHASHES = [
'LEHV6nWB2yk8pyo0adR*.7kCMdnj',
'LGF5]+Yk^6#M@-5c,1J5@[or[Q6.',
'LdHxL5Rk^6#M@-5c,1J5@[or[Q6.',
'LGF?UQ%2Tw[w]~RBVZRi};RPxuwH',
'U18:W20c[[Os-ZNrjta}fQfQfQfQ-ZNrjta}',
'U1Ed6O05}-I[}rEhoKazfQfQfQfQ}rEhoKaz',
'U32?$,uWklo{kWk9fjfjfQfQfQfQkWk9fjfj',
'U08DbR00omx9?IRhfSjsfQfQfQfQ?IRhfSjs',
'U56aYxGKfmkEogbIfRfRfQfQfQfQogbIfRfR',
'L19GOz-afQ-a-aj]fQj]fQfQfQfQ',
'L03eAJuifQuiuikCfQkCfQfQfQfQ',
'L1D*FJ}rfQ}r}roLfQoLfQfQfQfQ'
].filter((h) => isBlurhashValid(h).result)
function fallbackHashString(s: string): number {
let h = 0
for (let i = 0; i < s.length; i++) {
h = (Math.imul(31, h) + s.charCodeAt(i)) | 0
}
return Math.abs(h)
}
/** Deterministic placeholder blurhash from media URL (stable across re-renders). */
export function blurHashPlaceholderForMediaUrl(url: string): string {
if (PLACEHOLDER_BLURHASHES.length === 0) {
return 'LEHV6nWB2yk8pyo0adR*.7kCMdnj'
}
const i = fallbackHashString(url.trim()) % PLACEHOLDER_BLURHASHES.length
return PLACEHOLDER_BLURHASHES[i]!
}
/** Use NIP-94 blurHash when valid; otherwise URL-derived placeholder. */
export function resolveMediaBlurPlaceholder(url: string, blurHash?: string): string {
if (blurHash?.trim()) {
const v = isBlurhashValid(blurHash.trim())
if (v.result) return blurHash.trim()
}
return blurHashPlaceholderForMediaUrl(url)
}