本地存储消息

This commit is contained in:
2023-10-21 03:27:09 +08:00
parent 5c00514610
commit cabab4890b
2 changed files with 64 additions and 33 deletions

View File

@ -1,39 +1,36 @@
import { get, set, del, update, createStore, values } from 'idb-keyval'
import { Span, Button, List, ListItem, Input, createElement } from './weigets.js' import { Span, Button, List, ListItem, Input, createElement } from './weigets.js'
// 先不划分频道, 只有一个公共聊天室 // 先不划分频道, 只有一个公共聊天室
export default class Chat { export default class Chat {
constructor({ EventListeners = {}, onsend, onexit }) { constructor({ name, EventListeners = {}, onsend, onexit }) {
this.event = { onsend, onexit } this.event = { onsend, onexit }
this.store = createStore(`db-chat-${name}`, `store-chat-${name}`)
this.ul = List({ classList: ['chat-list'] }) this.ul = List({ classList: ['chat-list'] })
this.EventListeners = EventListeners this.EventListeners = EventListeners
document.body.appendChild(this.ul) // 元素加入页面 document.body.appendChild(createElement({
children: [
// 使用一个有序列表来存储消息 this.ul,
const messageBox = new Map() createElement({
type: 'text',
// 添加输入框 placeholder: '输入聊天内容',
const input = createElement({ style: {
type: 'text', height: '5rem',
placeholder: '输入聊天内容', margin: '1rem 2rem',
style: { padding: '1rem',
height: '5rem', boxSizing: 'border-box',
margin: '1rem 2rem', boxShadow: '0 0 1rem #eee',
padding: '1rem', },
boxSizing: 'border-box', onkeydow1n: event => {
boxShadow: '0 0 1rem #eee', const text = event.target.value.trim()
}, if (text && event.key === 'Enter') {
onkeydown: event => { this.发送消息(text)
if (event.key === 'Enter') { event.target.value = ''
const text = input.value.trim() }
if (text) {
this.send(text)
input.value = ''
} }
} }, 'textarea')
} ]
}, 'textarea') }))
document.body.appendChild(input)
// 写入 css 样式到 head // 写入 css 样式到 head
const style = document.createElement('style') const style = document.createElement('style')
style.innerText = ` style.innerText = `
@ -57,6 +54,7 @@ export default class Chat {
} }
` `
document.head.appendChild(style) document.head.appendChild(style)
this.载入消息()
} }
// 收到应答(对方确认消息已被接收) // 收到应答(对方确认消息已被接收)
answer(data) { answer(data) {
@ -76,12 +74,47 @@ export default class Chat {
this.ul.scrollTop = this.ul.scrollHeight this.ul.scrollTop = this.ul.scrollHeight
return item return item
} }
// 发送消息
send(text) { send(text) {
if (this.event.onsend) { if (this.event.onsend) {
this.event.onsend(text) 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() { exit() {
if (this.event.onexit) { if (this.event.onexit) {

View File

@ -139,11 +139,9 @@ const musicList = new MusicList({
}) })
const chat = new Chat({ const chat = new Chat({
name: 'default',
onsend: async (text, list) => { onsend: async (text, list) => {
console.log('发送消息', text)
chat.add({ name, text, time: new Date().toLocaleTimeString() })
clientList.send('chat', JSON.stringify({ type: 'message', text })) clientList.send('chat', JSON.stringify({ type: 'message', text }))
console.log('发送结束')
}, },
onexit: async () => { onexit: async () => {
console.log('退出聊天室') console.log('退出聊天室')
@ -376,4 +374,4 @@ if (localStorage.getItem('avatar')) {
// 设置标题为自己的昵称 // 设置标题为自己的昵称
if (localStorage.getItem('username')) { if (localStorage.getItem('username')) {
document.title = localStorage.getItem('username') document.title = localStorage.getItem('username')
} }