-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement artist image loading with error handling and PWA caching
- Add react-error-boundary for robust image loading - Create ArtistImage component with suspense and error handling - Implement image preloading in PWA service worker - Add runtime caching for Appwrite storage assets - Refactor image loading logic to use Appwrite storage
- Loading branch information
Showing
12 changed files
with
207 additions
and
33 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { useSuspenseQuery } from "@tanstack/react-query"; | ||
|
||
import { QUERY_KEYS } from "@/lib/QueryKeys"; | ||
import { getArtistImage } from "@/lib/images"; | ||
|
||
export const ArtistImage = ({ | ||
userId, | ||
name, | ||
}: { | ||
userId: string; | ||
name: string; | ||
}) => { | ||
const { data: imageSrc } = useSuspenseQuery({ | ||
queryKey: [QUERY_KEYS.ARTIST_IMAGE, userId], | ||
queryFn: () => getArtistImage(userId), | ||
retry: 2, | ||
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000), // bon ok ça c'est du copilot | ||
staleTime: 5 * 60 * 1000, // 5 minutes | ||
gcTime: 10 * 60 * 1000, // 10 minutes | ||
}); | ||
|
||
if (!imageSrc) return null; | ||
|
||
return ( | ||
<img | ||
src={imageSrc} | ||
alt={name} | ||
className={"w-32 rounded-full border-8 border-secondary"} | ||
/> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,23 @@ | ||
export const images = import.meta.glob("/src/assets/avatars/*.jpg", { | ||
eager: true, | ||
import: "default", | ||
}) as Record<string, string>; | ||
import * as Sentry from "@sentry/react"; | ||
|
||
export const imagePrefix = "/src/assets/avatars/"; | ||
import { storage } from "./appwrite"; | ||
import { assetsBucketId } from "./consts"; | ||
import { getStandists } from "./hooks/useStandists"; | ||
import { Standist } from "./models/Standist"; | ||
|
||
export const getArtistImage = async (standistId: string) => { | ||
try { | ||
const standists = await getStandists(); | ||
const standist = standists.find( | ||
(standist: Standist) => standist.userId === standistId, | ||
); | ||
if (!standist?.image || standist?.image == "fallback") | ||
throw new Error("No image found for standist " + standistId); | ||
return storage.getFileDownload(assetsBucketId, standist?.image); | ||
} catch (error) { | ||
console.error("Failed to load artist image:", error); | ||
// ça devrait jamais arriver hein... n'est-ce pas ? | ||
Sentry.captureException(error); // au cas où | ||
return "https://www.shutterstock.com/image-vector/default-avatar-profile-icon-social-600nw-1906669723.jpg"; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters