本地存储消息
This commit is contained in:
parent
5c00514610
commit
cabab4890b
91
src/chat.js
91
src/chat.js
@ -1,39 +1,36 @@
|
||||
import { get, set, del, update, createStore, values } from 'idb-keyval'
|
||||
import { Span, Button, List, ListItem, Input, createElement } from './weigets.js'
|
||||
|
||||
// 先不划分频道, 只有一个公共聊天室
|
||||
export default class Chat {
|
||||
constructor({ EventListeners = {}, onsend, onexit }) {
|
||||
constructor({ name, EventListeners = {}, onsend, onexit }) {
|
||||
this.event = { onsend, onexit }
|
||||
this.store = createStore(`db-chat-${name}`, `store-chat-${name}`)
|
||||
this.ul = List({ classList: ['chat-list'] })
|
||||
this.EventListeners = EventListeners
|
||||
document.body.appendChild(this.ul) // 元素加入页面
|
||||
|
||||
// 使用一个有序列表来存储消息
|
||||
const messageBox = new Map()
|
||||
|
||||
// 添加输入框
|
||||
const input = createElement({
|
||||
type: 'text',
|
||||
placeholder: '输入聊天内容',
|
||||
style: {
|
||||
height: '5rem',
|
||||
margin: '1rem 2rem',
|
||||
padding: '1rem',
|
||||
boxSizing: 'border-box',
|
||||
boxShadow: '0 0 1rem #eee',
|
||||
},
|
||||
onkeydown: event => {
|
||||
if (event.key === 'Enter') {
|
||||
const text = input.value.trim()
|
||||
if (text) {
|
||||
this.send(text)
|
||||
input.value = ''
|
||||
document.body.appendChild(createElement({
|
||||
children: [
|
||||
this.ul,
|
||||
createElement({
|
||||
type: 'text',
|
||||
placeholder: '输入聊天内容',
|
||||
style: {
|
||||
height: '5rem',
|
||||
margin: '1rem 2rem',
|
||||
padding: '1rem',
|
||||
boxSizing: 'border-box',
|
||||
boxShadow: '0 0 1rem #eee',
|
||||
},
|
||||
onkeydow1n: event => {
|
||||
const text = event.target.value.trim()
|
||||
if (text && event.key === 'Enter') {
|
||||
this.发送消息(text)
|
||||
event.target.value = ''
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}, 'textarea')
|
||||
document.body.appendChild(input)
|
||||
|
||||
}, 'textarea')
|
||||
]
|
||||
}))
|
||||
// 写入 css 样式到 head
|
||||
const style = document.createElement('style')
|
||||
style.innerText = `
|
||||
@ -57,6 +54,7 @@ export default class Chat {
|
||||
}
|
||||
`
|
||||
document.head.appendChild(style)
|
||||
this.载入消息()
|
||||
}
|
||||
// 收到应答(对方确认消息已被接收)
|
||||
answer(data) {
|
||||
@ -76,12 +74,47 @@ export default class Chat {
|
||||
this.ul.scrollTop = this.ul.scrollHeight
|
||||
return item
|
||||
}
|
||||
// 发送消息
|
||||
send(text) {
|
||||
if (this.event.onsend) {
|
||||
this.event.onsend(text)
|
||||
}
|
||||
}
|
||||
添加元素(data) {
|
||||
this.ul.appendChild(ListItem({
|
||||
children: [
|
||||
Span({ innerText: `${data.name} ${data.time} ${data.text}` })
|
||||
]
|
||||
}))
|
||||
}
|
||||
存储消息(data) {
|
||||
const { name, text, time, type } = data
|
||||
const id = window.crypto.randomUUID()
|
||||
const item = { id, name, text, time, type }
|
||||
set(id, item, this.store)
|
||||
}
|
||||
载入消息() {
|
||||
values(this.store).then(items => {
|
||||
items.map(item => {
|
||||
item.timestamp = new Date(item.time).getTime()
|
||||
return item
|
||||
}).sort((a, b) => a.timestamp - b.timestamp).forEach(item => {
|
||||
this.添加元素(item)
|
||||
})
|
||||
})
|
||||
}
|
||||
发送消息(text) {
|
||||
const name = '我'
|
||||
const time = new Date().toLocaleString()
|
||||
console.log('发送消息', { name, text, time })
|
||||
const type = 'text'
|
||||
this.添加元素({ name, text, time, type })
|
||||
this.存储消息({ name, text, time, type })
|
||||
this.send({ name, text, time, type })
|
||||
}
|
||||
收到消息(data) {
|
||||
const { name, text, time, type } = data
|
||||
this.add({ name, text, time, type })
|
||||
}
|
||||
// 退出
|
||||
exit() {
|
||||
if (this.event.onexit) {
|
||||
|
@ -139,11 +139,9 @@ const musicList = new MusicList({
|
||||
})
|
||||
|
||||
const chat = new Chat({
|
||||
name: 'default',
|
||||
onsend: async (text, list) => {
|
||||
console.log('发送消息', text)
|
||||
chat.add({ name, text, time: new Date().toLocaleTimeString() })
|
||||
clientList.send('chat', JSON.stringify({ type: 'message', text }))
|
||||
console.log('发送结束')
|
||||
},
|
||||
onexit: async () => {
|
||||
console.log('退出聊天室')
|
||||
@ -376,4 +374,4 @@ if (localStorage.getItem('avatar')) {
|
||||
// 设置标题为自己的昵称
|
||||
if (localStorage.getItem('username')) {
|
||||
document.title = localStorage.getItem('username')
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user