| class WindowHandler{ |
| |
| |
| |
| |
| |
| |
| |
|
|
| conversacion = [] |
| constructor(conversacion, index, chatHndl){ |
| |
| |
| this.index = index |
| this.conversacion = conversacion |
| this.chatHandler = chatHndl || 0 |
|
|
| |
| 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") |
| |
|
|
| |
| this.active = false; |
| |
| |
| this.interacted = false |
|
|
| this.crearVentanaChat(index, "Tab "+ index) |
| this.cargarEventos(); |
| $(document).trigger("ventana:cambiada") |
| this.cargarChat(conversacion) |
| |
| } |
|
|
| crearVentanaChat(index, nombre){ |
| |
| 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 |
|
|
| |
| let tempTab = this.templateTab.clone(); |
| tempTab.attr("id", index) |
| $(".chats").append(tempTab) |
|
|
|
|
| |
| this.ctx = tempTab |
| this.chatbox = this.ctx.find(".chat"); |
| this.ventanaSeleccionada() |
| } |
|
|
| ventanaSeleccionada(){ |
| |
| $(".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 |
| } |
|
|
| |
|
|
| |
|
|
|
|
|
|
|
|
| } |