Justxd22 commited on
Commit
413b9b9
·
1 Parent(s): d1b8835

feat: Add modal and notification system for investigation tools and enhance README with Docker runtime

Browse files
Dockerfile ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Use an official lightweight Python image
2
+ FROM python:3.10-slim
3
+
4
+ # Prevent Python from writing .pyc files and buffering stdout
5
+ ENV PYTHONDONTWRITEBYTECODE=1
6
+ ENV PYTHONUNBUFFERED=1
7
+
8
+ # Create a working directory
9
+ WORKDIR /app
10
+
11
+ # Copy requirements first to leverage Docker layer caching
12
+ COPY requirements.txt .
13
+
14
+ # Install dependencies
15
+ RUN pip install --no-cache-dir -r requirements.txt
16
+
17
+ # Copy the rest of the app
18
+ COPY . .
19
+
20
+ # Expose port (HF Spaces typically use 7860 for Gradio/Streamlit)
21
+ EXPOSE 7860
22
+
23
+ # Command to run the app
24
+ CMD ["python", "app.py"]
README.md CHANGED
@@ -8,6 +8,7 @@ sdk_version: 6.0.1
8
  app_file: app.py
9
  pinned: false
10
  license: gpl-3.0
 
11
  short_description: Even AI has something to hide
12
  tags:
13
  - building-mcp-track-creative
 
8
  app_file: app.py
9
  pinned: false
10
  license: gpl-3.0
11
+ runtime: docker
12
  short_description: Even AI has something to hide
13
  tags:
14
  - building-mcp-track-creative
ui/static/css/noir.css CHANGED
@@ -403,4 +403,107 @@ button.send-btn:hover {
403
 
404
  @keyframes spin {
405
  to { transform: rotate(360deg); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
406
  }
 
403
 
404
  @keyframes spin {
405
  to { transform: rotate(360deg); }
406
+ }
407
+
408
+ /* --- Tool Modal --- */
409
+ .modal-overlay {
410
+ position: fixed;
411
+ top: 0;
412
+ left: 0;
413
+ width: 100%;
414
+ height: 100%;
415
+ background: rgba(0, 0, 0, 0.6);
416
+ backdrop-filter: blur(5px);
417
+ z-index: 200;
418
+ display: none;
419
+ align-items: center;
420
+ justify-content: center;
421
+ }
422
+
423
+ .modal-overlay.active {
424
+ display: flex;
425
+ }
426
+
427
+ .modal-content {
428
+ background: var(--paper-color);
429
+ padding: 20px;
430
+ width: 400px;
431
+ border: 1px solid #555;
432
+ box-shadow: 0 10px 30px rgba(0,0,0,0.8);
433
+ font-family: 'Special Elite', cursive;
434
+ color: var(--ink-color);
435
+ transform: rotate(-1deg);
436
+ }
437
+
438
+ .modal-header {
439
+ font-size: 1.2rem;
440
+ border-bottom: 2px solid var(--ink-color);
441
+ margin-bottom: 15px;
442
+ padding-bottom: 5px;
443
+ font-weight: bold;
444
+ }
445
+
446
+ .modal-input {
447
+ width: 100%;
448
+ padding: 10px;
449
+ margin: 10px 0 20px 0;
450
+ background: rgba(255,255,255,0.5);
451
+ border: 1px solid #888;
452
+ font-family: 'Courier New', monospace;
453
+ font-size: 1.1rem;
454
+ color: #000;
455
+ box-sizing: border-box;
456
+ }
457
+
458
+ .modal-actions {
459
+ display: flex;
460
+ justify-content: flex-end;
461
+ gap: 10px;
462
+ }
463
+
464
+ .modal-btn {
465
+ padding: 8px 15px;
466
+ border: 1px solid #333;
467
+ cursor: pointer;
468
+ font-family: 'Special Elite', cursive;
469
+ transition: all 0.2s;
470
+ }
471
+
472
+ .modal-btn.confirm {
473
+ background: var(--desk-color);
474
+ color: #eee;
475
+ }
476
+
477
+ .modal-btn.confirm:hover {
478
+ background: #444;
479
+ }
480
+
481
+ .modal-btn.cancel {
482
+ background: transparent;
483
+ color: #333;
484
+ }
485
+
486
+ .modal-btn.cancel:hover {
487
+ text-decoration: line-through;
488
+ }
489
+
490
+ /* --- Notification Toast --- */
491
+ #notification-toast {
492
+ position: fixed;
493
+ bottom: 30px;
494
+ left: 50%;
495
+ transform: translateX(-50%) translateY(100px);
496
+ background: rgba(0, 0, 0, 0.8);
497
+ color: white;
498
+ padding: 10px 20px;
499
+ border-radius: 5px;
500
+ font-family: 'Special Elite', cursive;
501
+ z-index: 300;
502
+ transition: transform 0.3s ease-out;
503
+ border: 1px solid #555;
504
+ box-shadow: 0 5px 15px rgba(0,0,0,0.5);
505
+ }
506
+
507
+ #notification-toast.show {
508
+ transform: translateX(-50%) translateY(0);
509
  }
