Skip to content

Commit

Permalink
Proper async loading of provider images
Browse files Browse the repository at this point in the history
  • Loading branch information
fjsj committed Jan 8, 2025
1 parent 75b493b commit 85a3556
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 31 deletions.
11 changes: 1 addition & 10 deletions app/(app)/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useMedplum } from "@medplum/react-hooks";
import { useRouter } from "expo-router";
import { useCallback, useEffect, useState } from "react";
import { useCallback, useState } from "react";
import { SafeAreaView } from "react-native-safe-area-context";

import { CreateThreadModal } from "@/components/CreateThreadModal";
Expand All @@ -20,15 +20,6 @@ export default function Index() {
router.replace("/sign-in");
}, [medplum, router]);

// When threads are loaded, fetch their image URLs
useEffect(() => {
if (!isLoadingThreads) {
threads.forEach((thread) => {
thread.loadImageURL({ medplum });
});
}
}, [isLoadingThreads, threads, medplum]);

if (isLoadingThreads) {
return (
<SafeAreaView className="flex-1 items-center justify-center">
Expand Down
5 changes: 5 additions & 0 deletions contexts/ChatContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,11 @@ export function ChatProvider({
.sort((a, b) => b.threadOrder - a.threadOrder);
}, [threads, profile, threadCommMap]);

// Whenever threadsOut changes, load the image URL for each thread
useEffect(() => {
threadsOut.forEach((thread) => thread.loadImageURL({ medplum }));
}, [threadsOut, medplum]);

// Current thread memoized
const currentThread = useMemo(() => {
if (!currentThreadId || !profile) return null;
Expand Down
45 changes: 24 additions & 21 deletions models/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ export class ChatMessage {
export class Thread {
readonly messages: ChatMessage[];
readonly originalCommunication: Communication;
static imageURLCache = new Map<string, string>();
imageURL?: string;
static imageURLMap = new Map<string, string>();
static loadImageURLPromiseMap = new Map<string, Promise<void>>();

constructor({
messages,
Expand Down Expand Up @@ -120,27 +120,30 @@ export class Thread {
return this.lastProviderCommunication?.sender?.display;
}

get practitionerId(): string | undefined {
return this.lastProviderCommunication?.sender?.reference;
}

get imageURL(): string | undefined {
return this.practitionerId ? Thread.imageURLMap.get(this.practitionerId) : undefined;
}

async loadImageURL({ medplum }: { medplum: MedplumClient }) {
const practitionerId = this.lastProviderCommunication?.sender?.reference;
if (practitionerId) {
let imageUrl = Thread.imageURLCache.get(practitionerId);

if (!imageUrl) {
try {
const practitioner = await medplum.readReference(
this.lastProviderCommunication?.sender as Reference<Practitioner>,
);
if (practitioner.photo?.[0]?.url) {
imageUrl = practitioner.photo[0].url;
Thread.imageURLCache.set(practitionerId, imageUrl);
}
} catch {
// Ignore errors from fetching practitioner image
}
}
if (imageUrl) {
this.imageURL = imageUrl;
// Load the image URL for the thread if it hasn't been loaded yet and it isn't already loading
if (!this.practitionerId) return;
if (Thread.imageURLMap.has(this.practitionerId)) return;
if (Thread.loadImageURLPromiseMap.has(this.practitionerId)) return;

try {
const practitioner = await medplum.readReference(
this.lastProviderCommunication?.sender as Reference<Practitioner>,
);
if (practitioner.photo?.[0]?.url) {
const imageUrl = practitioner.photo[0].url;
Thread.imageURLMap.set(this.practitionerId, imageUrl);
}
} catch {
// Ignore errors from fetching practitioner image
}
}
}

0 comments on commit 85a3556

Please sign in to comment.