akashkolte commited on
Commit
fa02816
·
1 Parent(s): 1f17a48
backend/api/main.py CHANGED
@@ -10,6 +10,7 @@ from pathlib import Path
10
  from fastapi import BackgroundTasks, FastAPI, HTTPException
11
  from fastapi.middleware.cors import CORSMiddleware
12
  from fastapi.responses import StreamingResponse
 
13
  from pydantic import BaseModel, Field
14
 
15
  from backend.config.settings import settings
@@ -976,3 +977,9 @@ def submit_rating(req: RatingRequest):
976
  with open(logs_dir / "ratings.jsonl", "a", encoding="utf-8") as f:
977
  f.write(json.dumps(entry, ensure_ascii=False) + "\n")
978
  return {"status": "ok"}
 
 
 
 
 
 
 
10
  from fastapi import BackgroundTasks, FastAPI, HTTPException
11
  from fastapi.middleware.cors import CORSMiddleware
12
  from fastapi.responses import StreamingResponse
13
+ from fastapi.staticfiles import StaticFiles
14
  from pydantic import BaseModel, Field
15
 
16
  from backend.config.settings import settings
 
977
  with open(logs_dir / "ratings.jsonl", "a", encoding="utf-8") as f:
978
  f.write(json.dumps(entry, ensure_ascii=False) + "\n")
979
  return {"status": "ok"}
980
+
981
+
982
+ # Serve React frontend — must be last so API routes take priority
983
+ _frontend_dist = Path(__file__).parent.parent.parent / "frontend" / "dist"
984
+ if _frontend_dist.exists():
985
+ app.mount("/", StaticFiles(directory=str(_frontend_dist), html=True), name="static")
frontend/src/hooks/useSensing.ts CHANGED
@@ -16,7 +16,7 @@ import {
16
  import { DEFAULT_AIR_TEMPLATES } from "../lib/airTemplates";
17
 
18
  const EMA_ALPHA = 0.2;
19
- const GESTURE_DEBOUNCE_FRAMES = 5;
20
  const AFFECT_DEBOUNCE_FRAMES = 8;
21
 
22
  export function useSensing() {
 
16
  import { DEFAULT_AIR_TEMPLATES } from "../lib/airTemplates";
17
 
18
  const EMA_ALPHA = 0.2;
19
+ const GESTURE_DEBOUNCE_FRAMES = 3;
20
  const AFFECT_DEBOUNCE_FRAMES = 8;
21
 
22
  export function useSensing() {
frontend/src/lib/sensing.ts CHANGED
@@ -104,19 +104,17 @@ export function classifyGesture(landmarks: Point3D[]): GestureName | null {
104
  const pinkyTip = p[20];
105
  const indexMcp = p[5];
106
 
107
- // Require tip to be meaningfully closer to wrist than MCP (0.85×), not just barely under —
108
- // prevents borderline pointing poses from satisfying the curl check.
109
  const fingersCurled = [
110
  [indexTip, p[5]],
111
  [middleTip, p[9]],
112
  [ringTip, p[13]],
113
- ].every(([tip, mcp]) => norm3(tip) < norm3(mcp) * 0.85);
114
 
115
  // Check POINTING before THUMBS_UP — pointing with a raised thumb would otherwise
116
  // satisfy fingersCurled on a noisy frame and fire the wrong label first.
117
  const indexExtended = norm3(indexTip) > norm3(indexMcp) * 1.3;
118
  const othersCurled = [middleTip, ringTip, pinkyTip].every(
119
- (tip) => norm3(tip) < 0.5
120
  );
121
  if (indexExtended && othersCurled) return "POINTING";
122
 
 
104
  const pinkyTip = p[20];
105
  const indexMcp = p[5];
106
 
 
 
107
  const fingersCurled = [
108
  [indexTip, p[5]],
109
  [middleTip, p[9]],
110
  [ringTip, p[13]],
111
+ ].every(([tip, mcp]) => norm3(tip) < norm3(mcp));
112
 
113
  // Check POINTING before THUMBS_UP — pointing with a raised thumb would otherwise
114
  // satisfy fingersCurled on a noisy frame and fire the wrong label first.
115
  const indexExtended = norm3(indexTip) > norm3(indexMcp) * 1.3;
116
  const othersCurled = [middleTip, ringTip, pinkyTip].every(
117
+ (tip) => norm3(tip) < 0.7
118
  );
119
  if (indexExtended && othersCurled) return "POINTING";
120