diff --git a/src/lib/cards/BlueskyMediaCard/CreateBlueskyMediaCardModal.svelte b/src/lib/cards/BlueskyMediaCard/CreateBlueskyMediaCardModal.svelte index 8c12bb9..071cec5 100644 --- a/src/lib/cards/BlueskyMediaCard/CreateBlueskyMediaCardModal.svelte +++ b/src/lib/cards/BlueskyMediaCard/CreateBlueskyMediaCardModal.svelte @@ -9,7 +9,7 @@ let did = getDidContext(); - let mediaList: { fullsize: string; isVideo?: boolean; playlist?: string }[] = $state([]); + let mediaList: { fullsize: string; isVideo?: boolean; playlist?: string, thumbnail?: string }[] = $state([]); let isLoading = $state(true); @@ -17,14 +17,17 @@ const authorFeed = await getAuthorFeed({ did }); for (let post of authorFeed?.feed ?? []) { - for (let image of post.post.embed?.images ?? []) { + let images = post.post.embed?.$type === 'app.bsky.embed.images#view' ? post.post.embed : undefined + + for (let image of images?.images ?? []) { mediaList.push(image); } - if (post.post.embed.thumbnail && post.post.embed.playlist) { + if (post.post.embed?.$type === 'app.bsky.embed.video#view' && post.post.embed.thumbnail && post.post.embed.playlist) { mediaList.push({ ...post.post.embed, - isVideo: true + isVideo: true, + fullsize: '' }); } } @@ -64,7 +67,7 @@ class="relative cursor-pointer" > import type { ContentComponentProps } from '../types'; import { onMount, onDestroy, tick } from 'svelte'; - import ditheringTextureUrl from './LDR_LLL1_0.png'; - let { item }: ContentComponentProps = $props(); let container: HTMLDivElement; @@ -15,6 +13,99 @@ let isInitialized = $state(false); let resizeObserver: ResizeObserver | null = null; + // Pure hash function for shader keyword caching + function hashCode(s: string) { + if (s.length === 0) return 0; + let hash = 0; + for (let i = 0; i < s.length; i++) { + hash = (hash << 5) - hash + s.charCodeAt(i); + hash |= 0; + } + return hash; + } + + // WebGL helper types + type CompileShaderFn = (type: number, source: string, keywords?: string[]) => WebGLShader; + type CreateProgramFn = (vs: WebGLShader, fs: WebGLShader) => WebGLProgram; + type GetUniformsFn = (program: WebGLProgram) => Record; + + // Material class for shader programs with keyword variants + class Material { + private gl: WebGL2RenderingContext; + private compileShader: CompileShaderFn; + private createProgramFn: CreateProgramFn; + private getUniformsFn: GetUniformsFn; + vertexShader: WebGLShader; + fragmentShaderSource: string; + programs: Record = {}; + activeProgram: WebGLProgram | null = null; + uniforms: Record = {}; + + constructor( + gl: WebGL2RenderingContext, + vertexShader: WebGLShader, + fragmentShaderSource: string, + compileShader: CompileShaderFn, + createProgramFn: CreateProgramFn, + getUniformsFn: GetUniformsFn + ) { + this.gl = gl; + this.compileShader = compileShader; + this.createProgramFn = createProgramFn; + this.getUniformsFn = getUniformsFn; + this.vertexShader = vertexShader; + this.fragmentShaderSource = fragmentShaderSource; + } + + setKeywords(keywords: string[]) { + let hash = 0; + for (let i = 0; i < keywords.length; i++) hash += hashCode(keywords[i]); + + let program = this.programs[hash]; + if (!program) { + const fragmentShader = this.compileShader( + this.gl.FRAGMENT_SHADER, + this.fragmentShaderSource, + keywords + ); + program = this.createProgramFn(this.vertexShader, fragmentShader); + this.programs[hash] = program; + } + + if (program === this.activeProgram) return; + + this.uniforms = this.getUniformsFn(program); + this.activeProgram = program; + } + + bind() { + this.gl.useProgram(this.activeProgram); + } + } + + // Program class for simple shader programs + class Program { + private gl: WebGL2RenderingContext; + uniforms: Record = {}; + program: WebGLProgram; + + constructor( + gl: WebGL2RenderingContext, + vertexShader: WebGLShader, + fragmentShader: WebGLShader, + createProgramFn: CreateProgramFn, + getUniformsFn: GetUniformsFn + ) { + this.gl = gl; + this.program = createProgramFn(vertexShader, fragmentShader); + this.uniforms = getUniformsFn(this.program); + } + + bind() { + this.gl.useProgram(this.program); + } + } + // Get text from card data const text = $derived((item.cardData?.text as string) || 'hello'); const fontWeight = '900'; @@ -180,8 +271,9 @@ let pointers: Pointer[] = [PointerPrototype()]; let splatStack: number[] = []; - const { gl, ext } = getWebGLContext(fluidCanvas); - if (!gl) return; + const { gl: glMaybeNull, ext } = getWebGLContext(fluidCanvas); + if (!glMaybeNull) return; + const gl = glMaybeNull; if (isMobile()) { config.DYE_RESOLUTION = 512; @@ -316,59 +408,7 @@ return /Mobi|Android/i.test(navigator.userAgent); } - class Material { - vertexShader: WebGLShader; - fragmentShaderSource: string; - programs: Record = {}; - activeProgram: WebGLProgram | null = null; - uniforms: Record = {}; - - constructor(vertexShader: WebGLShader, fragmentShaderSource: string) { - this.vertexShader = vertexShader; - this.fragmentShaderSource = fragmentShaderSource; - } - - setKeywords(keywords: string[]) { - let hash = 0; - for (let i = 0; i < keywords.length; i++) hash += hashCode(keywords[i]); - - let program = this.programs[hash]; - if (!program) { - const fragmentShader = compileShader( - gl.FRAGMENT_SHADER, - this.fragmentShaderSource, - keywords - ); - program = createProgram(this.vertexShader, fragmentShader); - this.programs[hash] = program; - } - - if (program === this.activeProgram) return; - - this.uniforms = getUniforms(program); - this.activeProgram = program; - } - - bind() { - gl.useProgram(this.activeProgram); - } - } - - class Program { - uniforms: Record = {}; - program: WebGLProgram; - - constructor(vertexShader: WebGLShader, fragmentShader: WebGLShader) { - this.program = createProgram(vertexShader, fragmentShader); - this.uniforms = getUniforms(this.program); - } - - bind() { - gl.useProgram(this.program); - } - } - - function createProgram(vertexShader: WebGLShader, fragmentShader: WebGLShader) { + function createWebGLProgram(vertexShader: WebGLShader, fragmentShader: WebGLShader) { const program = gl.createProgram()!; gl.attachShader(program, vertexShader); gl.attachShader(program, fragmentShader); @@ -848,23 +888,21 @@ let sunrays: FBO; let sunraysTemp: FBO; - const ditheringTexture = createTextureAsync(ditheringTextureUrl); - - const blurProgram = new Program(blurVertexShader, blurShader); - const copyProgram = new Program(baseVertexShader, copyShader); - const clearProgram = new Program(baseVertexShader, clearShader); - const colorProgram = new Program(baseVertexShader, colorShader); - const splatProgram = new Program(baseVertexShader, splatShader); - const advectionProgram = new Program(baseVertexShader, advectionShader); - const divergenceProgram = new Program(baseVertexShader, divergenceShader); - const curlProgram = new Program(baseVertexShader, curlShader); - const vorticityProgram = new Program(baseVertexShader, vorticityShader); - const pressureProgram = new Program(baseVertexShader, pressureShader); - const gradienSubtractProgram = new Program(baseVertexShader, gradientSubtractShader); - const sunraysMaskProgram = new Program(baseVertexShader, sunraysMaskShader); - const sunraysProgram = new Program(baseVertexShader, sunraysShader); - - const displayMaterial = new Material(baseVertexShader, displayShaderSource); + const blurProgram = new Program(gl, blurVertexShader, blurShader, createWebGLProgram, getUniforms); + const copyProgram = new Program(gl, baseVertexShader, copyShader, createWebGLProgram, getUniforms); + const clearProgram = new Program(gl, baseVertexShader, clearShader, createWebGLProgram, getUniforms); + const colorProgram = new Program(gl, baseVertexShader, colorShader, createWebGLProgram, getUniforms); + const splatProgram = new Program(gl, baseVertexShader, splatShader, createWebGLProgram, getUniforms); + const advectionProgram = new Program(gl, baseVertexShader, advectionShader, createWebGLProgram, getUniforms); + const divergenceProgram = new Program(gl, baseVertexShader, divergenceShader, createWebGLProgram, getUniforms); + const curlProgram = new Program(gl, baseVertexShader, curlShader, createWebGLProgram, getUniforms); + const vorticityProgram = new Program(gl, baseVertexShader, vorticityShader, createWebGLProgram, getUniforms); + const pressureProgram = new Program(gl, baseVertexShader, pressureShader, createWebGLProgram, getUniforms); + const gradienSubtractProgram = new Program(gl, baseVertexShader, gradientSubtractShader, createWebGLProgram, getUniforms); + const sunraysMaskProgram = new Program(gl, baseVertexShader, sunraysMaskShader, createWebGLProgram, getUniforms); + const sunraysProgram = new Program(gl, baseVertexShader, sunraysShader, createWebGLProgram, getUniforms); + + const displayMaterial = new Material(gl, baseVertexShader, displayShaderSource, compileShader, createWebGLProgram, getUniforms); function getResolution(resolution: number) { let aspectRatio = gl.drawingBufferWidth / gl.drawingBufferHeight; @@ -987,48 +1025,6 @@ return target; } - function createTextureAsync(url: string) { - const texture = gl.createTexture()!; - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); - gl.texImage2D( - gl.TEXTURE_2D, - 0, - gl.RGB, - 1, - 1, - 0, - gl.RGB, - gl.UNSIGNED_BYTE, - new Uint8Array([255, 255, 255]) - ); - - const obj = { - texture, - width: 1, - height: 1, - attach(id: number) { - gl.activeTexture(gl.TEXTURE0 + id); - gl.bindTexture(gl.TEXTURE_2D, texture); - return id; - } - }; - - const image = new Image(); - image.onload = () => { - obj.width = image.width; - obj.height = image.height; - gl.bindTexture(gl.TEXTURE_2D, texture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image); - }; - image.src = url; - - return obj; - } - function initFramebuffers() { const simRes = getResolution(config.SIM_RESOLUTION); const dyeRes = getResolution(config.DYE_RESOLUTION); @@ -1452,16 +1448,6 @@ animationId = requestAnimationFrame(update); } - function hashCode(s: string) { - if (s.length === 0) return 0; - let hash = 0; - for (let i = 0; i < s.length; i++) { - hash = (hash << 5) - hash + s.charCodeAt(i); - hash |= 0; - } - return hash; - } - function correctDeltaX(delta: number) { const aspectRatio = fluidCanvas.width / fluidCanvas.height; if (aspectRatio < 1) delta *= aspectRatio; diff --git a/src/lib/cards/FluidTextCard/LDR_LLL1_0.png b/src/lib/cards/FluidTextCard/LDR_LLL1_0.png deleted file mode 100644 index d1920c63aab8bcee44df5a8f9f98cdf361b11a80..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7115 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 ZK11M^m#*dsF9rq%22WQ%mvv4FO#nIc=@9?` diff --git a/src/lib/components/post/embeds/External.svelte b/src/lib/components/post/embeds/External.svelte index db8a70f..b7bfc0d 100644 --- a/src/lib/components/post/embeds/External.svelte +++ b/src/lib/components/post/embeds/External.svelte @@ -3,13 +3,14 @@ const { data }: { data: PostEmbedExternal } = $props(); + // svelte-ignore state_referenced_locally const domain = new URL(data.external.href).hostname.replace('www.', '');
{#if data.external.thumb} @@ -20,7 +21,7 @@ /> {/if}