Fix room icons not rendering on iOS (#361)
Co-authored-by: Aditya Chaudhary <30+useradityaa@noreply.coracle.social>
This commit is contained in:
parent
f411973409
commit
84fee9de18
1 changed files with 34 additions and 18 deletions
|
|
@ -6,7 +6,6 @@
|
|||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import {onMount} from "svelte"
|
||||
import {maybe} from "@welshman/lib"
|
||||
|
||||
const {
|
||||
|
|
@ -22,46 +21,63 @@
|
|||
|
||||
const px = size * 4
|
||||
|
||||
const isSafari =
|
||||
// The ios app's wkwebview has no "Safari" token in its user agent, so
|
||||
// detect the engine instead of sniffing for the Safari browser.
|
||||
const isWebkit =
|
||||
typeof navigator !== "undefined" &&
|
||||
/safari/i.test(navigator.userAgent) &&
|
||||
!/chrome|chromium|android/i.test(navigator.userAgent)
|
||||
/applewebkit/i.test(navigator.userAgent) &&
|
||||
!/chrome|chromium|android|firefox/i.test(navigator.userAgent)
|
||||
|
||||
// Strip any query string/fragment - hosted icons are often served with one.
|
||||
const isRemoteSvg = (value: string) =>
|
||||
!value.startsWith("data:") && /\.svg$/i.test(value.split(/[?#]/)[0]!)
|
||||
|
||||
let canceled = false
|
||||
let objectUrl = $state(maybe<string>())
|
||||
|
||||
const src = $derived(objectUrl || icon)
|
||||
|
||||
// Primal issues 302 redirects from blossom, which messes up safari
|
||||
const fetchSvg = async () => {
|
||||
// Primal issues 302 redirects from blossom, which breaks mask-image on webkit.
|
||||
const fetchSvg = async (url: string) => {
|
||||
try {
|
||||
const response = await fetch(icon, {
|
||||
const response = await fetch(url, {
|
||||
mode: "cors",
|
||||
credentials: "omit",
|
||||
})
|
||||
|
||||
if (response.ok) {
|
||||
const blob = await response.blob()
|
||||
|
||||
if (!canceled) {
|
||||
objectUrl = URL.createObjectURL(blob)
|
||||
}
|
||||
return URL.createObjectURL(await response.blob())
|
||||
}
|
||||
} catch {
|
||||
// pass
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
if (isSafari && icon.toLowerCase().endsWith(".svg")) {
|
||||
fetchSvg()
|
||||
// Re-fetch when icon changes, revoking the previous blob url.
|
||||
$effect(() => {
|
||||
const url = icon
|
||||
|
||||
let canceled = false
|
||||
let created: string | undefined
|
||||
|
||||
if (isWebkit && isRemoteSvg(url)) {
|
||||
fetchSvg(url).then(blobUrl => {
|
||||
if (!blobUrl) return
|
||||
|
||||
if (canceled) {
|
||||
URL.revokeObjectURL(blobUrl)
|
||||
} else {
|
||||
created = blobUrl
|
||||
objectUrl = blobUrl
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return () => {
|
||||
canceled = true
|
||||
|
||||
if (objectUrl) {
|
||||
URL.revokeObjectURL(objectUrl)
|
||||
if (created) {
|
||||
URL.revokeObjectURL(created)
|
||||
objectUrl = undefined
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue