diff --git a/nobilis b/nobilis
index dfda74d..4e3c65d 160000
--- a/nobilis
+++ b/nobilis
@@ -1 +1 @@
-Subproject commit dfda74d1e4e2437a5027d0c62246129068f0d98d
+Subproject commit 4e3c65dcfe02bf985048d65c2ecd69705eaec38e
diff --git a/src/main/notifications.ts b/src/main/notifications.ts
index bd30b08..385484a 100644
--- a/src/main/notifications.ts
+++ b/src/main/notifications.ts
@@ -159,6 +159,14 @@ export class Notifier {
if (starts(0x52, 0x49, 0x46, 0x46) && bytes.subarray(8, 12).toString() === 'WEBP') {
return 'image/webp'
}
+ // ISO-BMFF: AVIF and HEIC share the ftyp box four bytes in and are told
+ // apart by the brand after it. Only avif is claimed here - Chromium
+ // decodes that one and does not decode HEIC, so calling a HEIC file by
+ // its real name would promise a picture that never appears.
+ if (bytes.subarray(4, 8).toString() === 'ftyp') {
+ const brand = bytes.subarray(8, 12).toString()
+ if (brand === 'avif' || brand === 'avis') return 'image/avif'
+ }
// Something else entirely. Chromium sniffs the bytes of an either
// way, so a wrong-but-plausible type still decodes what it can, and what
// it cannot decode falls out of the null below rather than here.
diff --git a/src/renderer/src/components/MediaEmbed.tsx b/src/renderer/src/components/MediaEmbed.tsx
index dccabc7..fde12eb 100644
--- a/src/renderer/src/components/MediaEmbed.tsx
+++ b/src/renderer/src/components/MediaEmbed.tsx
@@ -225,7 +225,7 @@ export function MediaEmbed({
// Browsers give no pause control over an animated GIF, so "don't autoplay"
// is expressed by not loading it until asked.
const animated =
- attachment?.mimetype === 'image/gif' || /\.(gif|webp)(\?\S*)?$/i.test(fullSrc)
+ attachment?.mimetype === 'image/gif' || /\.(gif|webp|avif)(\?\S*)?$/i.test(fullSrc)
if (animated && !autoplay && !playing) {
return (