Spaces:
Building
Building
import Initialize from "./initialize.js"; | |
import Chat from "./chat.js"; | |
import RenderSymbols from "./renderSymbols.js"; | |
class UIManager{ | |
constructor(){ | |
this.initializer = new Initialize(this); | |
this.chat = new Chat(this); | |
this.renderSymbols = new RenderSymbols(); | |
this.menu = document.getElementById('menu'); | |
this.hamburger = document.getElementById('hamburger'); | |
this.messagesDiv = document.getElementById('messages'); | |
this.container = document.getElementById('container') | |
this.prevChatsCont = document.getElementById('prevChatsCont'); | |
this.textBox = document.getElementById('textBox'); | |
this.sendBtn = document.getElementById('sendBtn'); | |
this.newChat = document.getElementById('newChat'); | |
this.models = document.getElementById('models'); | |
this.initialized = false; | |
this.webSearchBtn = document.getElementById('webSearch'); | |
this.webSearch = false; | |
this.aiDiv; | |
this.userDiv; | |
this.aiP; | |
this.userP; | |
this.imageMode = false; | |
this.dialog = null; | |
} | |
async run(){ | |
await this.initializer.initialize(); | |
this.handleTextBoxHeight(); | |
this.events(); | |
} | |
events(){ | |
this.sendBtn.addEventListener('click',()=>{ | |
this.send(); | |
}) | |
window.addEventListener('keydown',(e)=>{ | |
if (e.key === '/' && document.activeElement === this.textBox) { | |
e.preventDefault(); | |
this.showDialog(); | |
} | |
if(e.key=='Enter' && !this.sendBtn.disabled){ | |
this.send(); | |
} | |
}) | |
this.newChat.addEventListener('click', async ()=>{ | |
await this.initializer.initialize(); | |
}) | |
this.webSearchBtn.addEventListener('click', ()=>{ | |
if(this.webSearch){ | |
this.webSearchBtn.style.color = 'white'; | |
} else{ | |
this.webSearchBtn.style.color = 'rgba(30,30,250,0.8)'; | |
} | |
this.webSearch = !this.webSearch; | |
}) | |
document.getElementById('closeAlert').onclick = ()=>{ | |
document.getElementById('alert').style.display = 'none' | |
} | |
} | |
showDialog() { | |
if (this.dialog) { | |
this.dialog.remove(); | |
this.dialog = null; | |
return; | |
} | |
this.dialog = document.createElement('div'); | |
this.dialog.style.position = 'absolute'; | |
this.dialog.style.top = `${this.textBox.offsetTop - 100}px`; | |
this.dialog.style.left = `${this.textBox.offsetLeft}px`; | |
this.dialog.style.backgroundColor = 'white'; | |
this.dialog.style.border = '1px solid black'; | |
this.dialog.style.padding = '10px'; | |
this.dialog.style.zIndex = '1000'; | |
this.dialog.innerHTML = ` | |
<button id="dialogImage">Image</button> | |
<button id="dialogSearch">Search</button> | |
`; | |
document.body.appendChild(this.dialog); | |
document.getElementById('dialogImage').addEventListener('click', () => { | |
this.imageMode = true; | |
this.textBox.value = "/image "; | |
this.dialog.remove(); | |
this.dialog = null; | |
}); | |
document.getElementById('dialogSearch').addEventListener('click', () => { | |
this.webSearch = true; | |
this.webSearchBtn.style.color = 'rgba(30,30,250,0.8)'; | |
this.textBox.value = "/search "; | |
this.dialog.remove(); | |
this.dialog = null; | |
}); | |
} | |
async send(){ | |
let promptText = this.textBox.value; | |
let imageBase64 = null; | |
if (this.imageMode) { | |
const file = await this.getImageFile(); | |
if (file) { | |
imageBase64 = await this.getBase64(file); | |
} | |
promptText = promptText.replace(/^\/image\s*/, ''); | |
this.imageMode = false; | |
} | |
this.appendUserMsg(promptText, imageBase64); | |
this.appendAiMsg(); | |
await this.chat.chat(); | |
} | |
async getImageFile() { | |
return new Promise(resolve => { | |
const input = document.createElement('input'); | |
input.type = 'file'; | |
input.accept = 'image/*'; | |
input.onchange = e => { | |
const file = e.target.files[0]; | |
resolve(file); | |
}; | |
input.click(); | |
}); | |
} | |
async getBase64(file) { | |
return new Promise((resolve, reject) => { | |
const reader = new FileReader(); | |
reader.readAsDataURL(file); | |
reader.onload = () => resolve(reader.result); | |
reader.onerror = error => reject(error); | |
}); | |
} | |
appendUserMsg(msg=false, imageBase64 = null){ | |
this.userDiv = document.createElement('div'); | |
this.userDiv.className = 'user'; | |
this.userP = document.createElement('p'); | |
if(msg){ | |
this.userP.innerText = msg; | |
} else{ | |
this.userP.innerText = this.textBox.value; | |
} | |
if (imageBase64) { | |
const img = document.createElement('img'); | |
img.src = imageBase64; | |
img.style.maxWidth = '100%'; | |
img.style.height = 'auto'; | |
this.userDiv.appendChild(img); | |
} | |
this.userDiv.appendChild(this.userP); | |
this.messagesDiv.appendChild(this.userDiv); | |
} | |
appendAiMsg(msg=false){ | |
this.aiDiv = document.createElement('div'); | |
this.aiDiv.className = 'ai'; | |
this.aiP = document.createElement('p'); | |
if(msg){ | |
this.aiP.innerText=msg; | |
} | |
this.aiDiv.appendChild(this.aiP); | |
this.messagesDiv.appendChild(this.aiDiv); | |
} | |
handleTextBoxHeight() { | |
this.textBox.oninput = () => { | |
this.textBox.style.height = 'auto'; | |
if (this.textBox.scrollHeight <= 150) { | |
if(this.textBox.scrollHeight>60){ | |
this.textBox.style.height = `${this.textBox.scrollHeight}px`; | |
} | |
} else { | |
this.textBox.style.height = '150px'; | |
} | |
}; | |
} | |
addChat(){ | |
const prevChat = document.createElement('div'); | |
prevChat.innerText = this.initializer.convTitle; | |
prevChat.className = 'prevChat'; | |
prevChat.id = this.initializer.convId; | |
this.prevChatsCont.prepend(prevChat); | |
prevChat.style.backgroundColor = 'rgb(53, 53, 53)'; | |
prevChat.addEventListener('click', ()=>{ | |
this.initializer.reInitialize(prevChat.id); | |
}) | |
} | |
} | |
export default UIManager |