hydration mismatch warning

This commit is contained in:
Igor Loskutov
2025-06-17 12:53:19 -04:00
parent 7bb2962f94
commit b85338754e
6 changed files with 11270 additions and 7714 deletions

4
.gitignore vendored
View File

@@ -7,4 +7,6 @@ server/exportdanswer
dump.rdb dump.rdb
.yarn .yarn
ngrok.log ngrok.log
.claude/settings.local.json .claude/settings.local.json
restart-dev.sh
backend-output.log

View File

@@ -389,4 +389,8 @@ alembic upgrade head
- **Audio file backup** before deletion (configurable) - **Audio file backup** before deletion (configurable)
- **Legal review** of consent language and timing - **Legal review** of consent language and timing
This plan maintains backward compatibility while implementing the new consent flow without interrupting core recording functionality. This plan maintains backward compatibility while implementing the new consent flow without interrupting core recording functionality.
## Extra notes
Room creator must not be asked for consent

View File

@@ -38,11 +38,11 @@ services:
web: web:
image: node:18 image: node:18
ports: ports:
- "3000:3000" - "3001:3000"
command: sh -c "yarn install && yarn dev" command: sh -c "yarn install && yarn dev"
restart: unless-stopped restart: unless-stopped
working_dir: /app working_dir: /app
volumes: volumes:
- ./www:/app/ - ./www:/app/
env_file: env_file:
- ./www/.env.local - ./www/.env.development.local

View File

@@ -68,13 +68,13 @@ const TranscriptCreate = () => {
}; };
const send = () => { const send = () => {
if (loadingRecord || createTranscript.loading || permissionDenied) return; if (!isClient || loadingRecord || createTranscript.loading || permissionDenied) return;
setLoadingRecord(true); setLoadingRecord(true);
createTranscript.create({ name, target_language: getTargetLanguage() }); createTranscript.create({ name, target_language: getTargetLanguage() });
}; };
const uploadFile = () => { const uploadFile = () => {
if (loadingUpload || createTranscript.loading || permissionDenied) return; if (!isClient || loadingUpload || createTranscript.loading || permissionDenied) return;
setLoadingUpload(true); setLoadingUpload(true);
createTranscript.create({ name, target_language: getTargetLanguage() }); createTranscript.create({ name, target_language: getTargetLanguage() });
}; };
@@ -91,7 +91,7 @@ const TranscriptCreate = () => {
if (createTranscript.error) setLoadingRecord(false); if (createTranscript.error) setLoadingRecord(false);
}, [createTranscript.error]); }, [createTranscript.error]);
const { loading, permissionOk, permissionDenied, requestPermission } = const { loading, permissionOk, permissionDenied, requestPermission, isClient } =
useAudioDevice(); useAudioDevice();
return ( return (
@@ -123,12 +123,12 @@ const TranscriptCreate = () => {
<Text mt={6}> <Text mt={6}>
Reflector is a transcription and summarization pipeline that Reflector is a transcription and summarization pipeline that
transforms audio into knowledge. transforms audio into knowledge.
<Text className="hidden md:block"> <span className="hidden md:block">
The output is meeting minutes and topic summaries enabling {" "}The output is meeting minutes and topic summaries enabling
topic-specific analyses stored in your systems of record. This is topic-specific analyses stored in your systems of record. This is
accomplished on your infrastructure without 3rd parties accomplished on your infrastructure without 3rd parties
keeping your data private, secure, and organized. keeping your data private, secure, and organized.
</Text> </span>
</Text> </Text>
<About buttonText="Learn more" /> <About buttonText="Learn more" />
<Text mt={6}> <Text mt={6}>
@@ -179,29 +179,31 @@ const TranscriptCreate = () => {
placeholder="Choose your language" placeholder="Choose your language"
/> />
</Box> </Box>
{loading ? ( {isClient && !loading ? (
<Text className="">Checking permissions...</Text> permissionOk ? (
) : permissionOk ? ( <Spacer />
<Spacer /> ) : permissionDenied ? (
) : permissionDenied ? ( <Text className="">
<Text className=""> Permission to use your microphone was denied, please change
Permission to use your microphone was denied, please change the permission setting in your browser and refresh this
the permission setting in your browser and refresh this page.
page. </Text>
</Text> ) : (
<Button
colorScheme="whiteAlpha"
onClick={requestPermission}
disabled={permissionDenied}
>
Request Microphone Permission
</Button>
)
) : ( ) : (
<Button <Text className="">Checking permissions...</Text>
colorScheme="whiteAlpha"
onClick={requestPermission}
disabled={permissionDenied}
>
Request Microphone Permission
</Button>
)} )}
<Button <Button
colorScheme="whiteAlpha" colorScheme="whiteAlpha"
onClick={send} onClick={send}
isDisabled={!permissionOk || loadingRecord || loadingUpload} isDisabled={!isClient || !permissionOk || loadingRecord || loadingUpload}
mt={2} mt={2}
> >
{loadingRecord ? "Loading..." : "Record Meeting"} {loadingRecord ? "Loading..." : "Record Meeting"}

View File

@@ -9,8 +9,10 @@ const useAudioDevice = () => {
const [permissionDenied, setPermissionDenied] = useState<boolean>(false); const [permissionDenied, setPermissionDenied] = useState<boolean>(false);
const [audioDevices, setAudioDevices] = useState<Option[]>([]); const [audioDevices, setAudioDevices] = useState<Option[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [isClient, setIsClient] = useState(false);
useEffect(() => { useEffect(() => {
setIsClient(true);
checkPermission(); checkPermission();
}, []); }, []);
@@ -21,6 +23,12 @@ const useAudioDevice = () => {
}, [permissionOk]); }, [permissionOk]);
const checkPermission = (): void => { const checkPermission = (): void => {
// Skip on server-side rendering
if (typeof window === "undefined" || !navigator) {
setLoading(false);
return;
}
if (navigator.userAgent.includes("Firefox")) { if (navigator.userAgent.includes("Firefox")) {
navigator.mediaDevices navigator.mediaDevices
.getUserMedia({ audio: true, video: false }) .getUserMedia({ audio: true, video: false })
@@ -124,6 +132,7 @@ const useAudioDevice = () => {
audioDevices, audioDevices,
getAudioStream, getAudioStream,
requestPermission, requestPermission,
isClient,
}; };
}; };

File diff suppressed because it is too large Load Diff