Openstatus www.openstatus.dev

fix: globe if webgl is disable (#700)

authored by

Maximilian Kaske and committed by
GitHub
65d73220 4ef733c7

+28 -2
+28 -2
apps/web/src/components/marketing/monitor/globe.tsx
··· 1 1 "use client"; 2 2 3 - import { useEffect, useRef } from "react"; 3 + import { useEffect, useRef, useState } from "react"; 4 4 import createGlobe from "cobe"; 5 5 6 6 import { useMediaQuery } from "@/hooks/use-media-query"; 7 7 8 8 const SIZE = 350; 9 9 10 + // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/By_example/Detect_WebGL 11 + function isWebGLContext() { 12 + const canvas = document.createElement("canvas"); 13 + const gl = 14 + canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); 15 + 16 + return gl instanceof WebGLRenderingContext; 17 + } 18 + 10 19 export function Globe() { 11 20 const canvasRef = useRef<HTMLCanvasElement>(null); 12 21 const prefersReducedMotion = useMediaQuery( 13 - "((prefers-reduced-motion: reduce))", 22 + "(prefers-reduced-motion: reduce)", 14 23 ); 24 + const [disabledWebGL, setDisabledWebGL] = useState(false); 15 25 16 26 useEffect(() => { 17 27 let phi = 0; 18 28 if (!canvasRef.current) return; 29 + if (!document) return; 30 + if (!isWebGLContext()) { 31 + setDisabledWebGL(true); 32 + return; 33 + } 19 34 20 35 const globe = createGlobe(canvasRef.current, { 21 36 devicePixelRatio: 2, ··· 64 79 globe.destroy(); 65 80 }; 66 81 }, [prefersReducedMotion]); 82 + 83 + if (disabledWebGL) { 84 + return ( 85 + <div className="flex items-center justify-center"> 86 + <p className="text-muted-foreground text-sm"> 87 + <span className="font-semibold">Hint</span>: enable{" "} 88 + <span className="font-semibold">WebGL</span> to render the globe. 89 + </p> 90 + </div> 91 + ); 92 + } 67 93 68 94 return ( 69 95 <div className="flex justify-center">