添加聊天室
This commit is contained in:
parent
488d6d9c7c
commit
b14aaa6ec3
75
src/chat.js
Normal file
75
src/chat.js
Normal 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()
|
||||
}
|
||||
}
|
||||
}
|
40
src/main.js
40
src/main.js
@ -4,6 +4,7 @@ import 'virtual:windi-devtools'
|
||||
import IndexedDB from './database.js'
|
||||
import MusicList from './music.js'
|
||||
import ClientList from './client.js'
|
||||
import Chat from './chat.js'
|
||||
|
||||
// 缓冲分片发送
|
||||
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', {
|
||||
onopen: async event => {
|
||||
console.debug('打开信道', event.target.label, '广播请求音乐列表和身份信息')
|
||||
|
Loading…
Reference in New Issue
Block a user