Paso desarrollo 4
Browse files- static/css/tabs.css +1 -1
- static/js/chatHandler.js +14 -16
- static/js/inputboxHandler.js +1 -3
- static/js/windowHandler.js +66 -27
- static/main.html +8 -13
static/css/tabs.css
CHANGED
|
@@ -47,7 +47,7 @@
|
|
| 47 |
display: block;
|
| 48 |
line-height: 26px;
|
| 49 |
}
|
| 50 |
-
.tab-label >
|
| 51 |
display: flex;
|
| 52 |
align-items: center;
|
| 53 |
padding: 0 10px;
|
|
|
|
| 47 |
display: block;
|
| 48 |
line-height: 26px;
|
| 49 |
}
|
| 50 |
+
.tab-label > .tab-name, .tab-label-add > .tab-name{
|
| 51 |
display: flex;
|
| 52 |
align-items: center;
|
| 53 |
padding: 0 10px;
|
static/js/chatHandler.js
CHANGED
|
@@ -23,14 +23,13 @@ class ChatGPT{
|
|
| 23 |
/* Eventos escuchados
|
| 24 |
- chat:crear
|
| 25 |
- chat:enviar
|
| 26 |
-
- enviar:error
|
| 27 |
- chat:eliminar
|
| 28 |
|
| 29 |
**********************/
|
| 30 |
|
| 31 |
-
// Enpoint
|
| 32 |
endpointChat = "/chat";
|
| 33 |
token = null;
|
|
|
|
| 34 |
|
| 35 |
constructor(token){
|
| 36 |
// Token JWT de ejecución
|
|
@@ -40,15 +39,14 @@ class ChatGPT{
|
|
| 40 |
this.cargarEventos();
|
| 41 |
|
| 42 |
|
| 43 |
-
try{
|
| 44 |
-
|
| 45 |
-
}catch{
|
| 46 |
this.conversaciones = [[this.definicion]];
|
| 47 |
}
|
| 48 |
|
| 49 |
// Se crea un windowHandler por conversacion
|
| 50 |
for(let conversacion of this.conversaciones){
|
| 51 |
-
this.
|
| 52 |
}
|
| 53 |
|
| 54 |
// Anucia chats creados
|
|
@@ -63,8 +61,8 @@ class ChatGPT{
|
|
| 63 |
this.reintentos = 0;
|
| 64 |
this.enviar(params.mensaje, params.ctx);
|
| 65 |
});
|
| 66 |
-
$(document).on("
|
| 67 |
-
$(
|
| 68 |
}
|
| 69 |
|
| 70 |
crearChat(){
|
|
@@ -74,15 +72,15 @@ class ChatGPT{
|
|
| 74 |
this.conversaciones.push([this.definicion])
|
| 75 |
|
| 76 |
// Se crea el nuevo manejador de ventana
|
| 77 |
-
this.
|
| 78 |
new WindowHandler(
|
| 79 |
this.conversaciones[this.conversaciones.length-1],
|
| 80 |
-
this.
|
| 81 |
);
|
| 82 |
|
| 83 |
// Se anuncia la creación
|
| 84 |
-
$(document).trigger("chat:creado", this.
|
| 85 |
-
|
| 86 |
}
|
| 87 |
|
| 88 |
eliminarChat(ctx, index){
|
|
@@ -91,8 +89,8 @@ class ChatGPT{
|
|
| 91 |
|
| 92 |
// Elimina el elemento de la lista de conversas y handler de ventanas
|
| 93 |
this.conversaciones.splice(index, 1)
|
| 94 |
-
this.
|
| 95 |
-
this.
|
| 96 |
|
| 97 |
// Elimina la pestaña y contexto
|
| 98 |
$($(".tab-label")[index]).remove()
|
|
@@ -102,7 +100,7 @@ class ChatGPT{
|
|
| 102 |
let labels = $(".tab-label input")
|
| 103 |
for(let i=0; i<labels.length; i++){
|
| 104 |
$(labels[i]).val(i)
|
| 105 |
-
this.
|
| 106 |
}
|
| 107 |
$(labels[0]).prop("checked", true);
|
| 108 |
|
|
@@ -113,7 +111,7 @@ class ChatGPT{
|
|
| 113 |
$(document).trigger("chat:eliminado");
|
| 114 |
|
| 115 |
// Si no quedaron chats, crea uno vacio
|
| 116 |
-
if(this.
|
| 117 |
this.crearChat()
|
| 118 |
}
|
| 119 |
|
|
|
|
| 23 |
/* Eventos escuchados
|
| 24 |
- chat:crear
|
| 25 |
- chat:enviar
|
|
|
|
| 26 |
- chat:eliminar
|
| 27 |
|
| 28 |
**********************/
|
| 29 |
|
|
|
|
| 30 |
endpointChat = "/chat";
|
| 31 |
token = null;
|
| 32 |
+
windowHandlers = []
|
| 33 |
|
| 34 |
constructor(token){
|
| 35 |
// Token JWT de ejecución
|
|
|
|
| 39 |
this.cargarEventos();
|
| 40 |
|
| 41 |
|
| 42 |
+
try{this.conversaciones = JSON.parse(localStorage.getItem("conversaciones"))}catch{}
|
| 43 |
+
if (!this.conversaciones || this.conversaciones.length < 1){
|
|
|
|
| 44 |
this.conversaciones = [[this.definicion]];
|
| 45 |
}
|
| 46 |
|
| 47 |
// Se crea un windowHandler por conversacion
|
| 48 |
for(let conversacion of this.conversaciones){
|
| 49 |
+
this.windowHandlers.push(new WindowHandler(conversacion, this.windowHandlers.length));
|
| 50 |
}
|
| 51 |
|
| 52 |
// Anucia chats creados
|
|
|
|
| 61 |
this.reintentos = 0;
|
| 62 |
this.enviar(params.mensaje, params.ctx);
|
| 63 |
});
|
| 64 |
+
$(document).on("chat:eliminar", (event, params) => this.eliminarChat(params.ctx, params.index))
|
| 65 |
+
$("#nuevoChat").on("click", () => {$(document).trigger("chat:crear")})
|
| 66 |
}
|
| 67 |
|
| 68 |
crearChat(){
|
|
|
|
| 72 |
this.conversaciones.push([this.definicion])
|
| 73 |
|
| 74 |
// Se crea el nuevo manejador de ventana
|
| 75 |
+
this.windowHandlers.push(
|
| 76 |
new WindowHandler(
|
| 77 |
this.conversaciones[this.conversaciones.length-1],
|
| 78 |
+
this.windowHandlers.length)
|
| 79 |
);
|
| 80 |
|
| 81 |
// Se anuncia la creación
|
| 82 |
+
$(document).trigger("chat:creado", this.windowHandlers.length-1);
|
| 83 |
+
|
| 84 |
}
|
| 85 |
|
| 86 |
eliminarChat(ctx, index){
|
|
|
|
| 89 |
|
| 90 |
// Elimina el elemento de la lista de conversas y handler de ventanas
|
| 91 |
this.conversaciones.splice(index, 1)
|
| 92 |
+
this.windowHandlers[index].kill()
|
| 93 |
+
this.windowHandlers.splice(index, 1)
|
| 94 |
|
| 95 |
// Elimina la pestaña y contexto
|
| 96 |
$($(".tab-label")[index]).remove()
|
|
|
|
| 100 |
let labels = $(".tab-label input")
|
| 101 |
for(let i=0; i<labels.length; i++){
|
| 102 |
$(labels[i]).val(i)
|
| 103 |
+
this.windowHandlers[i].index=i;
|
| 104 |
}
|
| 105 |
$(labels[0]).prop("checked", true);
|
| 106 |
|
|
|
|
| 111 |
$(document).trigger("chat:eliminado");
|
| 112 |
|
| 113 |
// Si no quedaron chats, crea uno vacio
|
| 114 |
+
if(this.windowHandlers.length==0){
|
| 115 |
this.crearChat()
|
| 116 |
}
|
| 117 |
|
static/js/inputboxHandler.js
CHANGED
|
@@ -19,9 +19,7 @@ class InputBox{
|
|
| 19 |
|
| 20 |
this.textarea.on("change keydown keyup paste", () => this.recalcularTextarea())
|
| 21 |
|
| 22 |
-
|
| 23 |
-
$(document).trigger("chat:crear")}
|
| 24 |
-
)
|
| 25 |
|
| 26 |
$(document).on("chat:creado", (event, params) => this.chatCreado(params))
|
| 27 |
|
|
|
|
| 19 |
|
| 20 |
this.textarea.on("change keydown keyup paste", () => this.recalcularTextarea())
|
| 21 |
|
| 22 |
+
|
|
|
|
|
|
|
| 23 |
|
| 24 |
$(document).on("chat:creado", (event, params) => this.chatCreado(params))
|
| 25 |
|
static/js/windowHandler.js
CHANGED
|
@@ -1,20 +1,35 @@
|
|
| 1 |
class WindowHandler{
|
| 2 |
constructor(conversacion, index){
|
| 3 |
|
| 4 |
-
//
|
| 5 |
this.index = index
|
| 6 |
|
| 7 |
// Template de mensajes
|
| 8 |
-
this.
|
| 9 |
-
this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
// Parametros base
|
|
|
|
| 12 |
this.active = false;
|
| 13 |
-
|
|
|
|
| 14 |
this.interacted = false
|
| 15 |
|
| 16 |
-
//
|
| 17 |
-
this.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
// En envio de chat se recalcula el tamaño del area de texto
|
| 20 |
this.ctx.on("chat:enviar", (event, params) => this.recalcularTextarea());
|
|
@@ -26,6 +41,7 @@ class WindowHandler{
|
|
| 26 |
this.ctx.find(".input-text").keypress((event) => {
|
| 27 |
if (!event.shiftKey && event.keyCode === 13) {
|
| 28 |
this.manejadorEnviar();
|
|
|
|
| 29 |
}});
|
| 30 |
this.ctx.find(".input-send").click(() => this.manejadorEnviar());
|
| 31 |
this.ctx.find(".input-text").keypress(() => this.recalcularTextarea());
|
|
@@ -48,41 +64,64 @@ class WindowHandler{
|
|
| 48 |
this.ctx.on("precarga:error", (event, params) => {
|
| 49 |
this.respuestaError(params)
|
| 50 |
});
|
| 51 |
-
|
| 52 |
}
|
| 53 |
|
| 54 |
-
|
| 55 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
let tempTab = $(".tab-template").clone();
|
| 57 |
tempTab.removeClass("tab-template").addClass("tab")
|
| 58 |
$(".chats").append(tempTab)
|
|
|
|
|
|
|
| 59 |
this.ctx = tempTab
|
| 60 |
this.chatbox = this.ctx.find(".chat");
|
| 61 |
|
| 62 |
-
for(let mensaje of conversacion){
|
| 63 |
-
if(mensaje.role!="system"){
|
| 64 |
-
let clone = this.template.clone();
|
| 65 |
-
let texto = mensaje.content;
|
| 66 |
-
if(mensaje.role=="user") {
|
| 67 |
-
clone.addClass("me");
|
| 68 |
-
clone.find("div p").text(texto.replace(/\n/g, "<br>"));
|
| 69 |
-
}else{
|
| 70 |
-
texto = this.procesarTexto(texto);
|
| 71 |
-
clone.find("div p").html(texto);
|
| 72 |
-
}
|
| 73 |
-
this.chatbox.append(clone);
|
| 74 |
-
this.active = clone;
|
| 75 |
-
Prism.highlightAllUnder(this.active[0])
|
| 76 |
-
this.active = false;
|
| 77 |
-
this.chatbox.scrollTop(this.chatbox[0].scrollHeight);
|
| 78 |
-
this.interacted=true
|
| 79 |
-
}
|
| 80 |
-
}
|
| 81 |
|
|
|
|
| 82 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
|
| 84 |
|
| 85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
}
|
| 87 |
|
| 88 |
eliminarChat(){
|
|
|
|
| 1 |
class WindowHandler{
|
| 2 |
constructor(conversacion, index){
|
| 3 |
|
| 4 |
+
// El indice de este chat
|
| 5 |
this.index = index
|
| 6 |
|
| 7 |
// Template de mensajes
|
| 8 |
+
this.templateMsg = $('.message-template').clone();
|
| 9 |
+
this.templateMsg.removeClass("message-template")
|
| 10 |
+
this.templateMsg.addClass("message")
|
| 11 |
+
|
| 12 |
+
this.tabs = $(".tabs")
|
| 13 |
+
this.templateTag = $(".template .tab-label-template").clone()
|
| 14 |
+
this.templateTag.removeClass("tab-label-template").addClass("tab-label")
|
| 15 |
|
| 16 |
// Parametros base
|
| 17 |
+
// está activo (es el visible en pantalla)
|
| 18 |
this.active = false;
|
| 19 |
+
|
| 20 |
+
// ha tenido su primera interacción
|
| 21 |
this.interacted = false
|
| 22 |
|
| 23 |
+
//this.cargarEventos();
|
| 24 |
+
this.crearVentanaChat(index, "Tab "+ index)
|
| 25 |
+
//self.cargarChat(conversacion)
|
| 26 |
+
$(".tab-switch").on("change", function(){
|
| 27 |
+
$(".tab").removeClass("active")
|
| 28 |
+
let sw = $($(".tab")[this.value]).addClass("active")
|
| 29 |
+
})
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
cargarEventos(){
|
| 33 |
|
| 34 |
// En envio de chat se recalcula el tamaño del area de texto
|
| 35 |
this.ctx.on("chat:enviar", (event, params) => this.recalcularTextarea());
|
|
|
|
| 41 |
this.ctx.find(".input-text").keypress((event) => {
|
| 42 |
if (!event.shiftKey && event.keyCode === 13) {
|
| 43 |
this.manejadorEnviar();
|
| 44 |
+
|
| 45 |
}});
|
| 46 |
this.ctx.find(".input-send").click(() => this.manejadorEnviar());
|
| 47 |
this.ctx.find(".input-text").keypress(() => this.recalcularTextarea());
|
|
|
|
| 64 |
this.ctx.on("precarga:error", (event, params) => {
|
| 65 |
this.respuestaError(params)
|
| 66 |
});
|
| 67 |
+
|
| 68 |
}
|
| 69 |
|
| 70 |
+
crearVentanaChat(index, nombre){
|
| 71 |
|
| 72 |
+
// Crea el tab
|
| 73 |
+
let newTab = this.templateTag.clone()
|
| 74 |
+
|
| 75 |
+
// coloca el valor al input y lo selecciona
|
| 76 |
+
newTab.find("input").val(index)
|
| 77 |
+
newTab.find("input").prop("checked", true);
|
| 78 |
+
newTab.find("> div").text(nombre)
|
| 79 |
+
this.tabs.append(newTab)
|
| 80 |
+
|
| 81 |
+
// Crea la ventana de chat
|
| 82 |
let tempTab = $(".tab-template").clone();
|
| 83 |
tempTab.removeClass("tab-template").addClass("tab")
|
| 84 |
$(".chats").append(tempTab)
|
| 85 |
+
|
| 86 |
+
// establece los contextos de ventana
|
| 87 |
this.ctx = tempTab
|
| 88 |
this.chatbox = this.ctx.find(".chat");
|
| 89 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 90 |
|
| 91 |
+
//this.tabCambiada()
|
| 92 |
|
| 93 |
+
|
| 94 |
+
}
|
| 95 |
+
|
| 96 |
+
crearMensaje(texto, user){
|
| 97 |
+
this.active = this.template.clone();
|
| 98 |
+
switch(user){
|
| 99 |
+
case "system":
|
| 100 |
+
return
|
| 101 |
+
case "user":
|
| 102 |
+
clone.addClass("me");
|
| 103 |
+
clone.find("div p").text(texto);
|
| 104 |
+
case "assistant":
|
| 105 |
+
texto = this.procesarTexto(texto);
|
| 106 |
+
clone.find("div p").html(texto);
|
| 107 |
+
}
|
| 108 |
+
this.chatbox.append(this.active);
|
| 109 |
+
Prism.highlightAllUnder(this.active[0])
|
| 110 |
+
this.active = false;
|
| 111 |
+
this.chatbox.scrollTop(this.chatbox[0].scrollHeight);
|
| 112 |
+
this.interacted=true
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
cargarChat(conversacion){
|
| 118 |
|
| 119 |
|
| 120 |
|
| 121 |
+
for(let mensaje of conversacion){
|
| 122 |
+
this.crearMensaje(mensaje.contentm, mensaje.role)
|
| 123 |
+
}
|
| 124 |
+
|
| 125 |
}
|
| 126 |
|
| 127 |
eliminarChat(){
|
static/main.html
CHANGED
|
@@ -11,8 +11,7 @@
|
|
| 11 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js" integrity="sha512-9khQRAUBYEJDCDVP2yw3LRUQvjJ0Pjx0EShmaQjcHa6AXiOv6qHQu9lCAIR8O+/D8FtaCoJ2c0Tf9Xo7hYH01Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
| 12 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js" integrity="sha512-SkmBfuA2hqjzEVpmnMt/LINrjop3GKWqsuLSSB3e7iBmYK7JuWw4ldmmxwD9mdm2IRTTi0OxSAfEGvgEi0i2Kw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
| 13 |
|
| 14 |
-
<script src="static/js/inputboxHandler.js?v={% version %}"></script>
|
| 15 |
-
|
| 16 |
<script src="static/js/windowHandler.js?v={% version %}"></script>
|
| 17 |
<script src="static/js/chatHandler.js?v={% version %}"></script>
|
| 18 |
|
|
@@ -36,15 +35,6 @@
|
|
| 36 |
|
| 37 |
</div>
|
| 38 |
<!--/ Contenedor de chats -->
|
| 39 |
-
|
| 40 |
-
<!-- Caja de entrada y controles -->
|
| 41 |
-
<div class='input-box' id="inputBox">
|
| 42 |
-
<textarea class='input-text' placeholder="Escribe aquí" type="text" autofocus=""></textarea>
|
| 43 |
-
<button class='input-send' ></button>
|
| 44 |
-
<button class='input-menu' ></button>
|
| 45 |
-
<button class='input-delete' ></button>
|
| 46 |
-
</div>
|
| 47 |
-
<!--/ Contenedor de chats -->
|
| 48 |
</div>
|
| 49 |
<!--/ Estructura principal -->
|
| 50 |
|
|
@@ -53,7 +43,7 @@
|
|
| 53 |
|
| 54 |
<!-- Pestaña -->
|
| 55 |
<label class="tab-label-template">
|
| 56 |
-
<div>Tab </div>
|
| 57 |
<input type="radio" name="tabs" class="tab-switch" value=0>
|
| 58 |
</label>
|
| 59 |
<!--/ Pestaña -->
|
|
@@ -61,6 +51,12 @@
|
|
| 61 |
<!-- Contenido Pestaña -->
|
| 62 |
<div class="tab-template">
|
| 63 |
<div class="chat"></div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
|
| 65 |
</div>
|
| 66 |
|
|
@@ -79,7 +75,6 @@
|
|
| 79 |
var cHand;
|
| 80 |
$(document).ready(function() {
|
| 81 |
cHand = new ChatGPT("{% token %}");
|
| 82 |
-
new InputBox();
|
| 83 |
});
|
| 84 |
let versionLocal = localStorage.getItem("version")
|
| 85 |
let versionRemota = "{% version %}"
|
|
|
|
| 11 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js" integrity="sha512-9khQRAUBYEJDCDVP2yw3LRUQvjJ0Pjx0EShmaQjcHa6AXiOv6qHQu9lCAIR8O+/D8FtaCoJ2c0Tf9Xo7hYH01Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
| 12 |
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js" integrity="sha512-SkmBfuA2hqjzEVpmnMt/LINrjop3GKWqsuLSSB3e7iBmYK7JuWw4ldmmxwD9mdm2IRTTi0OxSAfEGvgEi0i2Kw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
| 13 |
|
| 14 |
+
<!-- <script src="static/js/inputboxHandler.js?v={% version %}"></script> -->
|
|
|
|
| 15 |
<script src="static/js/windowHandler.js?v={% version %}"></script>
|
| 16 |
<script src="static/js/chatHandler.js?v={% version %}"></script>
|
| 17 |
|
|
|
|
| 35 |
|
| 36 |
</div>
|
| 37 |
<!--/ Contenedor de chats -->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
</div>
|
| 39 |
<!--/ Estructura principal -->
|
| 40 |
|
|
|
|
| 43 |
|
| 44 |
<!-- Pestaña -->
|
| 45 |
<label class="tab-label-template">
|
| 46 |
+
<div class="tab-name">Tab </div>
|
| 47 |
<input type="radio" name="tabs" class="tab-switch" value=0>
|
| 48 |
</label>
|
| 49 |
<!--/ Pestaña -->
|
|
|
|
| 51 |
<!-- Contenido Pestaña -->
|
| 52 |
<div class="tab-template">
|
| 53 |
<div class="chat"></div>
|
| 54 |
+
<div class='input-box' id="inputBox">
|
| 55 |
+
<textarea class='input-text' placeholder="Escribe aquí" type="text" autofocus=""></textarea>
|
| 56 |
+
<button class='input-send' ></button>
|
| 57 |
+
<button class='input-menu' ></button>
|
| 58 |
+
<button class='input-delete' ></button>
|
| 59 |
+
</div>
|
| 60 |
|
| 61 |
</div>
|
| 62 |
|
|
|
|
| 75 |
var cHand;
|
| 76 |
$(document).ready(function() {
|
| 77 |
cHand = new ChatGPT("{% token %}");
|
|
|
|
| 78 |
});
|
| 79 |
let versionLocal = localStorage.getItem("version")
|
| 80 |
let versionRemota = "{% version %}"
|