import { sendAudio } from './session'
import { ipcMain } from "electron";
+import { backgroundMitt } from './emitter';
+
const portAudio = require('naudiodon');
let ai: typeof portAudio.AudioIO | null = null;
const audio = bufSplit(input, 8192);
- // call this fuction after last audio chunk has been written.
+ // Called on end of write.
const callback = () => {
- // TODO: clear portAudio writable buffer on write end.
+
+ // We stop audio playback anim.
+ backgroundMitt.emit('ipc-renderer', {
+ endpoint: 'stop-playback-anim'
+ });
+
}
write();
// check to see if this is a Render Message.
if (m.content) {
+
// If there is audio, play it.
if (m.content.audio) {
const audioBytes = Buffer.from(m.content.audio as string, 'hex');
+ m.content.audio = true;
play(audioBytes);
+ } else {
+ m.content.audio = false;
}
// if there is no unique id, add it.
- if(!m.uid) m.uid = uuidv4();
+ if(!m.uid) m.uid = uuidv4();
}
backgroundMitt.emit('ipc-renderer', {
.pause {
opacity: 1;
&::before {
- -moz-animation: audio1 1.5s infinite ease-in-out;
- -o-animation: audio1 1.5s infinite ease-in-out;
- -webkit-animation: audio1 1.5s infinite ease-in-out;
- animation: audio1 1.5s infinite ease-in-out;
+ -moz-animation: circle1 1.5s infinite ease-in-out;
+ -o-animation: circle1 1.5s infinite ease-in-out;
+ -webkit-animation: circle1 1.5s infinite ease-in-out;
+ animation: circle1 1.5s infinite ease-in-out;
}
&::after {
- -moz-animation: audio2 2.2s infinite ease-in-out;
- -o-animation: audio2 2.2s infinite ease-in-out;
- -webkit-animation: audio2 2.2s infinite ease-in-out;
- animation: audio2 2.2s infinite ease-in-out;
+ -moz-animation: circle2 2.2s infinite ease-in-out;
+ -o-animation: circle2 2.2s infinite ease-in-out;
+ -webkit-animation: circle2 2.2s infinite ease-in-out;
+ animation: circle2 2.2s infinite ease-in-out;
}
}
}
}
-.animate-audio1 {
- -moz-animation: audio1 1.5s infinite ease-in-out;
- -o-animation: audio1 1.5s infinite ease-in-out;
- -webkit-animation: audio1 1.5s infinite ease-in-out;
- animation: audio1 1.5s infinite ease-in-out;
-}
-@keyframes audio1 {
+@keyframes circle1 {
0%,
100% {
box-shadow: 0 0 0 0.4em rgba(195, 195, 195, 0.4);
box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.25);
}
}
-.animate-audio2 {
- -moz-animation: audio2 2.2s infinite ease-in-out;
- -o-animation: audio2 2.2s infinite ease-in-out;
- -webkit-animation: audio2 2.2s infinite ease-in-out;
- animation: audio2 2.2s infinite ease-in-out;
-}
-@keyframes audio2 {
+
+@keyframes circle2 {
0%,
100% {
box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.15);
</div>
<!-- Render Crimata icon or friend's initials. -->
- <div v-if="message.modifier == 'fr'" class="photo">
+ <div v-if="message.modifier == 'fr'" class="photo"
+ :class="{ playing: isPlaying }"
+ >
{{ message.context[0] }}
</div>
<script lang='ts'>
- import {defineComponent} from 'vue';
+ import {defineComponent, ref, onMounted} from 'vue';
export default defineComponent({
name: "MessageItem",
type: Object,
required: true
}
+ },
+
+ setup(props) {
+ let isPlaying = ref(false);
+
+ const onStopPlayback = (e: any) => {
+ window.ipcRenderer.removeAllListeners("stop-playback-anim");
+ isPlaying.value = false
+ }
+
+ onMounted(() => {
+
+ // Turn on audio playback animation if audio.
+ if (props.message.content.audio === true) {
+ window.ipcRenderer.on("stop-playback-anim", onStopPlayback);
+ isPlaying.value = true
+ }
+
+ })
+
+ return {
+ isPlaying
+ }
}
})
animation-duration: 0.25s;
}
+ @keyframes appear {
+ from {
+ transform: scale(0.3);
+ }
+ to {
+ transform: scale(1);
+ }
+ }
+
#aiBubble {
background-color: white;
}
border-radius: 15px;
}
- @keyframes appear {
- from {
- transform: scale(0.3);
+ // Apply for audio message playback.
+ .playing {
+ animation-name: circle1;
+ animation-duration: 2s;
+ animation-iteration-count: infinite;
+ }
+
+ @keyframes circle1 {
+ 0%,
+ 100% {
+ box-shadow: 0 0 0 0.4em rgba(195, 195, 195, 0.4), 0 0 0 0.25em rgba(195, 195, 195, 0.15);
}
- to {
- transform: scale(1);
+ 25% {
+ box-shadow: 0 0 0 0.15em rgba(195, 195, 195, 0.15), 0 0 0 0.4em rgba(195, 195, 195, 0.3);
+ }
+ 50% {
+ box-shadow: 0 0 0 0.55em rgba(195, 195, 195, 0.55), 0 0 0 0.15em rgba(195, 195, 195, 0.05);
+ }
+ 75% {
+ box-shadow: 0 0 0 0.25em rgba(195, 195, 195, 0.25), 0 0 0 0.55em rgba(195, 195, 195, 0.45);
}
}