Fix error on message details screen with audio messages

This commit is contained in:
Evan Hahn 2021-03-24 17:06:12 -05:00 committed by GitHub
parent 5f9a75d9f4
commit 77c306843d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 417 additions and 224 deletions

View file

@ -14,15 +14,26 @@ type Contents = {
waveformCache: WaveformCache;
};
export const GlobalAudioContext = React.createContext<Contents | null>(null);
// This context's value is effectively global. This is not ideal but is necessary because
// the app has multiple React roots. In the future, we should use a single React root
// and instantiate these inside of `GlobalAudioProvider`. (We may wish to keep
// `audioContext` global, however, as the browser limits the number that can be
// created.)
const globalContents: Contents = {
audio: new Audio(),
audioContext: new AudioContext(),
waveformCache: new LRU({
max: MAX_WAVEFORM_COUNT,
}),
};
export const GlobalAudioContext = React.createContext<Contents>(globalContents);
export type GlobalAudioProps = {
conversationId: string;
children?: React.ReactNode | React.ReactChildren;
};
const audioContext = new AudioContext();
/**
* A global context that holds Audio, AudioContext, LRU instances that are used
* inside the conversation by ts/components/conversation/MessageAudio.tsx
@ -31,37 +42,15 @@ export const GlobalAudioProvider: React.FC<GlobalAudioProps> = ({
conversationId,
children,
}) => {
const audio = React.useRef<HTMLAudioElement | null>(null);
const waveformCache = React.useRef<WaveformCache | null>(null);
// NOTE: We don't want to construct these values on every re-render hence
// the constructor calls have to be guarded by `if`s.
if (!audio.current) {
audio.current = new Audio();
}
if (!waveformCache.current) {
waveformCache.current = new LRU({
max: MAX_WAVEFORM_COUNT,
});
}
// When moving between conversations - stop audio
React.useEffect(() => {
return () => {
if (audio.current) {
audio.current.pause();
}
globalContents.audio.pause();
};
}, [conversationId]);
const value = {
audio: audio.current,
audioContext,
waveformCache: waveformCache.current,
};
return (
<GlobalAudioContext.Provider value={value}>
<GlobalAudioContext.Provider value={globalContents}>
{children}
</GlobalAudioContext.Provider>
);