From 58e083c8798bc91735efa39018f1e2dbf8ad7ba0 Mon Sep 17 00:00:00 2001
From: Robbe Van Petegem <robbe@vanpetegem.me>
Date: Mon, 25 Jan 2021 19:02:41 +0100
Subject: [PATCH] Provide image fallback if image is unavailable

---
 src/components/AlbumCard.vue  | 24 ++++++++++++++++++++++--
 src/components/ArtistCard.vue | 24 ++++++++++++++++++++++--
 src/views/albums/Album.vue    | 26 ++++++++++++++++++++++++--
 src/views/artists/Artist.vue  | 26 ++++++++++++++++++++++++--
 4 files changed, 92 insertions(+), 8 deletions(-)

diff --git a/src/components/AlbumCard.vue b/src/components/AlbumCard.vue
index 912f258d..9df3f1bc 100644
--- a/src/components/AlbumCard.vue
+++ b/src/components/AlbumCard.vue
@@ -1,7 +1,17 @@
 <template>
   <VCard :to="{ name: 'album', params: { id: album.id } }">
-    <VImg :aspect-ratio="1" :src="album.image500" v-if="album.image500" />
-    <VImg :aspect-ratio="1" :src="album.image" v-else-if="album.image" />
+    <VImg
+      :aspect-ratio="1"
+      :src="album.image500"
+      v-if="album.image500 && !imageUnavailable"
+      @error="setImageUnavailable"
+    />
+    <VImg
+      :aspect-ratio="1"
+      :src="album.image"
+      v-else-if="album.image && !imageUnavailable"
+      @error="setImageUnavailable"
+    />
     <VImg
       :aspect-ratio="1"
       :src="require('@mdi/svg/svg/album.svg')"
@@ -45,6 +55,11 @@ export default {
       required: false,
     },
   },
+  data() {
+    return {
+      imageUnavailable: false,
+    };
+  },
   computed: {
     catalogueNumber() {
       if (this.labelForCatNr) {
@@ -63,5 +78,10 @@ export default {
       return full_title;
     },
   },
+  methods: {
+    setImageUnavailable() {
+      this.imageUnavailable = true;
+    },
+  },
 };
 </script>
diff --git a/src/components/ArtistCard.vue b/src/components/ArtistCard.vue
index b0c0b17c..b973050a 100644
--- a/src/components/ArtistCard.vue
+++ b/src/components/ArtistCard.vue
@@ -1,7 +1,17 @@
 <template>
   <VCard :to="{ name: 'artist', params: { id: artist.id } }">
-    <VImg :aspect-ratio="1" :src="artist.image500" v-if="artist.image500" />
-    <VImg :aspect-ratio="1" :src="artist.image" v-else-if="artist.image" />
+    <VImg
+      :aspect-ratio="1"
+      :src="artist.image500"
+      v-if="artist.image500 && !imageUnavailable"
+      @error="setImageUnavailable"
+    />
+    <VImg
+      :aspect-ratio="1"
+      :src="artist.image"
+      v-else-if="artist.image"
+      @error="setImageUnavailable"
+    />
     <VImg
       :aspect-ratio="1"
       :src="require('@mdi/svg/svg/account-music.svg')"
@@ -26,5 +36,15 @@ export default {
   props: {
     artist: { type: Object, required: true },
   },
+  data() {
+    return {
+      imageUnavailable: false,
+    };
+  },
+  methods: {
+    setImageUnavailable() {
+      this.imageUnavailable = true;
+    },
+  },
 };
 </script>
diff --git a/src/views/albums/Album.vue b/src/views/albums/Album.vue
index eb897839..76b81d7e 100644
--- a/src/views/albums/Album.vue
+++ b/src/views/albums/Album.vue
@@ -2,10 +2,22 @@
   <VContainer fluid v-if="album">
     <vue-headful :title="album.title + ' | Accentor'" />
     <VRow>
-      <VCol lg="3" md="4" sm="6" v-if="album.image500" cols="12">
+      <VCol
+        lg="3"
+        md="4"
+        sm="6"
+        v-if="album.image500 && !imageUnavailable"
+        cols="12"
+      >
         <VImg :src="album.image500" class="elevation-3" />
       </VCol>
-      <VCol lg="3" md="4" sm="6" v-else-if="album.image" cols="12">
+      <VCol
+        lg="3"
+        md="4"
+        sm="6"
+        v-else-if="album.image && !imageUnavailable"
+        cols="12"
+      >
         <VImg :src="album.image" class="elevation-3" />
       </VCol>
       <VCol lg="9" md="8" sm="6" cols="12">
@@ -58,6 +70,11 @@ import AlbumArtists from "../../components/AlbumArtists";
 export default {
   name: "Album",
   components: { AlbumArtists, TracksTable, AlbumActions },
+  data() {
+    return {
+      imageUnavailable: false,
+    };
+  },
   watch: {
     album: function () {
       if (this.album === undefined) {
@@ -82,5 +99,10 @@ export default {
       );
     },
   },
+  methods: {
+    setImageUnavailable() {
+      this.imageUnavailable = true;
+    },
+  },
 };
 </script>
diff --git a/src/views/artists/Artist.vue b/src/views/artists/Artist.vue
index 5348586c..77a42d2f 100644
--- a/src/views/artists/Artist.vue
+++ b/src/views/artists/Artist.vue
@@ -2,10 +2,22 @@
   <VContainer fluid v-if="artist">
     <vue-headful :title="artist.name + ' | Accentor'" />
     <VRow>
-      <VCol lg="3" md="4" sm="6" v-if="artist.image500" cols="12">
+      <VCol
+        lg="3"
+        md="4"
+        sm="6"
+        v-if="artist.image500 && !imageUnavailable"
+        cols="12"
+      >
         <VImg :src="artist.image500" class="elevation-3" />
       </VCol>
-      <VCol lg="3" md="4" sm="6" v-else-if="artist.image" cols="12">
+      <VCol
+        lg="3"
+        md="4"
+        sm="6"
+        v-else-if="artist.image && !imageUnavailable"
+        cols="12"
+      >
         <VImg :src="artist.image" class="elevation-3" />
       </VCol>
       <VCol lg="9" md="8" sm="6" cols="12">
@@ -55,6 +67,11 @@ export default {
     AlbumCard,
     ArtistActions,
   },
+  data() {
+    return {
+      imageUnavailable: false,
+    };
+  },
   watch: {
     artist: function () {
       if (this.artist === undefined) {
@@ -79,5 +96,10 @@ export default {
       return this.artists[this.$route.params.id];
     },
   },
+  methods: {
+    setImageUnavailable() {
+      this.imageUnavailable = true;
+    },
+  },
 };
 </script>