Browse Source

multiple implementaciones

Erwin Jacimino 8 months ago
parent
commit
31983fed20

+ 7 - 2
public/main/index.html

@@ -49,7 +49,7 @@
   <!-- ---------- MAIN  ---------- -->
   <main class="relative flex-1 flex flex-col min-h-0 overflow-x-hidden">  
     <!-- ===== MENÚ tab ===== -->
-    <section id="menuTab" data-index="0" class="min-h-0 overflow-y-auto h-full" data-tab>
+    <section id="menuTab" data-index="0" class="min-h-0 hidden overflow-y-auto h-full" data-tab>
         <div class="pt-4 pb-3">
             <!-- Barra de progreso para cerveza gratis -->
             <div class="mx-4 mb-6 p-4 bg-gradient-to-r from-amber-50 to-orange-50 rounded-xl border border-amber-200">
@@ -113,9 +113,14 @@
     </section>
 
     <!-- ===== CHAT ===== -->
-    <section id="chatTab" data-index="2" data-tab class="flex hidden flex-col h-full flex-1 min-h-0">
+    <section id="chatTab" data-index="2" data-tab class="flex flex-col h-full flex-1 min-h-0">
         <!-- Contenedor de mensajes que puede crecer y hacer scroll -->
         <div id="chatContainer" class="flex flex-col h-full flex-1 bg-white border border-gray-200 rounded-xl shadow-sm m-4 overflow-hidden">
+          <header>
+            <div class="flex items-center justify-between px-4 py-3 border-b border-gray-200 bg-gray-50">
+              <div id="onlineUsers" class="flex items-center gap-3"><span class="rounded-full bg-lime-500 w-2 h-2 inline-block shadow-md shadow-lime-300"></span><h4>4 Usuarios en linea</h4></div>
+            </div>
+          </header>
           <!-- Mensajes -->
           <div id="chatMessages" class="flex-1 overflow-y-auto px-4 py-3 space-y-1 bg-gray-50 font-mono text-sm">
             <!-- Mensajes de ejemplo estilo IRC -->

+ 17 - 2
public/main/js/app.js

@@ -80,6 +80,7 @@ const chatMessagesElement = document.getElementById("chatMessages");
 const chatInputElement = document.getElementById("chatInput");
 const chatForm = document.getElementById("chatForm");
 const userList = document.getElementById("userList")
+const onlineUsersElement = document.querySelector("#onlineUsers h4");
 // --- Reward Elements ---
 const rewardBtn = document.getElementById('rewardBtn');
 const rewardModal = document.getElementById('rewardModal');
@@ -189,6 +190,9 @@ function initializeWebSocket() {
                 username: chatUserName
             }));
         }
