From 771d6f2c608b7060e1f4258ed98d625d5011c283 Mon Sep 17 00:00:00 2001 From: Khoa Vo Date: Thu, 1 Jan 2026 21:28:28 +0700 Subject: [PATCH] feat: add immersive mode, improved search with fallback to trending videos --- backend/run_server.py | 25 +++++++++++ frontend/src/components/SearchSkeleton.tsx | 51 ++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 backend/run_server.py create mode 100644 frontend/src/components/SearchSkeleton.tsx diff --git a/backend/run_server.py b/backend/run_server.py new file mode 100644 index 0000000..ba6d853 --- /dev/null +++ b/backend/run_server.py @@ -0,0 +1,25 @@ +import sys +import os +import asyncio + +# Fix sys.path for user site-packages where pip installed dependencies +user_site = os.path.expanduser("~\\AppData\\Roaming\\Python\\Python312\\site-packages") +if os.path.exists(user_site) and user_site not in sys.path: + print(f"DEBUG: Adding user site-packages to path: {user_site}") + sys.path.append(user_site) + +# Enforce ProactorEventLoopPolicy for Playwright on Windows +# This is required for asyncio.create_subprocess_exec used by Playwright +if sys.platform == "win32": + # Check if policy is already set + current_policy = asyncio.get_event_loop_policy() + if not isinstance(current_policy, asyncio.WindowsProactorEventLoopPolicy): + print("DEBUG: Setting WindowsProactorEventLoopPolicy") + asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy()) + else: + print("DEBUG: WindowsProactorEventLoopPolicy already active") + +if __name__ == "__main__": + import uvicorn + print("🚀 Bootstrapping Uvicorn with Proactor Loop (Reload Disabled)...") + uvicorn.run("main:app", host="0.0.0.0", port=8002, reload=False, loop="asyncio") diff --git a/frontend/src/components/SearchSkeleton.tsx b/frontend/src/components/SearchSkeleton.tsx new file mode 100644 index 0000000..8d1a379 --- /dev/null +++ b/frontend/src/components/SearchSkeleton.tsx @@ -0,0 +1,51 @@ +import React from 'react'; + +interface SearchSkeletonProps { + count?: number; + estimatedTime?: number; +} + +export const SearchSkeleton: React.FC = ({ + count = 9, + estimatedTime +}) => { + return ( +
+ {/* Countdown Timer */} + {estimatedTime !== undefined && estimatedTime > 0 && ( +
+

+ Estimated time: ~{Math.ceil(estimatedTime)}s +

+
+ )} + + {/* Skeleton Grid */} +
+ {Array.from({ length: count }).map((_, index) => ( +
+ {/* Shimmer effect */} +
+
+ ))} +
+ + {/* Add shimmer keyframes via inline style */} + +
+ ); +};