ui/static/js/game_logic.js CHANGED
@@ -141,9 +141,20 @@ function renderSuspects() {
141
  }, 500);
142
  }
143
 
 
 
 
 
 
 
 
 
 
 
 
144
  function copyToClipboard(text) {
145
  navigator.clipboard.writeText(text).then(() => {
146
- alert("Copied: " + text);
147
  }).catch(err => {
148
  console.error('Failed to copy: ', err);
149
  });
@@ -319,15 +330,48 @@ function makeDraggable(elmnt) {
319
 
320
  // --- Tools ---
321
 
 
 
322
  function useTool(toolName) {
323
- const input = prompt(`Enter input for ${toolName} (e.g., phone number):`);
324
- if (input) {
325
- sendAction('use_tool', { tool: toolName, input: input });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
  }
327
  }
328
 
 
 
 
 
 
329
  // --- Listeners ---
330
 
 
 
 
 
 
 
331
  document.getElementById('send-btn').addEventListener('click', sendUserMessage);
332
  document.getElementById('chat-input').addEventListener('keypress', function (e) {
333
  if (e.key === 'Enter' && !e.shiftKey) {
 
141
  }, 500);
142
  }
143
 
144
+ // --- Modal & Notifications ---
145
+
146
+ function showNotification(message) {
147
+ const toast = document.getElementById('notification-toast');
148
+ toast.innerText = message;
149
+ toast.classList.add('show');
150
+ setTimeout(() => {
151
+ toast.classList.remove('show');
152
+ }, 2000);
153
+ }
154
+
155
  function copyToClipboard(text) {
156
  navigator.clipboard.writeText(text).then(() => {
157
+ showNotification("COPIED: " + text);
158
  }).catch(err => {
159
  console.error('Failed to copy: ', err);
160
  });
 
330
 
331
  // --- Tools ---
332
 
333
+ let pendingTool = null;
334
+
335
  function useTool(toolName) {
336
+ pendingTool = toolName;
337
+ const modal = document.getElementById('tool-modal');
338
+ const input = document.getElementById('modal-input');
339
+ const promptText = document.getElementById('modal-prompt-text');
340
+
341
+ // Custom prompts
342
+ if (toolName === 'get_location') promptText.innerText = "Enter Target Phone Number:";
343
+ if (toolName === 'call_alibi') promptText.innerText = "Enter Witness Phone Number:";
344
+ if (toolName === 'get_dna_test') promptText.innerText = "Enter Evidence ID:";
345
+ if (toolName === 'get_footage') promptText.innerText = "Enter Camera Location:";
346
+
347
+ input.value = '';
348
+ modal.classList.add('active');
349
+ input.focus();
350
+ }
351
+
352
+ function submitTool() {
353
+ const input = document.getElementById('modal-input');
354
+ const value = input.value.trim();
355
+
356
+ if (value && pendingTool) {
357
+ sendAction('use_tool', { tool: pendingTool, input: value });
358
+ closeModal();
359
  }
360
  }
361
 
362
+ function closeModal() {
363
+ document.getElementById('tool-modal').classList.remove('active');
364
+ pendingTool = null;
365
+ }
366
+
367
  // --- Listeners ---
368
 
369
+ document.getElementById('modal-cancel').onclick = closeModal;
370
+ document.getElementById('modal-confirm').onclick = submitTool;
371
+ document.getElementById('modal-input').addEventListener('keypress', function (e) {
372
+ if (e.key === 'Enter') submitTool();
373
+ });
374
+
375
  document.getElementById('send-btn').addEventListener('click', sendUserMessage);
376
  document.getElementById('chat-input').addEventListener('keypress', function (e) {
377
  if (e.key === 'Enter' && !e.shiftKey) {
ui/templates/game_interface.html CHANGED
@@ -74,6 +74,22 @@
74
 
75
  </div>
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  <script src="../static/js/game_logic.js"></script>
78
  </body>
79
  </html>
 
74
 
75
  </div>
76
 
77
+ <!-- Tool Input Modal -->
78
+ <div id="tool-modal" class="modal-overlay">
79
+ <div class="modal-content">
80
+ <div class="modal-header">INVESTIGATION TOOL</div>
81
+ <div id="modal-prompt-text">Enter details:</div>
82
+ <input type="text" id="modal-input" class="modal-input" placeholder="...">
83
+ <div class="modal-actions">
84
+ <button id="modal-cancel" class="modal-btn cancel">CANCEL</button>
85
+ <button id="modal-confirm" class="modal-btn confirm">SUBMIT</button>
86
+ </div>
87
+ </div>
88
+ </div>
89
+
90
+ <!-- Notification Toast -->
91
+ <div id="notification-toast">Notification</div>
92
+
93
  <script src="../static/js/game_logic.js"></script>
94
  </body>
95
  </html>