+
} label="AeThex Studio" color="from-purple-900/40 to-pink-900/40" onPress={() => handleNav('/mobile/studio')} />
+
} label="App Store" color="from-blue-900/40 to-cyan-900/40" onPress={() => handleNav('/mobile/appstore')} />
} label="Capture" color="from-blue-900/40 to-purple-900/40" onPress={() => handleNav('/camera')} />
} label="Alerts" color="from-red-900/40 to-pink-900/40" badge="3" onPress={() => handleNav('/notifications')} />
} label="Modules" color="from-emerald-900/40 to-cyan-900/40" onPress={() => handleNav('/hub/code-gallery')} />
diff --git a/client/src/pages/os.tsx b/client/src/pages/os.tsx
index bedfdaf..038ef88 100644
--- a/client/src/pages/os.tsx
+++ b/client/src/pages/os.tsx
@@ -14,6 +14,53 @@ import { StatusBar, Style } from '@capacitor/status-bar';
import { MobileQuickActions } from "@/components/MobileQuickActions";
import { Minesweeper } from "@/components/games/Minesweeper";
import { CookieClicker } from "@/components/games/CookieClicker";
+import AethexStudio from "@/components/AethexStudio";
+import AethexAppStore from "@/components/AethexAppStore";
+import { BootSequence } from "@/os/boot/BootSequence";
+import { Taskbar } from "@/os/core/Taskbar";
+import { TerminalApp } from "@/os/apps/TerminalApp";
+import { PassportApp } from "@/os/apps/PassportApp";
+import { SettingsApp, WALLPAPERS, ACCENT_COLORS, ThemeSettings, DesktopLayout } from "@/os/apps/SettingsApp";
+import { FilesApp } from "@/os/apps/FilesApp";
+import { AchievementsApp } from "@/os/apps/AchievementsApp";
+import { OpportunitiesApp } from "@/os/apps/OpportunitiesApp";
+import { EventsApp } from "@/os/apps/EventsApp";
+import { ChatApp } from "@/os/apps/ChatApp";
+import { ManifestoApp } from "@/os/apps/ManifestoApp";
+import { MusicApp } from "@/os/apps/MusicApp";
+import { PitchApp } from "@/os/apps/PitchApp";
+import { NetworkMapApp } from "@/os/apps/NetworkMapApp";
+import { MetricsDashboardApp } from "@/os/apps/MetricsDashboardApp";
+import { CodeEditorApp } from "@/os/apps/CodeEditorApp";
+import { NewsFeedApp } from "@/os/apps/NewsFeedApp";
+import { ArcadeApp } from "@/os/apps/ArcadeApp";
+import { ProfilesApp } from "@/os/apps/ProfilesApp";
+import { NetworkNeighborhoodApp } from "@/os/apps/NetworkNeighborhoodApp";
+import { FoundryApp } from "@/os/apps/FoundryApp";
+import { DevToolsApp } from "@/os/apps/DevToolsApp";
+import { IntelApp } from "@/os/apps/IntelApp";
+import { DrivesApp } from "@/os/apps/DrivesApp";
+import { MissionApp } from "@/os/apps/MissionApp";
+import { LeaderboardApp } from "@/os/apps/LeaderboardApp";
+import { CalculatorApp } from "@/os/apps/CalculatorApp";
+import { NotesApp } from "@/os/apps/NotesApp";
+import { SystemMonitorApp } from "@/os/apps/SystemMonitorApp";
+import { WebcamApp } from "@/os/apps/WebcamApp";
+import {
+ ProjectsAppWrapper,
+ MessagingAppWrapper,
+ MarketplaceAppWrapper,
+ FileManagerAppWrapper,
+ CodeGalleryAppWrapper,
+ NotificationsAppWrapper,
+ AnalyticsAppWrapper
+} from "@/os/apps/IframeWrappers";
+import { DesktopWidgets, DraggableWidget, WidgetPosition, WidgetPositions, getDefaultWidgetPositions } from "@/os/components/Widgets";
+import { DesktopIcon, ContextMenuComponent, MenuItem } from "@/os/components/Desktop";
+import { Window } from "@/os/components/Window";
+import { Skeleton, LoadingSkeleton, ParticleField } from "@/os/components/UI";
+import { SpotlightSearch, ToastContainer, OnboardingTour } from "@/os/components/Overlays";
+import { OSProviders, useWindows, useDesktop, useSettings, useNotifications } from "@/os/contexts";
import {
Terminal, FileText, IdCard, Music, Settings, Globe,
X, Minus, Square, Maximize2, Volume2, Wifi, Battery,
@@ -26,7 +73,8 @@ import {
TrendingUp, ArrowUp, ArrowDown, Hash, Key, HardDrive, FolderSearch,
AlertTriangle, Briefcase, CalendarDays, FolderGit2, MessageSquare,
ShoppingCart, Folder, Code, Home, Flag, Cookie, ChevronLeft,
- MoreVertical, Search, Mic, ArrowLeft, RefreshCw, Star, Clock, MapPin
+ MoreVertical, Search, Mic, ArrowLeft, RefreshCw, Star, Clock, MapPin,
+ Store, Rocket
} from "lucide-react";
interface WindowState {
@@ -52,27 +100,6 @@ interface Toast {
type: 'info' | 'success' | 'warning' | 'error';
}
-interface ThemeSettings {
- mode: 'dark' | 'light' | 'system';
- accentColor: string;
- transparency: number;
-}
-
-interface DesktopLayout {
- name: string;
- windows: Array<{ appId: string; x: number; y: number; width: number; height: number }>;
- desktop: number;
-}
-
-const ACCENT_COLORS = [
- { id: 'cyan', name: 'Cyan', color: '#06b6d4', ring: 'ring-cyan-400/50', shadow: 'shadow-cyan-500/20', bg: 'bg-cyan-500' },
- { id: 'purple', name: 'Purple', color: '#a855f7', ring: 'ring-purple-400/50', shadow: 'shadow-purple-500/20', bg: 'bg-purple-500' },
- { id: 'green', name: 'Green', color: '#22c55e', ring: 'ring-green-400/50', shadow: 'shadow-green-500/20', bg: 'bg-green-500' },
- { id: 'orange', name: 'Orange', color: '#f97316', ring: 'ring-orange-400/50', shadow: 'shadow-orange-500/20', bg: 'bg-orange-500' },
- { id: 'pink', name: 'Pink', color: '#ec4899', ring: 'ring-pink-400/50', shadow: 'shadow-pink-500/20', bg: 'bg-pink-500' },
- { id: 'red', name: 'Red', color: '#ef4444', ring: 'ring-red-400/50', shadow: 'shadow-red-500/20', bg: 'bg-red-500' },
-];
-
type ClearanceMode = 'foundation' | 'corp';
interface ClearanceTheme {
@@ -150,69 +177,83 @@ interface ContextMenuState {
}
const WALLPAPERS = [
- { id: 'default', name: 'Cyber Grid', bg: 'linear-gradient(to bottom right, #0f172a, #1e1b4b, #0f172a)', secret: false },
- { id: 'matrix', name: 'Matrix', bg: 'linear-gradient(to bottom, #001100, #002200, #001100)', secret: false },
- { id: 'sunset', name: 'Neon Sunset', bg: 'linear-gradient(to bottom, #1a0533, #4a1942, #0f172a)', secret: false },
- { id: 'ocean', name: 'Deep Ocean', bg: 'linear-gradient(to bottom, #0a1628, #0d3b66, #0a1628)', secret: false },
- { id: 'vaporwave', name: '⚡ Vaporwave', bg: 'linear-gradient(135deg, #ff71ce, #01cdfe, #05ffa1, #b967ff)', secret: true },
- { id: 'bloodmoon', name: '🔥 Blood Moon', bg: 'linear-gradient(to bottom, #1a0000, #4a0000, #1a0000)', secret: true },
- { id: 'galaxy', name: '🌌 Galaxy', bg: 'radial-gradient(ellipse at center, #1b2735 0%, #090a0f 100%)', secret: true },
];
const KONAMI_CODE = ['ArrowUp', 'ArrowUp', 'ArrowDown', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'ArrowLeft', 'ArrowRight', 'b', 'a'];
-export default function AeThexOS() {
+function AeThexOSInner() {
const layout = usePlatformLayout();
const { impact, notification } = useHaptics();
const { keyboardVisible, deviceInfo } = useMobileNative('dark');
const native = useNativeFeatures();
const biometric = useBiometricAuth();
- // Skip boot sequence on mobile
+ // Context hooks
+ const windowContext = useWindows();
+ const {
+ currentDesktop,
+ desktopIcons,
+ showStartMenu,
+ contextMenu,
+ mousePosition,
+ setCurrentDesktop,
+ setDesktopIcons,
+ setShowStartMenu,
+ toggleStartMenu,
+ setContextMenu,
+ setMousePosition,
+ getDesktopWindowCount
+ } = useDesktop();
+ const {
+ theme,
+ wallpaper,
+ soundEnabled,
+ clearanceMode,
+ clearanceTheme,
+ isSwitchingClearance,
+ savedLayouts,
+ setTheme,
+ setWallpaper,
+ setSoundEnabled,
+ setClearanceMode,
+ setIsSwitchingClearance,
+ setSavedLayouts
+ } = useSettings();
+ const {
+ toasts,
+ notifications,
+ showNotifications,
+ addToast,
+ addNotification,
+ clearNotification,
+ clearAllNotifications,
+ setShowNotifications,
+ toggleNotifications
+ } = useNotifications();
+
+ // Local state (not moved to context)
const [isBooting, setIsBooting] = useState(!layout.isMobile);
const [bootProgress, setBootProgress] = useState(0);
const [bootStep, setBootStep] = useState('');
- const [windows, setWindows] = useState
([]);
- const [activeWindowId, setActiveWindowId] = useState(null);
- const [maxZIndex, setMaxZIndex] = useState(1);
- const [showStartMenu, setShowStartMenu] = useState(false);
const [time, setTime] = useState(new Date());
- const [contextMenu, setContextMenu] = useState(null);
- const [wallpaper, setWallpaper] = useState(WALLPAPERS[0]);
- const [soundEnabled, setSoundEnabled] = useState(false);
const [showScreensaver, setShowScreensaver] = useState(false);
- const [notifications, setNotifications] = useState([]);
- const [showNotifications, setShowNotifications] = useState(false);
const [secretsUnlocked, setSecretsUnlocked] = useState(false);
const [konamiProgress, setKonamiProgress] = useState([]);
- const [toasts, setToasts] = useState([]);
const [showSpotlight, setShowSpotlight] = useState(false);
const [spotlightQuery, setSpotlightQuery] = useState('');
- const [currentDesktop, setCurrentDesktop] = useState(0);
const [showOnboarding, setShowOnboarding] = useState(false);
const [onboardingStep, setOnboardingStep] = useState(0);
- const [desktopIcons, setDesktopIcons] = useState([]);
- const [theme, setTheme] = useState(() => {
- const saved = localStorage.getItem('aethex-theme');
- return saved ? JSON.parse(saved) : { mode: 'dark', accentColor: 'cyan', transparency: 80 };
- });
- const [savedLayouts, setSavedLayouts] = useState(() => {
- const saved = localStorage.getItem('aethex-layouts');
- return saved ? JSON.parse(saved) : [];
- });
- const [clearanceMode, setClearanceMode] = useState(() => {
- const saved = localStorage.getItem('aethex-clearance');
- return (saved as ClearanceMode) || 'foundation';
- });
- const [isSwitchingClearance, setIsSwitchingClearance] = useState(false);
const [showDailyTip, setShowDailyTip] = useState(false);
const [dailyTip, setDailyTip] = useState(DAILY_TIPS[0]);
- const [mousePosition, setMousePosition] = useState({ x: 0, y: 0 });
const audioContextRef = useRef(null);
- const clearanceTheme = CLEARANCE_THEMES[clearanceMode];
const desktopRef = useRef(null);
const idleTimer = useRef(null);
const spotlightRef = useRef(null);
+
+ // Motion values for mobile gestures (must be declared before any conditional returns)
+ const dragX = useMotionValue(0);
+ const dragOpacity = useTransform(dragX, [-200, 0, 200], [0.5, 1, 0.5]);
+
const { user, isAuthenticated, logout } = useAuth();
const [, setLocation] = useLocation();
const [activeTrayPanel, setActiveTrayPanel] = useState<'wifi' | 'volume' | 'battery' | 'notifications' | 'upgrade' | null>(null);
@@ -270,24 +311,6 @@ export default function AeThexOS() {
staleTime: 300000,
});
- const addToast = useCallback((message: string, type: Toast['type'] = 'info') => {
- const id = Date.now().toString();
- setToasts(prev => [...prev, { id, message, type }]);
- setTimeout(() => setToasts(prev => prev.filter(t => t.id !== id)), 4000);
- }, []);
-
- useEffect(() => {
- localStorage.setItem('aethex-theme', JSON.stringify(theme));
- }, [theme]);
-
- useEffect(() => {
- localStorage.setItem('aethex-layouts', JSON.stringify(savedLayouts));
- }, [savedLayouts]);
-
- useEffect(() => {
- localStorage.setItem('aethex-clearance', clearanceMode);
- }, [clearanceMode]);
-
useEffect(() => {
const handleMouseMove = (e: MouseEvent) => {
setMousePosition({ x: e.clientX, y: e.clientY });
@@ -596,6 +619,8 @@ export default function AeThexOS() {
{ id: "arcade", title: "Snake", icon: , component: "arcade", defaultWidth: 420, defaultHeight: 520 },
{ id: "minesweeper", title: "Minesweeper", icon: , component: "minesweeper", defaultWidth: 400, defaultHeight: 500 },
{ id: "cookieclicker", title: "Cookie Clicker", icon: , component: "cookieclicker", defaultWidth: 420, defaultHeight: 600 },
+ { id: "aethexstudio", title: "AeThex Studio", icon: , component: "aethexstudio", defaultWidth: 1200, defaultHeight: 700 },
+ { id: "aethexappstore", title: "App Store", icon: , component: "aethexappstore", defaultWidth: 1000, defaultHeight: 650 },
{ id: "calculator", title: "Calculator", icon: , component: "calculator", defaultWidth: 320, defaultHeight: 450 },
{ id: "settings", title: "Settings", icon: , component: "settings", defaultWidth: 550, defaultHeight: 500 },
];
@@ -624,6 +649,8 @@ export default function AeThexOS() {
{ id: "pitch", title: "Contracts", icon: , component: "pitch", defaultWidth: 500, defaultHeight: 400 },
{ id: "sysmonitor", title: "Infrastructure", icon: , component: "sysmonitor", defaultWidth: 450, defaultHeight: 400 },
{ id: "leaderboard", title: "Performance", icon: , component: "leaderboard", defaultWidth: 500, defaultHeight: 550 },
+ { id: "aethexstudio", title: "AeThex Studio", icon: , component: "aethexstudio", defaultWidth: 1200, defaultHeight: 700 },
+ { id: "aethexappstore", title: "App Store", icon: , component: "aethexappstore", defaultWidth: 1000, defaultHeight: 650 },
{ id: "calculator", title: "Calculator", icon: , component: "calculator", defaultWidth: 320, defaultHeight: 450 },
{ id: "settings", title: "Settings", icon: , component: "settings", defaultWidth: 550, defaultHeight: 500 },
];
@@ -711,20 +738,16 @@ export default function AeThexOS() {
: app;
playSound('open');
- const existingWindow = windows.find(w => w.id === appToOpen.id);
+ const existingWindow = windowContext.windows.find(w => w.id === appToOpen.id);
if (existingWindow) {
- setWindows(prev => prev.map(w =>
- w.id === appToOpen.id ? { ...w, minimized: false, zIndex: maxZIndex + 1, desktopId: currentDesktop } : w
- ));
- setMaxZIndex(prev => prev + 1);
- setActiveWindowId(appToOpen.id);
+ windowContext.focusWindow(appToOpen.id);
return;
}
- const offsetX = (windows.length % 5) * 40 + 100;
- const offsetY = (windows.length % 5) * 40 + 50;
+ const offsetX = (windowContext.windows.length % 5) * 40 + 100;
+ const offsetY = (windowContext.windows.length % 5) * 40 + 50;
- const newWindow: WindowState = {
+ const newWindow = {
id: appToOpen.id,
title: appToOpen.title,
icon: appToOpen.icon,
@@ -735,36 +758,30 @@ export default function AeThexOS() {
height: appToOpen.defaultHeight,
minimized: false,
maximized: false,
- zIndex: maxZIndex + 1,
desktopId: currentDesktop
};
- setWindows(prev => [...prev, newWindow]);
- setMaxZIndex(prev => prev + 1);
- setActiveWindowId(appToOpen.id);
+ windowContext.openWindow(newWindow);
setShowStartMenu(false);
- }, [windows, maxZIndex, playSound, currentDesktop, isDesktopLocked, apps]);
+ }, [windowContext, playSound, currentDesktop, isDesktopLocked, apps]);
const closeWindow = useCallback((id: string) => {
playSound('close');
- setWindows(prev => prev.filter(w => w.id !== id));
- if (activeWindowId === id) setActiveWindowId(null);
- }, [activeWindowId, playSound]);
+ windowContext.closeWindow(id);
+ }, [windowContext, playSound]);
const minimizeWindow = useCallback((id: string) => {
playSound('minimize');
- setWindows(prev => prev.map(w => w.id === id ? { ...w, minimized: true } : w));
- }, [playSound]);
+ windowContext.minimizeWindow(id);
+ }, [windowContext, playSound]);
const toggleMaximize = useCallback((id: string) => {
- setWindows(prev => prev.map(w => w.id === id ? { ...w, maximized: !w.maximized } : w));
- }, []);
+ windowContext.maximizeWindow(id);
+ }, [windowContext]);
const focusWindow = useCallback((id: string) => {
- setWindows(prev => prev.map(w => w.id === id ? { ...w, zIndex: maxZIndex + 1 } : w));
- setMaxZIndex(prev => prev + 1);
- setActiveWindowId(id);
- }, [maxZIndex]);
+ windowContext.focusWindow(id);
+ }, [windowContext]);
const handleDesktopClick = (e: React.MouseEvent) => {
setShowStartMenu(false);
@@ -786,20 +803,11 @@ export default function AeThexOS() {
const screenWidth = window.innerWidth;
const screenHeight = window.innerHeight - 48;
- if (x <= 10) {
- setWindows(prev => prev.map(w => w.id === id ? { ...w, x: 0, y: 0, width: screenWidth / 2, height: screenHeight } : w));
- return true;
- }
- if (x + width >= screenWidth - 10) {
- setWindows(prev => prev.map(w => w.id === id ? { ...w, x: screenWidth / 2, y: 0, width: screenWidth / 2, height: screenHeight } : w));
- return true;
- }
- if (y <= 10) {
- setWindows(prev => prev.map(w => w.id === id ? { ...w, x: 0, y: 0, width: screenWidth, height: screenHeight, maximized: true } : w));
- return true;
+ if (x <= 10 || x + width >= screenWidth - 10 || y <= 10) {
+ return windowContext.snapWindow(id, x, y);
}
return false;
- }, []);
+ }, [windowContext]);
const handleLogout = async () => {
await logout();
@@ -873,6 +881,8 @@ export default function AeThexOS() {
case 'notifications': return ;
case 'analytics': return ;
case 'drives': return ;
+ case 'aethexstudio': return ;
+ case 'aethexappstore': return ;
case 'iframe': return null;
case 'settings': return
- {/* Scan lines overlay */}
-
-
- {/* CRT flicker effect */}
-
-
- {/* Vignette effect */}
-
-
-
- {/* Left side - Boot logs */}
-
-
-
- System Log
-
-
-
- {bootLogs.map((log, i) => (
-
- {log}
-
- ))}
-
-
-
- {/* Threat Level Indicator */}
-
-
Aegis Status
-
-
- {threatLevel === 'scanning' ? 'SCANNING...' : `THREAT: ${threatLevel.toUpperCase()}`}
-
-
-
-
- {/* Center - Main boot display */}
-
-
- {/* Logo with glow */}
-
-
- {/* Current step with typing effect */}
-
- {bootStep}
-
- _
-
-
-
- {/* Progress bar */}
-
-
- BOOT SEQUENCE
- {bootProgress}%
-
-
-
-
- {/* Detected identity badge */}
- {detectedIdentity && (
-
-
-
- {detectedIdentity.username} • ID:{detectedIdentity.passportId}
-
-
- )}
-
- AeThex OS v4.2.1 • Aegis Security Layer Active
-
-
- {showLoginPrompt && (
-
-
-
- {detectedIdentity
- ? `IDENTITY VERIFIED • THREAT LEVEL: ${threatLevel.toUpperCase()}`
- : `SYSTEM READY • THREAT LEVEL: ${threatLevel.toUpperCase()}`
- }
-
-
-
-
- {detectedIdentity ? `Enter as ${detectedIdentity.username}` : 'Login with Passport'}
-
- {!detectedIdentity && (
-
- Continue as Guest
-
- )}
-
-
- )}
-
-
-
-
- {/* Right side - System specs (hidden on mobile) */}
-
-
- System Info
-
-
-
BUILD: 2025.12.21
-
KERNEL: 4.2.1-aethex
-
ARCH: x86_64
-
-
NEXUS NETWORK
-
Peers: 42 online
-
Latency: 12ms
-
-
-
PASSPORT
-
{detectedIdentity ? 'Token: VALID' : 'Token: NONE'}
-
Mode: {detectedIdentity ? 'ARCHITECT' : 'GUEST'}
-
-
-
-
-
+