Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added echo/frontend/src/assets/audio-alert.opus
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { useDisclosure, useLocalStorage, useWindowEvent } from "@mantine/hooks";
import * as Sentry from "@sentry/react";
import {
IconAlertTriangle,
IconCheck,
IconMicrophone,
IconPlayerPause,
Expand Down Expand Up @@ -523,35 +524,25 @@ export const ParticipantConversationAudio = () => {
overlayProps={{
color: "#FF9AA2",
}}
role="alertdialog"
aria-live="assertive"
aria-atomic="true"
>
<Stack gap="md">
<Text fw={600} size="lg">
<Trans id="participant.modal.interruption.title">
Recording interrupted
</Trans>
</Text>
<Group gap="xs">
<IconAlertTriangle size={24} color="#FF9AA2" />
<Text fw={600} size="lg">
<Trans id="participant.modal.interruption.title">
Recording interrupted
</Trans>
</Text>
<IconAlertTriangle size={24} color="#FF9AA2" />
</Group>
<Text>
{(() => {
const savedDuration = Math.max(
0,
interruptionRecordingTimeRef.current - 60,
);
const hours = Math.floor(savedDuration / 3600);
const minutes = Math.floor((savedDuration % 3600) / 60);
const seconds = savedDuration % 60;
const formattedDuration =
hours > 0
? `${hours.toString().padStart(2, "0")}:${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`
: `${minutes.toString().padStart(2, "0")}:${seconds.toString().padStart(2, "0")}`;
return (
<Trans id="participant.modal.interruption.issue.description">
We saved your recording up to{" "}
<strong>{formattedDuration}</strong> but lost the last 60
seconds or so. <br /> Press below to reconnect, then hit the
record button to continue.
</Trans>
);
})()}
<Trans id="participant.modal.interruption.issue.message">
Attention! We lost the last 60 seconds or so of your recording due
to some interruption. Please press the button below to reconnect.
</Trans>
</Text>

{/* Uploading indicator - same pattern as StopRecordingConfirmationModal */}
Expand All @@ -572,7 +563,7 @@ export const ParticipantConversationAudio = () => {
disabled={isReconnecting || uploadChunkMutation.isPending}
fullWidth
radius="md"
size="md"
size="xl"
>
<Trans id="participant.button.interruption.reconnect">
Reconnect
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useCallback, useEffect, useRef, useState } from "react";
import audioAlertSound from "@/assets/audio-alert.opus";

// Minimum chunk size in bytes - chunks smaller than this are considered suspicious
const MIN_CHUNK_SIZE_BYTES = 1024; // 1KB
Expand Down Expand Up @@ -170,52 +171,13 @@ const useChunkedAudioRecorder = ({
hadConsecutiveSuspiciousChunksRef.current = true;
hasCalledInterruptionCallbackRef.current = true;

// notification sound for interruption
// Play notification sound for interruption
try {
const audioContext = new (
window.AudioContext || (window as any).webkitAudioContext
)();

// First tone - louder and longer
const oscillator1 = audioContext.createOscillator();
const gainNode1 = audioContext.createGain();
oscillator1.connect(gainNode1);
gainNode1.connect(audioContext.destination);

oscillator1.frequency.value = 800;
gainNode1.gain.value = 0.6; // Much louder

oscillator1.start(audioContext.currentTime);
oscillator1.stop(audioContext.currentTime + 0.35);

// Second tone
const oscillator2 = audioContext.createOscillator();
const gainNode2 = audioContext.createGain();
oscillator2.connect(gainNode2);
gainNode2.connect(audioContext.destination);

oscillator2.frequency.value = 600;
gainNode2.gain.value = 0.6; // Much louder

oscillator2.start(audioContext.currentTime + 0.35);
oscillator2.stop(audioContext.currentTime + 0.7);

// Third tone for emphasis
const oscillator3 = audioContext.createOscillator();
const gainNode3 = audioContext.createGain();
oscillator3.connect(gainNode3);
gainNode3.connect(audioContext.destination);

oscillator3.frequency.value = 700;
gainNode3.gain.value = 0.6;

oscillator3.start(audioContext.currentTime + 0.7);
oscillator3.stop(audioContext.currentTime + 1.05);

// Clean up after sound completes
setTimeout(() => {
audioContext.close();
}, 1200);
const audio = new Audio(audioAlertSound);
audio.volume = 1.0;
audio.play().catch((error) => {
console.error("Failed to play notification sound:", error);
});
} catch (error) {
console.error("Failed to play notification sound:", error);
}
Expand Down
55 changes: 30 additions & 25 deletions echo/frontend/src/locales/de-DE.po
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ msgstr "Willkommen zurück"
#~ msgid "select.all.modal.skip.reason"
#~ msgstr "einige könnten aufgrund von leerem Transkript oder Kontextlimit übersprungen werden"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:547
#~ msgid "participant.modal.interruption.issue.description"
#~ msgstr "Wir haben deine Aufnahme bis <0>{formattedDuration}</0> gespeichert, aber den Rest leider verloren. <1/> Drücke unten, um dich erneut zu verbinden, und dann auf Aufnahme, um fortzufahren."

#. js-lingui-explicit-id
#: src/routes/project/library/ProjectLibrary.tsx:238
msgid "library.generate.duration.message"
Expand All @@ -91,17 +96,17 @@ msgstr " Von Benachrichtigungen abmelden"
#~ msgstr "-5s"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:435
#: src/components/participant/ParticipantConversationAudio.tsx:436
msgid "participant.modal.refine.info.title.go.deeper"
msgstr "Tiefer eintauchen"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:428
#: src/components/participant/ParticipantConversationAudio.tsx:429
msgid "participant.modal.refine.info.title.concrete"
msgstr "Konkret machen"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:421
#: src/components/participant/ParticipantConversationAudio.tsx:422
msgid "participant.modal.refine.info.title.generic"
msgstr "\"Verfeinern\" bald verfügbar"

Expand Down Expand Up @@ -547,6 +552,11 @@ msgstr "Aspekte"
msgid "At least one topic must be selected to enable Make it concrete"
msgstr "Wähle mindestens ein Thema, um Konkret machen zu aktivieren"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:539
msgid "participant.modal.interruption.issue.message"
msgstr "Achtung! Wir haben die letzten 60 Sekunden Ihrer Aufnahme aufgrund einer Unterbrechung verloren. Bitte drücken Sie die Schaltfläche unten, um die Verbindung wiederherzustellen."

#~ msgid "Audio Processing In Progress"
#~ msgstr "Audioverarbeitung wird durchgeführt"

Expand Down Expand Up @@ -1525,7 +1535,7 @@ msgstr "Fehler beim Aktivieren des Automatischen Auswählens für diesen Chat"
#~ msgid "Failed to finish conversation. Please try again or start a new conversation."
#~ msgstr "Fehler beim Beenden des Gesprächs. Bitte versuchen Sie es erneut oder starten Sie ein neues Gespräch."

#: src/components/participant/ParticipantConversationAudio.tsx:271
#: src/components/participant/ParticipantConversationAudio.tsx:272
msgid "Failed to finish conversation. Please try again."
msgstr "Fehler beim Beenden des Gesprächs. Bitte versuchen Sie es erneut."

Expand Down Expand Up @@ -1564,7 +1574,7 @@ msgstr "Fehler beim Markieren aller Ankündigungen als gelesen"
msgid "Failed to mark announcement as read"
msgstr "Fehler beim Markieren der Ankündigung als gelesen"

#: src/components/participant/ParticipantConversationAudio.tsx:365
#: src/components/participant/ParticipantConversationAudio.tsx:366
msgid "Failed to reconnect. Please try reloading the page."
msgstr "Verbindung fehlgeschlagen. Bitte versuche, die Seite neu zu laden."

Expand Down Expand Up @@ -1597,15 +1607,15 @@ msgstr "Artefakt konnte nicht überarbeitet werden. Bitte versuchen Sie es erneu
#~ msgid "Failed to start new conversation. Please try again."
#~ msgstr "Fehler beim Starten eines neuen Gesprächs. Bitte versuchen Sie es erneut."

#: src/components/participant/ParticipantConversationAudio.tsx:171
#: src/components/participant/ParticipantConversationAudio.tsx:172
msgid "Failed to stop recording on device change. Please try again."
msgstr "Fehler beim Beenden der Aufnahme bei Änderung des Mikrofons. Bitte versuchen Sie es erneut."

#~ msgid "Failed to verify email status. Please try again."
#~ msgstr "E-Mail-Status konnte nicht überprüft werden. Bitte versuchen Sie es erneut."

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:441
#: src/components/participant/ParticipantConversationAudio.tsx:442
msgid "participant.modal.refine.info.title"
msgstr "Funktion bald verfügbar"

Expand Down Expand Up @@ -1668,7 +1678,7 @@ msgid "participant.button.finish.text.mode"
msgstr "Beenden"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:693
#: src/components/participant/ParticipantConversationAudio.tsx:681
msgid "participant.button.finish"
msgstr "Beenden"

Expand Down Expand Up @@ -1734,7 +1744,7 @@ msgstr "Zusammenfassung wird erstellt. Kurz warten ..."
msgid "German"
msgstr "Deutsch"

#: src/components/participant/ParticipantConversationAudio.tsx:413
#: src/components/participant/ParticipantConversationAudio.tsx:414
msgid "Get an immediate reply from Dembrane to help you deepen the conversation."
msgstr "Erhalte eine sofortige Antwort von Dembrane, um das Gespräch zu vertiefen."

Expand Down Expand Up @@ -1836,7 +1846,7 @@ msgstr ""
"* Wie sieht Erfolg aus"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:507
#: src/components/participant/ParticipantConversationAudio.tsx:508
msgid "participant.button.i.understand"
msgstr "Ich verstehe"

Expand Down Expand Up @@ -2913,12 +2923,12 @@ msgid "Recommended apps"
msgstr "Empfohlene Apps"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:577
#: src/components/participant/ParticipantConversationAudio.tsx:565
msgid "participant.button.interruption.reconnect"
msgstr "Erneut verbinden"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:673
#: src/components/participant/ParticipantConversationAudio.tsx:661
msgid "participant.button.record"
msgstr "Aufnehmen"

Expand All @@ -2930,7 +2940,7 @@ msgid "Record another conversation"
msgstr "Ein weiteres Gespräch aufnehmen"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:529
#: src/components/participant/ParticipantConversationAudio.tsx:532
msgid "participant.modal.interruption.title"
msgstr "Aufnahme unterbrochen"

Expand Down Expand Up @@ -2959,7 +2969,7 @@ msgid "References"
msgstr "Referenzen"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:724
#: src/components/participant/ParticipantConversationAudio.tsx:712
msgid "participant.button.refine"
msgstr "Verfeinern"

Expand Down Expand Up @@ -3601,7 +3611,7 @@ msgid "Stop"
msgstr "Stopp"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:743
#: src/components/participant/ParticipantConversationAudio.tsx:731
msgid "participant.button.stop"
msgstr "Beenden"

Expand Down Expand Up @@ -3686,11 +3696,11 @@ msgstr "System"
msgid "Tags"
msgstr "Tags"

#: src/components/participant/ParticipantConversationAudio.tsx:407
#: src/components/participant/ParticipantConversationAudio.tsx:408
msgid "Take some time to create an outcome that makes your contribution concrete or get an immediate reply from Dembrane to help you deepen the conversation."
msgstr "Nimm dir Zeit, ein konkretes Ergebnis zu erstellen, das deinen Beitrag festhält, oder erhalte eine sofortige Antwort von Dembrane, um das Gespräch zu vertiefen."

#: src/components/participant/ParticipantConversationAudio.tsx:410
#: src/components/participant/ParticipantConversationAudio.tsx:411
msgid "Take some time to create an outcome that makes your contribution concrete."
msgstr "Nimm dir Zeit, ein konkretes Ergebnis zu erstellen, das deinen Beitrag festhält."

Expand Down Expand Up @@ -3849,7 +3859,7 @@ msgstr "Diese E-Mail ist bereits in der Liste."
#~ msgstr "Diese E-Mail ist bereits für Benachrichtigungen angemeldet."

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:497
#: src/components/participant/ParticipantConversationAudio.tsx:498
msgid "participant.modal.refine.info.available.in"
msgstr "Diese Funktion wird in {remainingTime} Sekunden verfügbar sein."

Expand Down Expand Up @@ -4243,7 +4253,7 @@ msgid "participant.modal.uploading"
msgstr "Audio wird hochgeladen..."

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:562
#: src/components/participant/ParticipantConversationAudio.tsx:550
msgid "participant.modal.interruption.uploading"
msgstr "Audio wird hochgeladen..."

Expand Down Expand Up @@ -4377,15 +4387,10 @@ msgstr "Wir haben Ihnen eine E-Mail mit den nächsten Schritten gesendet. Wenn S
#~ msgstr "Wir haben Ihnen eine E-Mail mit den nächsten Schritten gesendet. Wenn Sie sie nicht sehen, überprüfen Sie Ihren Spam-Ordner. Wenn Sie sie immer noch nicht sehen, kontaktieren Sie bitte jules@dembrane.com"

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:449
#: src/components/participant/ParticipantConversationAudio.tsx:450
msgid "participant.modal.refine.info.reason"
msgstr "Wir brauchen etwas mehr Kontext, um dir effektiv beim Verfeinern zu helfen. Bitte nimm weiter auf, damit wir dir bessere Vorschläge geben können."

#. js-lingui-explicit-id
#: src/components/participant/ParticipantConversationAudio.tsx:547
msgid "participant.modal.interruption.issue.description"
msgstr "Wir haben deine Aufnahme bis <0>{formattedDuration}</0> gespeichert, aber den Rest leider verloren. <1/> Drücke unten, um dich erneut zu verbinden, und dann auf Aufnahme, um fortzufahren."

#: src/routes/participant/ParticipantPostConversation.tsx:252
msgid "We will only send you a message if your host generates a report, we never share your details with anyone. You can opt out at any time."
msgstr "Wir werden Ihnen nur eine Nachricht senden, wenn Ihr Gastgeber einen Bericht erstellt. Wir geben Ihre Daten niemals an Dritte weiter. Sie können sich jederzeit abmelden."
Expand Down
2 changes: 1 addition & 1 deletion echo/frontend/src/locales/de-DE.ts

Large diffs are not rendered by default.

Loading
Loading