添加聊天室

This commit is contained in:
2023-10-18 23:54:44 +08:00
parent 488d6d9c7c
commit b14aaa6ec3
2 changed files with 113 additions and 2 deletions

75
src/chat.js Normal file
View File

@ -0,0 +1,75 @@
import { Span, Button, List, ListItem } from './weigets.js'
// 先不划分频道, 只有一个公共聊天室
export default class Chat {
constructor({ EventListeners = {}, onsend, onexit }) {
this.event = { onsend, onexit }
this.ul = List({ classList: ['chat-list'] })
this.EventListeners = EventListeners
document.body.appendChild(this.ul) // 元素加入页面
// 添加输入框
const input = document.createElement('input')
input.type = 'text'
input.placeholder = '输入聊天内容'
input.style.width = '100%'
input.style.height = '5rem'
input.style.margin = '1rem 2rem'
input.addEventListener('keydown', event => {
if (event.key === 'Enter') {
const text = input.value.trim()
if (text) {
this.send(text)
input.value = ''
}
}
})
document.body.appendChild(input)
// 写入 css 样式到 head
const style = document.createElement('style')
style.innerText = `
ul.chat-list {
max-height: 70vh;
overflow-y: auto;
}
ul.chat-list > li > span {
cursor: pointer;
}
ul.chat-list > li.play > span {
color: #02be08;
}
ul.chat-list > li.cache::marker {
color: #02be08;
font-size: 1em;
contentx: '⚡';
}
ul.chat-list > li.disable {
color: #888;
}
`
document.head.appendChild(style)
}
// 添加一条消息
add({ name, text, time, type }) {
this.ul.appendChild(ListItem({
classList: [type],
children: [
Span({ innerText: `${name} ${time} ${text}` })
]
}))
this.ul.scrollTop = this.ul.scrollHeight
}
// 发送消息
send(text) {
if (this.event.onsend) {
this.event.onsend(text)
}
}
// 退出
exit() {
if (this.event.onexit) {
this.event.onexit()
}
}
}

View File

@ -4,6 +4,7 @@ import 'virtual:windi-devtools'
import IndexedDB from './database.js' import IndexedDB from './database.js'
import MusicList from './music.js' import MusicList from './music.js'
import ClientList from './client.js' import ClientList from './client.js'
import Chat from './chat.js'
// 缓冲分片发送 // 缓冲分片发送
const CHUNK_SIZE = 1024 * 64 // 默认每个块的大小为128KB const CHUNK_SIZE = 1024 * 64 // 默认每个块的大小为128KB
@ -140,9 +141,44 @@ const musicList = new MusicList({
} }
}) })
const ImageList = [] const chat = new Chat({
onsend: async (text, list) => {
console.log('发送消息', text)
clientList.send('chat', JSON.stringify({ type: 'message', text }))
console.log('发送结束')
},
onexit: async () => {
console.log('退出聊天室')
}
})
// 只有一个基本信道, 用于交换和调度信息 // 与每个客户端都建立聊天信道
clientList.setChannel('chat', {
onopen: async event => {
console.debug('打开信道', event.target.label)
},
onmessage: async (event, client) => {
const data = JSON.parse(event.data)
if (data.type === 'message') {
console.log(client.name, '发来消息:', data)
chat.add({ name: client.name, text: data.text, time: new Date().toLocaleTimeString() })
return
}
if (data.type === 'image') {
console.log(client.name, '发来图片:', data)
return
}
console.log('未知类型:', data.type)
},
onclose: event => {
console.log('关闭信道', event.target.label)
},
onerror: event => {
console.error('信道错误', event.target.label, event.error)
}
})
// 与每个客户端都建立基本信道, 用于交换和调度信息
clientList.setChannel('base', { clientList.setChannel('base', {
onopen: async event => { onopen: async event => {
console.debug('打开信道', event.target.label, '广播请求音乐列表和身份信息') console.debug('打开信道', event.target.label, '广播请求音乐列表和身份信息')