pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

detect all images and add a fade in animation on image loads

Pas bf1bb277 ba7c079b

+73
+16
src/assets/css/index.css
··· 427 427 .google-cast-button:not(.casting) google-cast-launcher { 428 428 @apply brightness-[500]; 429 429 } 430 + 431 + /* Image fade-in on load */ 432 + img:not([src=""]) { 433 + opacity: 0; 434 + transition: opacity 0.8s ease-in-out; 435 + } 436 + 437 + /* Fade in when image has loaded class */ 438 + img.loaded { 439 + opacity: 1; 440 + } 441 + 442 + /* For images that are already cached/loaded, show them immediately */ 443 + img[complete]:not([src=""]) { 444 + opacity: 1; 445 + }
+2
src/index.tsx
··· 37 37 isExtensionActiveCached, 38 38 } from "./backend/extension/messaging"; 39 39 import { initializeChromecast } from "./setup/chromecast"; 40 + import { initializeImageFadeIn } from "./setup/imageFadeIn"; 40 41 import { initializeOldStores } from "./stores/__old/migrations"; 41 42 42 43 // initialize 43 44 initializeChromecast(); 45 + initializeImageFadeIn(); 44 46 45 47 function LoadingScreen(props: { type: "user" | "lazy" }) { 46 48 const mapping = {
+55
src/setup/imageFadeIn.ts
··· 1 + /** 2 + * Global image fade-in handler 3 + * Automatically adds 'loaded' class to images when they finish loading 4 + */ 5 + export function initializeImageFadeIn() { 6 + // Handle images that are already loaded (cached) 7 + const handleExistingImages = () => { 8 + const images = document.querySelectorAll("img:not(.loaded)"); 9 + images.forEach((img) => { 10 + const htmlImg = img as HTMLImageElement; 11 + if (htmlImg.complete && htmlImg.naturalHeight !== 0) { 12 + htmlImg.classList.add("loaded"); 13 + } 14 + }); 15 + }; 16 + 17 + // Handle images that load after DOM is ready 18 + const handleImageLoad = (e: Event) => { 19 + const img = e.target as HTMLImageElement; 20 + if (img.tagName === "IMG") { 21 + img.classList.add("loaded"); 22 + } 23 + }; 24 + 25 + // Use event delegation for all images (including dynamically added ones) 26 + document.addEventListener("load", handleImageLoad, true); 27 + 28 + // Handle existing images on initialization 29 + if (document.readyState === "loading") { 30 + document.addEventListener("DOMContentLoaded", handleExistingImages); 31 + } else { 32 + handleExistingImages(); 33 + } 34 + 35 + // Also check periodically for images that might have loaded 36 + // This handles edge cases where the load event might not fire 37 + const checkInterval = setInterval(() => { 38 + const images = document.querySelectorAll("img:not(.loaded)"); 39 + if (images.length === 0) { 40 + clearInterval(checkInterval); 41 + return; 42 + } 43 + images.forEach((img) => { 44 + const htmlImg = img as HTMLImageElement; 45 + if (htmlImg.complete && htmlImg.naturalHeight !== 0) { 46 + htmlImg.classList.add("loaded"); 47 + } 48 + }); 49 + }, 100); 50 + 51 + // Clean up interval after 10 seconds to avoid memory leaks 52 + setTimeout(() => { 53 + clearInterval(checkInterval); 54 + }, 10000); 55 + }