Skip to content

Commit

Permalink
feat: animations by audio recording status
Browse files Browse the repository at this point in the history
  • Loading branch information
mikejgray committed Dec 22, 2023
1 parent 5d44f6b commit 44fa579
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 10 deletions.
2 changes: 1 addition & 1 deletion neon_iris/models/web_sat.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""API data models for the WebSAT API."""
# NEON AI (TM) SOFTWARE, Software Development Kit & Application Development System
# All trademark and other rights reserved by their respective owners
# Copyright 2008-2021 Neongecko.com Inc.
# Copyright 2008-2024 Neongecko.com Inc.
# BSD-3
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
Expand Down
Empty file removed neon_iris/static/scripts/main.js
Empty file.
20 changes: 20 additions & 0 deletions neon_iris/static/scripts/sprite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
const sprite = document.querySelector(".sprite");

function triggerWake() {
sprite.classList.remove("record", "waiting");
sprite.classList.add("wake");
}

function triggerRecord() {
sprite.classList.remove("wake", "waiting");
sprite.classList.add("record");
}

function triggerWaiting() {
sprite.classList.remove("wake", "record");
sprite.classList.add("waiting");
}

function triggerDone() {
sprite.classList.remove("wake", "record", "waiting");
}
2 changes: 2 additions & 0 deletions neon_iris/static/scripts/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ function submitMessage() {

async function getAIResponse(text = "", recording = "") {
try {
triggerWaiting(); // Trigger waiting animation
const payload =
text !== "" && recording === ""
? { utterance: text }
Expand All @@ -43,6 +44,7 @@ async function getAIResponse(text = "", recording = "") {
// Assuming 'data' contains the AI response in a property named 'reply'
const aiMessage = data.transcription;

triggerDone(); // Trigger done animation
// Add in the user's transcription if STT
if (text === "" && recording !== "") {
const userMessage = createMessageDiv("user", data.utterance);
Expand Down
16 changes: 10 additions & 6 deletions neon_iris/static/scripts/websocket.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,14 @@ async function handleSpeechEnd(audio) {
// Save the spoken audio as a downloadable file
const downloadArea = document.getElementById("download-area");
if (downloadArea) {
downloadArea.innerHTML = "";
const downloadLink = document.createElement("a");
downloadLink.href = audioUrl;
downloadLink.download = "recorded_audio.wav";
downloadLink.textContent = "Download Recorded Audio";
downloadArea.appendChild(downloadLink);
const downloadButton = document.createElement("a");
downloadButton.href = audioUrl;
downloadButton.download = "recorded_audio.wav";
downloadButton.textContent = "Download Recorded Audio";
downloadButton.className = "download-button"; // Add a class for styling
downloadButton.setAttribute("role", "button"); // Accessibility improvement
downloadArea.appendChild(downloadButton);
triggerWaiting(); // Trigger waiting animation
} else {
console.error("Download area not found");
}
Expand Down Expand Up @@ -131,13 +133,15 @@ const WebSocketHandler = (() => {
audio.onended = () => {
console.log("Activation sound is done playing");
if (myVad && !isVadRunning) {
triggerRecord(); // Trigger recording animation
myVad.start();
isVadRunning = true;
} else if (!shouldListen && isVadRunning) {
myVad.pause();
isVadRunning = false;
}
};
triggerWake(); // Trigger wake animation
audio.play();
lastActivationTime = currentTime;
}
Expand Down
61 changes: 61 additions & 0 deletions neon_iris/static/sprite.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/* Base styles for the split sprite */
.sprite {
width: 40px; /* sprite width adjusted to 40px */
height: 40px; /* sprite height adjusted to 40px */
border-radius: 50%;
background-image: linear-gradient(to right, #000 50%, #fff 50%);
box-shadow: 0 0 0 2px #000; /* Adjusted border thickness for smaller size */
transition: transform 0.3s ease, opacity 0.3s ease;
opacity: 0; /* sprite is invisible by default */
position: relative; /* Required for absolute positioning of pseudo-elements */
display: flex; /* Center content */
justify-content: center;
align-items: center;
margin: 20px;
}

/* Pulse animation while recording */
@keyframes pulse {
0%,
100% {
transform: scale(1);
}
50% {
transform: scale(1.1);
}
}

.sprite.record {
animation: pulse 1s infinite ease-in-out;
opacity: 1; /* sprite is visible while recording */
}

/* Spin animation while waiting for a response */
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

.sprite.waiting {
animation: spin 2s infinite linear;
opacity: 1; /* sprite is visible while waiting */
}

/* Appear animation for wake word activation */
@keyframes appear {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}

.sprite.wake {
animation: appear 1s forwards;
opacity: 1; /* sprite is visible when awake */
}
20 changes: 18 additions & 2 deletions neon_iris/static/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@ html {
margin: 0;
padding: 0;
}
img.logo {
width: 40px;
height: 40px;
}
a {
text-decoration: none;
}
a:link {
color: #000;
color: #fff;
border-bottom: 1px solid #ff0000;
}
a:visited {
color: #e600e6;
border-bottom: 1px solid #b3b3b3;
}
a:hover {
color: #2d8653;
color: black;
border-bottom: 1px solid #000099;
}
.button-container {
Expand Down Expand Up @@ -116,6 +120,18 @@ a:hover {
text-align: center;
font-size: 1.5em;
}
.download-button {
display: inline-block;
padding: 10px 20px;
margin: 10px 0;
background-color: #03a9f4;
color: #ffffff;
text-align: center;
text-decoration: none;
border-radius: 5px;
transition: background-color 0.3s;
}

/* Style for user messages */
.user-message {
background-color: #007bff; /* Blue background for user messages */
Expand Down
5 changes: 4 additions & 1 deletion neon_iris/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ title }}</title>
<link rel="stylesheet" href="/static/styles.css" />
<link rel="stylesheet" href="/static/sprite.css" />
</head>
<body>
<div class="chat-container">
<div class="chat-header">
{{ description }} <img src="/static/logo.webp" />
{{ description }} <img src="/static/logo.webp" class="logo" />
</div>
<button id="startButton">Start Recording</button>
<div class="chat-window" id="chatWindow">
Expand All @@ -22,6 +23,7 @@
<div class="input-area">
<input type="text" id="chatInput" placeholder="{{ placeholder }}" />
<button onclick="submitMessage()">Submit</button>
<div class="sprite" />
</div>
</div>
</body>
Expand All @@ -36,4 +38,5 @@
<script src="/static/scripts/websocket.js"></script>
<script src="/static/scripts/audio.js"></script>
<script src="/static/scripts/ui.js"></script>
<script src="/static/scripts/sprite.js"></script>
</html>

0 comments on commit 44fa579

Please sign in to comment.