add wordballoons to agents on the webapp
(i know they will be broken, this is just to give an environment for them to actually be used in)
This commit is contained in:
parent
22f0d4a008
commit
396ef67c78
1 changed files with 184 additions and 166 deletions
|
@ -1,5 +1,14 @@
|
||||||
import { createNanoEvents, Emitter, Unsubscribe } from 'nanoevents';
|
import { createNanoEvents, Emitter, Unsubscribe } from 'nanoevents';
|
||||||
import { MSAgentAddUserMessage, MSAgentChatMessage, MSAgentInitMessage, MSAgentJoinMessage, MSAgentProtocolMessage, MSAgentProtocolMessageType, MSAgentRemoveUserMessage, MSAgentTalkMessage } from '@msagent-chat/protocol';
|
import {
|
||||||
|
MSAgentAddUserMessage,
|
||||||
|
MSAgentChatMessage,
|
||||||
|
MSAgentInitMessage,
|
||||||
|
MSAgentJoinMessage,
|
||||||
|
MSAgentProtocolMessage,
|
||||||
|
MSAgentProtocolMessageType,
|
||||||
|
MSAgentRemoveUserMessage,
|
||||||
|
MSAgentTalkMessage
|
||||||
|
} from '@msagent-chat/protocol';
|
||||||
import { User } from './user';
|
import { User } from './user';
|
||||||
import { agentCreateCharacterFromUrl } from '@msagent-chat/msagent.js';
|
import { agentCreateCharacterFromUrl } from '@msagent-chat/msagent.js';
|
||||||
|
|
||||||
|
@ -41,27 +50,27 @@ export class MSAgentClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAgents() {
|
async getAgents() {
|
||||||
let res = await fetch(this.url + "/api/agents");
|
let res = await fetch(this.url + '/api/agents');
|
||||||
return await res.json() as APIAgentInfo[];
|
return (await res.json()) as APIAgentInfo[];
|
||||||
}
|
}
|
||||||
|
|
||||||
connect(): Promise<void> {
|
connect(): Promise<void> {
|
||||||
return new Promise(res => {
|
return new Promise((res) => {
|
||||||
let url = new URL(this.url);
|
let url = new URL(this.url);
|
||||||
switch (url.protocol) {
|
switch (url.protocol) {
|
||||||
case "http:":
|
case 'http:':
|
||||||
url.protocol = "ws:";
|
url.protocol = 'ws:';
|
||||||
break;
|
break;
|
||||||
case "https:":
|
case 'https:':
|
||||||
url.protocol = "wss:";
|
url.protocol = 'wss:';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Unknown protocol ${url.protocol}`);
|
throw new Error(`Unknown protocol ${url.protocol}`);
|
||||||
}
|
}
|
||||||
url.pathname = "/api/socket"
|
url.pathname = '/api/socket';
|
||||||
this.socket = new WebSocket(url);
|
this.socket = new WebSocket(url);
|
||||||
this.socket.addEventListener('open', () => res());
|
this.socket.addEventListener('open', () => res());
|
||||||
this.socket.addEventListener('message', e => {
|
this.socket.addEventListener('message', (e) => {
|
||||||
if (e.data instanceof ArrayBuffer) {
|
if (e.data instanceof ArrayBuffer) {
|
||||||
// server should not send binary
|
// server should not send binary
|
||||||
return;
|
return;
|
||||||
|
@ -70,13 +79,13 @@ export class MSAgentClient {
|
||||||
});
|
});
|
||||||
this.socket.addEventListener('close', () => {
|
this.socket.addEventListener('close', () => {
|
||||||
this.events.emit('close');
|
this.events.emit('close');
|
||||||
})
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
send(msg: MSAgentProtocolMessage) {
|
send(msg: MSAgentProtocolMessage) {
|
||||||
if (this.socket === null || this.socket.readyState !== this.socket.OPEN) {
|
if (this.socket === null || this.socket.readyState !== this.socket.OPEN) {
|
||||||
console.error("Tried to send data on a closed or uninitialized socket");
|
console.error('Tried to send data on a closed or uninitialized socket');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let data = JSON.stringify(msg);
|
let data = JSON.stringify(msg);
|
||||||
|
@ -85,9 +94,9 @@ export class MSAgentClient {
|
||||||
|
|
||||||
join(username: string, agent: string) {
|
join(username: string, agent: string) {
|
||||||
if (this.socket === null || this.socket.readyState !== this.socket.OPEN) {
|
if (this.socket === null || this.socket.readyState !== this.socket.OPEN) {
|
||||||
throw new Error("Tried to join() on a closed or uninitialized socket");
|
throw new Error('Tried to join() on a closed or uninitialized socket');
|
||||||
}
|
}
|
||||||
return new Promise<void>(res => {
|
return new Promise<void>((res) => {
|
||||||
let msg: MSAgentJoinMessage = {
|
let msg: MSAgentJoinMessage = {
|
||||||
op: MSAgentProtocolMessageType.Join,
|
op: MSAgentProtocolMessageType.Join,
|
||||||
data: {
|
data: {
|
||||||
|
@ -132,7 +141,7 @@ export class MSAgentClient {
|
||||||
this.agent = initMsg.data.agent;
|
this.agent = initMsg.data.agent;
|
||||||
this.charlimit = initMsg.data.charlimit;
|
this.charlimit = initMsg.data.charlimit;
|
||||||
for (let _user of initMsg.data.users) {
|
for (let _user of initMsg.data.users) {
|
||||||
let agent = await agentCreateCharacterFromUrl(this.url + "/api/agents/" + _user.agent);
|
let agent = await agentCreateCharacterFromUrl(this.url + '/api/agents/' + _user.agent);
|
||||||
agent.addToDom(this.agentContainer);
|
agent.addToDom(this.agentContainer);
|
||||||
agent.show();
|
agent.show();
|
||||||
let user = new User(_user.username, agent);
|
let user = new User(_user.username, agent);
|
||||||
|
@ -143,7 +152,7 @@ export class MSAgentClient {
|
||||||
}
|
}
|
||||||
case MSAgentProtocolMessageType.AddUser: {
|
case MSAgentProtocolMessageType.AddUser: {
|
||||||
let addUserMsg = msg as MSAgentAddUserMessage;
|
let addUserMsg = msg as MSAgentAddUserMessage;
|
||||||
let agent = await agentCreateCharacterFromUrl(this.url + "/api/agents/" + addUserMsg.data.agent);
|
let agent = await agentCreateCharacterFromUrl(this.url + '/api/agents/' + addUserMsg.data.agent);
|
||||||
agent.addToDom(this.agentContainer);
|
agent.addToDom(this.agentContainer);
|
||||||
agent.show();
|
agent.show();
|
||||||
let user = new User(addUserMsg.data.username, agent);
|
let user = new User(addUserMsg.data.username, agent);
|
||||||
|
@ -153,7 +162,7 @@ export class MSAgentClient {
|
||||||
}
|
}
|
||||||
case MSAgentProtocolMessageType.RemoveUser: {
|
case MSAgentProtocolMessageType.RemoveUser: {
|
||||||
let remUserMsg = msg as MSAgentRemoveUserMessage;
|
let remUserMsg = msg as MSAgentRemoveUserMessage;
|
||||||
let user = this.users.find(u => u.username === remUserMsg.data.username);
|
let user = this.users.find((u) => u.username === remUserMsg.data.username);
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
user.agent.hide(true);
|
user.agent.hide(true);
|
||||||
if (this.playingAudio.has(user!.username)) {
|
if (this.playingAudio.has(user!.username)) {
|
||||||
|
@ -165,7 +174,7 @@ export class MSAgentClient {
|
||||||
}
|
}
|
||||||
case MSAgentProtocolMessageType.Chat: {
|
case MSAgentProtocolMessageType.Chat: {
|
||||||
let chatMsg = msg as MSAgentChatMessage;
|
let chatMsg = msg as MSAgentChatMessage;
|
||||||
let user = this.users.find(u => u.username === chatMsg.data.username);
|
let user = this.users.find((u) => u.username === chatMsg.data.username);
|
||||||
this.events.emit('chat', user, chatMsg.data.message);
|
this.events.emit('chat', user, chatMsg.data.message);
|
||||||
if (chatMsg.data.audio !== undefined) {
|
if (chatMsg.data.audio !== undefined) {
|
||||||
let audio = new Audio(this.url + chatMsg.data.audio);
|
let audio = new Audio(this.url + chatMsg.data.audio);
|
||||||
|
@ -173,10 +182,19 @@ export class MSAgentClient {
|
||||||
this.playingAudio.get(user!.username)?.pause();
|
this.playingAudio.get(user!.username)?.pause();
|
||||||
this.playingAudio.delete(user!.username);
|
this.playingAudio.delete(user!.username);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.playingAudio.set(user!.username, audio);
|
this.playingAudio.set(user!.username, audio);
|
||||||
|
|
||||||
audio.addEventListener('ended', () => {
|
audio.addEventListener('ended', () => {
|
||||||
this.playingAudio.delete(user!.username);
|
this.playingAudio.delete(user!.username);
|
||||||
|
|
||||||
|
// give a bit of time before the wordballoon disappears
|
||||||
|
setTimeout(() => {
|
||||||
|
user!.agent.stopSpeaking();
|
||||||
|
}, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
user?.agent.speak(chatMsg.data.message);
|
||||||
audio.play();
|
audio.play();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue