chgpt / static /js /windowHandler.js
Miguel Diaz
Update assistant + google oauth + google search
9c5c050
class WindowHandler{
/* Eventos generados
- chat:enviar
- chat:eliminar
**********************/
/* Eventos escuchados
**********************/
conversacion = []
constructor(conversacion, index, chatHndl){
// El indice de este chat
this.index = index
this.conversacion = conversacion
this.chatHandler = chatHndl || 0
// Template de mensajes
this.templateMsg = $("#template-message").contents("div.message").clone()
this.tabs = $(".tabs")
this.templateLabel = $("#template-label").contents("label").clone()
this.templateTab = $("#template-tab").contents("div.tab").clone()
this.chatbox = this.templateTab.find(".chat")
// Parametros base
this.active = false;
// ha tenido su primera interacci贸n
this.interacted = false
this.crearVentanaChat(index, "Tab "+ index)
this.cargarEventos();
$(document).trigger("ventana:cambiada")
this.cargarChat(conversacion)
}
crearVentanaChat(index, nombre){
// coloca el valor al input y lo selecciona
let newLabel = this.templateLabel.clone()
newLabel.find("input").val(index).prop("checked", true);
newLabel.find("> div").text(nombre)
this.tabs.append(newLabel)
this.label = newLabel
// Crea la ventana de chat
let tempTab = this.templateTab.clone();
tempTab.attr("id", index)
$(".chats").append(tempTab)
// establece los contextos de ventana
this.ctx = tempTab
this.chatbox = this.ctx.find(".chat");
this.ventanaSeleccionada()
}
ventanaSeleccionada(){
// cuando la ventana es seleccionada, cambia
$(".tab").removeClass("active")
this.label.find("input")[0].checked=true;
this.ctx.addClass("active");
}
cargarEventos(){
this.label.click(()=> this.ventanaSeleccionada())
this.ctx.find(".input-text").keypress((event) => {
if (!event.shiftKey && event.keyCode === 13) {
this.manejadorEnviar();
}
this.recalcularTextarea()
});
this.ctx.find(".input-send").click(() => this.manejadorEnviar());
this.ctx.find(".input-text").on("keyup,keydown", () => this.recalcularTextarea());
this.ctx.find(".input-delete").click(() => this.eliminarChat() )
this.ctx.find(".input-menu").click(() => $(document).trigger("mostrar:opciones"))
}
crearMensaje(texto, user){
this.active = this.templateMsg.clone();
switch(user){
case "system":
return;
case "user":
this.active.addClass("me");
this.active.find("div p").text(texto);
break;
case "assistant":
texto = this.procesarTexto(texto);
this.active.find("div p").html(texto);
Prism.highlightAllUnder(this.active[0])
break;
case "loading":
this.active.find("div p").html('<div class="loader-wrap"><span class="loader"></span></div>');
break;
}
this.chatbox.append(this.active);
this.chatbox.scrollTop(this.chatbox[0].scrollHeight);
this.interacted=true
return this.active
}
manejadorEnviar(){
let mensaje = this.ctx.find(".input-text").val();
this.ctx.find("button").prop("disabled", true);
this.ctx.find("textarea").prop("disabled", true);
if(mensaje==""){
return false;
}
if(this.conversacion.length==0){
this.conversacion.push({role:"system", content: this.chatHandler.config.assistantPrompt})
}
this.conversacion.push({role: "user", content: mensaje})
self = this
this.crearMensaje(mensaje, "user");
$(document).trigger("chat:enviar", {ctx: self, conversacion:this.conversacion})
}
respuestaInicio(){
this.crearMensaje("", "loading");
}
respuestaStatus(mensaje, modo=false){
let temp = $("<div></div>")
temp.text(mensaje)
if(!this.active.find(".loader").hasClass("firststage")){
this.active.find(".loader").addClass("firststage")
}
switch(modo){
case "enlinea":
this.active.find("div p div:last-child").text(this.active.find("div p div:last-child").text() + mensaje);
break;
case "reemplazar":
this.active.find("div p div:not(.loader-wrap)").remove();
this.active.find("div p").append(temp)
break;
default:
this.active.find("div p").append(temp)
}
this.chatbox.scrollTop(this.chatbox[0].scrollHeight);
}
respuestaMensaje(data){
let mensaje = data.content
this.active.find("div p").html("");
mensaje = this.procesarTexto(mensaje);
this.active.find("div p").html(mensaje);
Prism.highlightAllUnder(this.active[0]);
this.chatbox.scrollTop(this.chatbox[0].scrollHeight);
this.conversacion.push(data)
this.active = false;
this.interacted = true;
this.ctx.find("button").prop("disabled", false);
this.ctx.find("textarea").prop("disabled", false);
this.ctx.find("textarea").val("")
this.ctx.find("textarea").focus();
$(document).trigger("chat:salvar", {index: this.index, conversacion: this.conversacion})
}
respuestaError(error){
this.ctx.find("button").prop("disabled", false);
this.ctx.find("textarea").prop("disabled", false);
this.ctx.find("textarea").val("")
this.ctx.find("textarea").focus();
if(error.hasOwnProperty("responseJSON")){
this.active.find("div p").html(error.responseJSON.detail)
}else{
this.active.find("div p").html("El API no responde, la conexi贸n pudo haberse caido")
}
switch(error.status | 0){
case 404:
this.active.addClass("error")
break;
case 408:
this.active.addClass("warning")
break;
default:
this.active.addClass("error")
}
this.active = false;
this.chatbox.scrollTop(this.chatbox[0].scrollHeight)
}
cargarChat(conversacion){
for(let mensaje of this.conversacion){
this.crearMensaje(mensaje.content, mensaje.role)
}
}
eliminarChat(){
if(confirm("驴Est谩s seguro que quieres eliminar esta conversaci贸n?")){
this.label.remove()
this.ctx.remove()
$(document).trigger("chat:eliminar", {ctx:this.ctx, index:this.index})
}
}
recalcularTextarea(){
this.ctx.find(".input-box").css("height", "30px");
let height = parseInt((this.ctx.find(".input-text").prop('scrollHeight')+15)/15)*15;
this.ctx.find(".input-box").css("height", height+"px");
height -= 30;
this.ctx.find(".chat").css("--textarea", height+"px");
}
procesarTexto(texto){
let resultado = "";
let codigo = false;
for(let actual of texto.split("```")){
if(codigo){
let temp = actual.split("\n",1);
resultado += "<pre><code class='language-";
resultado += temp[0].length>1?temp[0]:"none";
temp = $("<div></div>").text(actual.substr(temp[0].length+1)).html()
resultado += "'>"+temp+"</code></pre>";
}else{
resultado += $("<div></div>").text(actual).html().replace(/`([^`]+?)`/gm, "<b>$1</b>").replace(/\n/g, "<br>");
resultado = resultado.replace(/\[(.*?)\]\((.*?)\)/gm, "[<a href='$2' target='_blank'>$1</a>]")
}
codigo = !codigo;
}
return resultado
}
}