本地存储消息
This commit is contained in:
		
							
								
								
									
										69
									
								
								src/chat.js
									
									
									
									
									
								
							
							
						
						
									
										69
									
								
								src/chat.js
									
									
									
									
									
								
							@@ -1,18 +1,17 @@
 | 
				
			|||||||
 | 
					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({
 | 
				
			||||||
 | 
					 | 
				
			||||||
        // 添加输入框
 | 
					 | 
				
			||||||
        const input = createElement({
 | 
					 | 
				
			||||||
                    type: 'text',
 | 
					                    type: 'text',
 | 
				
			||||||
                    placeholder: '输入聊天内容',
 | 
					                    placeholder: '输入聊天内容',
 | 
				
			||||||
                    style: {
 | 
					                    style: {
 | 
				
			||||||
@@ -22,18 +21,16 @@ export default class Chat {
 | 
				
			|||||||
                        boxSizing: 'border-box',
 | 
					                        boxSizing: 'border-box',
 | 
				
			||||||
                        boxShadow: '0 0 1rem #eee',
 | 
					                        boxShadow: '0 0 1rem #eee',
 | 
				
			||||||
                    },
 | 
					                    },
 | 
				
			||||||
            onkeydown: event => {
 | 
					                    onkeydow1n: event => {
 | 
				
			||||||
                if (event.key === 'Enter') {
 | 
					                        const text = event.target.value.trim()
 | 
				
			||||||
                    const text = input.value.trim()
 | 
					                        if (text && event.key === 'Enter') {
 | 
				
			||||||
                    if (text) {
 | 
					                            this.发送消息(text)
 | 
				
			||||||
                        this.send(text)
 | 
					                            event.target.value = ''
 | 
				
			||||||
                        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) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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('退出聊天室')
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user