zeroed-some/bashamole / 2edb0eb

Browse files

refactor visuals stable

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
2edb0eb9c91b7fde223cb8b9311a3bc509a0056e
Parents
9709dd7
Tree
826295e

2 changed files

StatusFile+-
M frontend/src/components/Game.tsx 63 62
M frontend/src/components/TreeVisualizer.tsx 7 3
frontend/src/components/Game.tsxmodified
@@ -41,6 +41,13 @@ const Game: React.FC = () => {
4141
     }
4242
   }, [commandHistory]);
4343
 
44
+  // Auto-focus input after command execution
45
+  useEffect(() => {
46
+    if (!executing && inputRef.current && !terminalMinimized) {
47
+      inputRef.current.focus();
48
+    }
49
+  }, [executing, terminalMinimized]);
50
+
4451
   // Start a new game
4552
   const startNewGame = async () => {
4653
     try {
@@ -133,7 +140,7 @@ const Game: React.FC = () => {
133140
       }]);
134141
     } finally {
135142
       setExecuting(false);
136
-      inputRef.current?.focus();
143
+      // Focus will be restored by useEffect
137144
     }
138145
   };
139146
 
@@ -224,59 +231,8 @@ const Game: React.FC = () => {
224231
         />
225232
       </div>
226233
 
227
-      {/* Top Header Bar */}
228
-      <div className="absolute top-0 left-0 right-0 bg-gray-900/90 backdrop-blur-sm border-b border-gray-700 p-4 z-20">
229
-        <div className="max-w-7xl mx-auto flex justify-between items-center">
230
-          <div className="flex items-center gap-4">
231
-            <h1 className="text-2xl font-bold">🐭 Bashamole</h1>
232
-            <div className="text-sm text-gray-400">
233
-              Location: <span className="font-mono text-blue-400">{gameState.tree.player_location}</span>
234
-            </div>
235
-          </div>
236
-          
237
-          <div className="flex items-center gap-3">
238
-            {gameState.tree.is_completed ? (
239
-              <div className="text-green-400 font-bold animate-pulse">
240
-                🎉 You found the mole!
241
-              </div>
242
-            ) : (
243
-              <>
244
-                <button
245
-                  onClick={getHints}
246
-                  className="px-3 py-1.5 bg-yellow-600 text-white text-sm rounded hover:bg-yellow-700 transition"
247
-                >
248
-                  Get Hint 💡
249
-                </button>
250
-                <button
251
-                  onClick={startNewGame}
252
-                  className="px-3 py-1.5 bg-gray-700 text-white text-sm rounded hover:bg-gray-600 transition"
253
-                >
254
-                  New Game
255
-                </button>
256
-              </>
257
-            )}
258
-          </div>
259
-        </div>
260
-      </div>
261
-
262
-      {/* Hints Popup */}
263
-      {showHints && hints.length > 0 && (
264
-        <div className="absolute top-20 left-1/2 transform -translate-x-1/2 bg-yellow-900/95 backdrop-blur-sm border border-yellow-600 rounded-lg p-4 max-w-md z-30 shadow-2xl">
265
-          <button
266
-            onClick={() => setShowHints(false)}
267
-            className="absolute top-2 right-2 text-yellow-400 hover:text-yellow-300"
268
-          >
269
-            ✕
270
-          </button>
271
-          <h3 className="text-yellow-400 font-bold mb-2">💡 Hints:</h3>
272
-          {hints.map((hint, index) => (
273
-            <p key={index} className="text-yellow-200 text-sm">{hint}</p>
274
-          ))}
275
-        </div>
276
-      )}
277
-
278
-      {/* Floating Terminal */}
279
-      <div className={`absolute bottom-4 left-4 bg-gray-800/95 backdrop-blur-sm rounded-lg shadow-2xl border border-gray-700 transition-all duration-300 z-30 ${
234
+      {/* Floating Terminal - Top Left */}
235
+      <div className={`absolute top-4 left-4 bg-gray-800/95 backdrop-blur-sm rounded-lg shadow-2xl border border-gray-700 transition-all duration-300 z-30 ${
280236
         terminalMinimized ? 'w-80' : 'w-[500px]'
281237
       }`}>
282238
         {/* Terminal Header */}
@@ -286,7 +242,7 @@ const Game: React.FC = () => {
286242
             onClick={() => setTerminalMinimized(!terminalMinimized)}
287243
             className="text-gray-400 hover:text-white transition"
288244
           >
289
-            {terminalMinimized ? '▲' : '▼'}
245
+            {terminalMinimized ? '▼' : '▲'}
290246
           </button>
291247
         </div>
292248
 
@@ -341,13 +297,58 @@ const Game: React.FC = () => {
341297
         )}
342298
       </div>
343299
 
344
-      {/* Instructions - Bottom Right */}
345
-      <div className="absolute bottom-4 right-4 bg-gray-800/80 backdrop-blur-sm rounded-lg p-3 text-xs text-gray-400 max-w-xs z-20">
346
-        <div className="font-semibold text-gray-300 mb-1">Controls:</div>
347
-        <div>• Click nodes to navigate</div>
348
-        <div>• Scroll to zoom, drag to pan</div>
349
-        <div>• Type commands in terminal</div>
350
-        <div className="mt-1 text-gray-500">Find and eliminate the mole!</div>
300
+      {/* Hints Popup */}
301
+      {showHints && hints.length > 0 && (
302
+        <div className="absolute top-20 left-1/2 transform -translate-x-1/2 bg-yellow-900/95 backdrop-blur-sm border border-yellow-600 rounded-lg p-4 max-w-md z-30 shadow-2xl">
303
+          <button
304
+            onClick={() => setShowHints(false)}
305
+            className="absolute top-2 right-2 text-yellow-400 hover:text-yellow-300"
306
+          >
307
+            ✕
308
+          </button>
309
+          <h3 className="text-yellow-400 font-bold mb-2">💡 Hints:</h3>
310
+          {hints.map((hint, index) => (
311
+            <p key={index} className="text-yellow-200 text-sm">{hint}</p>
312
+          ))}
313
+        </div>
314
+      )}
315
+
316
+      {/* Bottom Game Bar */}
317
+      <div className="absolute bottom-0 left-0 right-0 bg-gray-900/90 backdrop-blur-sm border-t border-gray-700 p-4 z-20">
318
+        <div className="max-w-7xl mx-auto flex justify-between items-center">
319
+          <div className="flex items-center gap-4">
320
+            <h1 className="text-2xl font-bold">🐭 Bashamole</h1>
321
+            <div className="text-sm text-gray-400">
322
+              Location: <span className="font-mono text-blue-400">{gameState.tree.player_location}</span>
323
+            </div>
324
+          </div>
325
+          
326
+          <div className="flex items-center gap-3">
327
+            {gameState.tree.is_completed ? (
328
+              <div className="text-green-400 font-bold animate-pulse">
329
+                🎉 You found the mole!
330
+              </div>
331
+            ) : (
332
+              <>
333
+                <button
334
+                  onClick={getHints}
335
+                  className="px-3 py-1.5 bg-yellow-600 text-white text-sm rounded hover:bg-yellow-700 transition"
336
+                >
337
+                  Get Hint 💡
338
+                </button>
339
+                <div className="text-xs text-gray-500">
340
+                  Click nodes or use terminal
341
+                </div>
342
+              </>
343
+            )}
344
+            <button
345
+              onClick={startNewGame}
346
+              className="px-3 py-1.5 bg-gray-700 text-white text-sm rounded hover:bg-gray-600 transition"
347
+            >
348
+              New Game
349
+            </button>
350
+          </div>
351
+        </div>
351352
       </div>
352353
     </div>
353354
   );
frontend/src/components/TreeVisualizer.tsxmodified
@@ -72,7 +72,7 @@ const TreeVisualizer: React.FC<TreeVisualizerProps> = ({
7272
       .append('g')
7373
       .attr('transform', `translate(${width / 2},${margin.top})`);
7474
 
75
-    // Create tree layout - vertical orientation
75
+    // Create tree layout - vertical orientation with more spacing
7676
     const treeLayout = d3
7777
       .tree<TreeNode>()
7878
       .size([width - margin.left - margin.right, height - margin.top - margin.bottom])
@@ -80,10 +80,14 @@ const TreeVisualizer: React.FC<TreeVisualizerProps> = ({
8080
         const aIsLeaf = !a.children || a.children.length === 0;
8181
         const bIsLeaf = !b.children || b.children.length === 0;
8282
         
83
+        // Much more spacing for leaf nodes to prevent crowding
8384
         if (aIsLeaf && bIsLeaf) {
84
-          return 1.5;
85
+          return 3; // Increased from 1.5
8586
         }
86
-        return a.parent === b.parent ? 1 : 1.2;
87
+        if (aIsLeaf || bIsLeaf) {
88
+          return 2.5; // Mixed leaf/non-leaf
89
+        }
90
+        return a.parent === b.parent ? 2 : 2.5; // Increased general spacing
8791
       });
8892
 
8993
     // Create hierarchy