Skip to content

Commit

Permalink
Merge pull request #4 from Nonhuman-Nonsense/albin
Browse files Browse the repository at this point in the history
Albin
  • Loading branch information
albin-karlsson authored Apr 20, 2024
2 parents cfb1c9e + a3e019e commit c80afc5
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 59 deletions.
37 changes: 34 additions & 3 deletions client/src/components/AudioOutput.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,38 @@
import React from "react";
// In the AudioOutput component
import React, { useEffect, useRef } from "react";

function AudioOutput() {
return <></>;
function AudioOutput({ currentAudioMessage }) {
const audioRef = useRef(null);

useEffect(() => {
if (currentAudioMessage) {
console.log(
"Creating blob with ArrayBuffer of size:",
currentAudioMessage.audio.byteLength
);
const blob = new Blob([currentAudioMessage.audio], { type: "audio/mp3" });
const url = URL.createObjectURL(blob);
console.log("Blob URL:", url); // Check the generated URL
audioRef.current.src = url;
audioRef.current
.play()
.catch((err) => console.error("Error playing audio:", err));

return () => {
console.log("Revoking URL:", url);
URL.revokeObjectURL(url);
};
}
}, [currentAudioMessage]);

return (
<audio
ref={audioRef}
controls
autoPlay
onLoadedData={() => console.log("Audio loaded")}
/>
);
}

export default AudioOutput;
15 changes: 12 additions & 3 deletions client/src/components/Contact.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ import React from "react";
function Contact() {
return (
<div className="wrapper">
<div className="text-container" style={{ justifyContent: "center" }}>
<div
className="text-container"
style={{ justifyContent: "center" }}
>
<h4>
The project is an initiative by art & design
<br /> collective Nonhuman Nonsense developed in
Expand All @@ -18,11 +21,17 @@ function Contact() {
@nonhuman-nonsense
</a>
<br />
<a className="link" href="https://nonhuman-nonsense.com">
<a
className="link"
href="https://nonhuman-nonsense.com"
>
nonhuman-nonsense.com
</a>
<br />
<a className="link" href="mailto:[email protected]">
<a
className="link"
href="mailto:[email protected]"
>
[email protected]
</a>
</h4>
Expand Down
25 changes: 18 additions & 7 deletions client/src/components/Council.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function Council({ options }) {
const [activeOverlay, setActiveOverlay] = useState("");
const { width: screenWidth } = useWindowSize();
const [conversation, setConversation] = useState([]); // State to store conversation updates
const [audioMessages, setAudioMessages] = useState([]); // To store multiple ArrayBuffers
const socketRef = useRef(null); // Using useRef to persist socket instance

const foodsContainerStyle = {
Expand All @@ -33,26 +34,33 @@ function Council({ options }) {
useEffect(() => {
socketRef.current = io();

// Send initial data to start the conversation
let promptsAndOptions = {
options: {
...globalOptions,
humanName: humanName,
humanName,
raiseHandPrompt: false,
neverMindPrompt: false,
},
name: "New room",
topic: topic,
topic,
characters: foods,
};

socketRef.current.emit("start_conversation", promptsAndOptions);

// Listen for conversation updates
// Listen for conversation text updates
socketRef.current.on("conversation_update", (message) => {
setConversation((prev) => [...prev, message]); // Update conversation state
setConversation((prev) => [...prev, message]);
});

// Listen for audio updates
socketRef.current.on("audio_update", (audioMessage) => {
setAudioMessages((prevAudioMessages) => [
...prevAudioMessages,
audioMessage,
]);
});

// Cleanup on component unmount
return () => {
socketRef.current.disconnect();
};
Expand Down Expand Up @@ -108,7 +116,10 @@ function Council({ options }) {
className="text-container"
style={{ justifyContent: "end" }}
>
<Output conversation={conversation} />
<Output
conversation={conversation}
audioMessages={audioMessages}
/>
</div>
)}
<div style={foodsContainerStyle}>
Expand Down
92 changes: 46 additions & 46 deletions client/src/components/Output.jsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,75 @@
import React, { useState, useEffect } from "react";
import TextOutput from "./TextOutput";
import AudioOutput from "./AudioOutput";
import ConversationControls from "./ConversationControls";

function Output({ conversation }) {
function Output({ conversation, audioMessages }) {
const [currentMessageIndex, setCurrentMessageIndex] = useState(0);
const [currentSnippetIndex, setCurrentSnippetIndex] = useState(0);
const [currentMessageTextSnippet, setCurrentMessageTextSnippet] =
useState("");
const [initialize, setInitialize] = useState(true); // Flag to control initialization
const [isPaused, setIsPaused] = useState(false);

// Function to calculate the display time based on text length
const calculateDisplayTime = (text) => Math.max(3, text.length * 0.05);
useEffect(() => {
console.log("Audio buffers length:", audioMessages.length);
console.log("Current audio buffer index:", currentMessageIndex);
}, [audioMessages, currentMessageIndex]);

function handlePauseResume() {
if (!isPaused) {
console.log("Pausing");
} else {
console.log("Resuming");
}
useEffect(() => {
if (conversation.length > 0 && !isPaused) {
const snippets =
conversation[currentMessageIndex].text.split(/(?<=\.\s)/);
if (snippets.length > currentSnippetIndex) {
setCurrentMessageTextSnippet(snippets[currentSnippetIndex]);
const timeout = setTimeout(() => {
if (currentSnippetIndex < snippets.length - 1) {
setCurrentSnippetIndex(currentSnippetIndex + 1);
} else if (currentMessageIndex < conversation.length - 1) {
setCurrentMessageIndex(currentMessageIndex + 1);
setCurrentSnippetIndex(0);
}
}, calculateDisplayTime(snippets[currentSnippetIndex]) * 1000);

setIsPaused(!isPaused);
}
return () => clearTimeout(timeout); // Cleanup timeout on unmount or dependency change
}
}
}, [currentMessageIndex, currentSnippetIndex, conversation, isPaused]); // Include isPaused in dependencies

function handleSkipForward() {
// TODO: See if last message before skipping forward
const calculateDisplayTime = (text) => Math.max(3, text.length * 0.065);

console.log("Skipping forward");
function handlePauseResume() {
setIsPaused(!isPaused); // Toggle pause state
}

useEffect(() => {
if (initialize && conversation.length > 0) {
setCurrentMessageIndex(0);
setCurrentSnippetIndex(0);
setInitialize(false); // Reset initialization flag after first setup
}
}, [conversation, initialize]);

useEffect(() => {
const processSnippets = () => {
if (conversation.length > currentMessageIndex) {
const snippets =
conversation[currentMessageIndex].text.split(/(?<=\.\s)/);
if (snippets.length > currentSnippetIndex) {
setCurrentMessageTextSnippet(snippets[currentSnippetIndex]);
const timeout = setTimeout(() => {
if (currentSnippetIndex < snippets.length - 1) {
setCurrentSnippetIndex(currentSnippetIndex + 1);
} else if (currentMessageIndex < conversation.length - 1) {
setCurrentMessageIndex(currentMessageIndex + 1);
setCurrentSnippetIndex(0);
}
}, calculateDisplayTime(snippets[currentSnippetIndex]) * 1000);
return () => clearTimeout(timeout);
}
function handleSkipForward() {
if (conversation.length > currentMessageIndex) {
const snippets =
conversation[currentMessageIndex].text.split(/(?<=\.\s)/);
if (currentSnippetIndex < snippets.length - 1) {
// Move to the next snippet within the same message
setCurrentSnippetIndex(currentSnippetIndex + 1);
} else if (currentMessageIndex < conversation.length - 1) {
// Move to the first snippet of the next message
setCurrentMessageIndex(currentMessageIndex + 1);
setCurrentSnippetIndex(0);
}
};

processSnippets();
}, [currentMessageIndex, currentSnippetIndex, conversation]);
}
}

return (
<div>
<div style={{ textAlign: "center", width: "75%" }}>
<h2>
Speaker:{" "}
{conversation.length > 0
? conversation[currentMessageIndex].speaker
: ""}
</h2>
<TextOutput currentMessageTextSnippet={currentMessageTextSnippet} />
<AudioOutput />
<AudioOutput
currentAudioMessage={audioMessages.find(
(a) => a.message_index == currentMessageIndex
)}
/>
<ConversationControls
isPaused={isPaused}
onPauseResume={handlePauseResume}
Expand Down

0 comments on commit c80afc5

Please sign in to comment.