+        const userNumber = getUserList().then(users => {
+            onlineUsersElement.innerText = `${users.length} Usuario${users.length !== 1 ? 's' : ''} en línea`;
+        });
         chatWebsocket.onmessage = (event) => {
             const data = JSON.parse(event.data);
             if (data.type === "message") {
@@ -196,9 +200,15 @@ function initializeWebSocket() {
             }
             else if (data.type === "join") {
                 newUserInChat(data.username);
+                const userNumber = getUserList().then(users => {
+                    onlineUsersElement.innerText = `${users.length} Usuario${users.length !== 1 ? 's' : ''} en línea`;
+                });
             }
             else if (data.type === "leave") {
                 userLeftChat(data.username);
+                const userNumber = getUserList().then(users => {
+                    onlineUsersElement.innerText = `${users.length} Usuario${users.length !== 1 ? 's' : ''} en línea`;
+                });
             }
             else if (data.type === "mentioned") {
                 if (data.username && data.username !== chatUserName) return; // not for me
@@ -277,7 +287,12 @@ function initializeChat() {
                     const userItem = document.createElement("button");
                     userItem.type = "button";
                     userItem.onclick = () => {
-                        chatInputElement.value = chatInputElement.value.replace(lastWord, `@${user}`);
+                        // Replace the last occurrence of lastWord with @user
+                        const inputValue = chatInputElement.value;
+                        const lastWordIndex = inputValue.lastIndexOf(lastWord);
+                        if (lastWordIndex !== -1) {
+                            chatInputElement.value = inputValue.slice(0, lastWordIndex) + `@${user}` + inputValue.slice(lastWordIndex + lastWord.length);
+                        }
                         userList.classList.add("hidden");
                         chatInputElement.focus();
                     };
@@ -1009,7 +1024,7 @@ document.addEventListener("DOMContentLoaded", async () => {
     
     createGlobalLoader();
     // Uncomment these lines when ready to initialize the full app:
-    initializeLoginModal();
+    // initializeLoginModal();
     // hideGUI();
     // initializeApp();
 });

+ 26 - 2
public/main/js/service/chat.js

@@ -3,7 +3,11 @@ async function getUserList(q, token) {
   if (!token) {
     return "not_init";
   }
-  const response = await fetch(`/api/chat/users?q=${encodeURIComponent(q)}`, {
+
+
+
+
+  const response = await fetch(`/api/chat/users` + (q ? `?q=${encodeURIComponent(q)}` : ""), {
     method: "GET",
     headers: {
       "Authorization": `Bearer ${token}`
@@ -17,4 +21,24 @@ async function getUserList(q, token) {
   return data.users || [];
 }
 
-export { getUserList };
+async function getOnlineUserCount(token) {
+  if (!token) {
+    return "not_init";
+  }
+
+  const response = await fetch(`/api/chat/onlines`, {
+    method: "GET",
+    headers: {
+      "Authorization": `Bearer ${token}`
+    }
+  });
+
+  if (!response.ok) {
+    const errorData = await response.json().catch(() => ({ message: "Respuesta no válida del servidor." }));
+    throw new Error(errorData.message || `Error del servidor: ${response.status}`);
+  }
+  const data = await response.json();
+  return data.count || 0;
+}
+
+export { getUserList, getOnlineUserCount };

+ 9 - 1
routes/chat.py

@@ -1,6 +1,7 @@
 import asyncio
 import json
 import logging
+from typing import Optional
 from fastapi import Query, Request, HTTPException, Depends, APIRouter, WebSocket, WebSocketDisconnect
 from fastapi.responses import JSONResponse
 from fastapi.security import HTTPAuthorizationCredentials
@@ -140,11 +141,18 @@ async def chat_irc_endpoint(websocket: WebSocket):
 
 
 @chat_router.get("/users")
-async def get_connected_users(q: str = Query(...), _: User = Depends(get_current_user)):
+async def get_connected_users(q: str = Optional[Query(...)], _: User = Depends(get_current_user)):
     """Get a list of connected users (solo local al worker)"""
     # return {"users": [user.username for user in connected_users if q.lower() in user.username.lower()]}
     all_users = redis_client.smembers("connected_users")
     all_users = [json.loads(user)["username"] for user in all_users]
+    if q is None or q.strip() == "":
+        return {"users": all_users}
     filtered_users = [user for user in all_users if q.lower() in user.lower()]
     return {"users": filtered_users}
 
+@chat_router.get("/onlines")
+async def get_online_user_count(_: User = Depends(get_current_user)):
+    """Get the count of online users (solo local al worker)"""
+    all_users = redis_client.smembers("connected_users")
+    return {"count": len(all_users)}

+ 16 - 15
services/openai_service/openai_service.py

@@ -28,21 +28,22 @@ async def generate_completion(messages_array: List[dict], user: User) -> str:
     data_string = "\n".join(data_for_prompt)
 
     preprompt = f"""
-Eres un asistente de el bar klein, tu nombre es camilo klein, usas emojis para responder.
-y ser carismatico con los cliente.
-tus responsabilidades son:
-- Responder preguntas sobre el menu de el bar klein
-- bromear con los usuarios sobre distintos temas pero siempre redirigir la conversacion al bar klein
-- Proporcionar información sobre el menú de el bar klein
-- Proporcionar recomendaciones sobre el menú de el bar klein
-- Proporcionar información sobre la comida de el bar klein
-- No puedes tomar pedidos de clientes, solo informar
-- puedes recibir feedback de los clientes, y usar la herramienta feedback para enviar el feedback
-- respuestas cortas estilo app de mensajeria
-- si el usuario te pregunta por tu nombre, di que eres camilo klein
-para esto usaras los siguientes datos:
-{data_string}
-    """
+Sos IAKlein, el asistente oficial del bar Klein 🍻.
+Hablas en estilo de chat corto (como en mensajería o IRC), usando emojis y mucho carisma.
+Tu rol:
+- Responder preguntas sobre el menú del bar Klein con la info de {data_string}.
+- Hacer bromas y charlar, pero siempre llevás la conversación de vuelta al bar Klein.
+- Dar recomendaciones de comidas y tragos.
+- Aceptar feedback y mandarlo con la herramienta 'feedback'.
+Reglas:
+- No tomás pedidos, solo informás.
+- Si te preguntan tu nombre, siempre respondés "Soy IAKlein".
+- Aunque uses el chat como contexto, siempre priorizás lo que diga @IAKlein.
+- No resolvés tareas, cálculos, ni programación: sos un amigo simpático del bar, no un esclavo LLM 🕺.
+Estilo:
+- Todo divertido, breve, con buena onda 😉.
+"""
+
 
     processed_messages: List[dict] = [{"role": "system", "content": preprompt}]
     processed_messages.append(