tahamajs/IE / Projects /front /src /components /desktop /WindowContainer.tsx
tahamajs's picture
download
raw
3.84 kB
import React, { createContext, useCallback, useContext, useMemo, useState, type ReactNode } from "react";
export interface DesktopWindow {
id: string;
title: string;
icon?: ReactNode;
content: ReactNode;
isOpen: boolean;
isMinimized: boolean;
isMaximized: boolean;
position: { x: number; y: number };
size: { width: number; height: number };
zIndex: number;
minWidth?: number;
minHeight?: number;
}
interface WindowContextType {
windows: DesktopWindow[];
activeWindowId: string | null;
openWindow: (title: string, content: ReactNode, options?: Partial<DesktopWindow>) => string;
closeWindow: (id: string) => void;
minimizeWindow: (id: string) => void;
maximizeWindow: (id: string) => void;
restoreWindow: (id: string) => void;
bringToFront: (id: string) => void;
updateWindow: (id: string, updates: Partial<DesktopWindow>) => void;
}
const WindowContext = createContext<WindowContextType | undefined>(undefined);
export function useWindowManager() {
const ctx = useContext(WindowContext);
if (!ctx) throw new Error("useWindowManager must be used within WindowContainer");
return ctx;
}
export function WindowContainer({ children }: { children: ReactNode }) {
const [windows, setWindows] = useState<DesktopWindow[]>([]);
const [activeWindowId, setActiveWindowId] = useState<string | null>(null);
const [nextZIndex, setNextZIndex] = useState(10);
const openWindow = useCallback((title: string, content: ReactNode, options?: Partial<DesktopWindow>) => {
const id = globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random().toString(36).slice(2)}`;
const basePosition = { x: 100 + windows.length * 30, y: 100 + windows.length * 30 };
const newWindow: DesktopWindow = {
id,
title,
content,
isOpen: true,
isMinimized: false,
isMaximized: false,
position: options?.position ?? basePosition,
size: options?.size ?? { width: 800, height: 600 },
zIndex: nextZIndex,
minWidth: options?.minWidth ?? 400,
minHeight: options?.minHeight ?? 300,
icon: options?.icon,
};
setWindows((prev) => [...prev, newWindow]);
setActiveWindowId(id);
setNextZIndex((prev) => prev + 1);
return id;
}, [nextZIndex, windows.length]);
const closeWindow = useCallback((id: string) => {
setWindows((prev) => prev.filter((w) => w.id !== id));
setActiveWindowId((prev) => (prev === id ? null : prev));
}, []);
const minimizeWindow = useCallback((id: string) => {
setWindows((prev) => prev.map((w) => (w.id === id ? { ...w, isMinimized: true } : w)));
}, []);
const maximizeWindow = useCallback((id: string) => {
setWindows((prev) => prev.map((w) => (w.id === id ? { ...w, isMaximized: true, isMinimized: false } : w)));
}, []);
const restoreWindow = useCallback((id: string) => {
setWindows((prev) => prev.map((w) => (w.id === id ? { ...w, isMaximized: false, isMinimized: false } : w)));
}, []);
const bringToFront = useCallback((id: string) => {
setWindows((prev) => prev.map((w) => (w.id === id ? { ...w, zIndex: nextZIndex } : w)));
setActiveWindowId(id);
setNextZIndex((prev) => prev + 1);
}, [nextZIndex]);
const updateWindow = useCallback((id: string, updates: Partial<DesktopWindow>) => {
setWindows((prev) => prev.map((w) => (w.id === id ? { ...w, ...updates } : w)));
}, []);
const value = useMemo(
() => ({
windows,
activeWindowId,
openWindow,
closeWindow,
minimizeWindow,
maximizeWindow,
restoreWindow,
bringToFront,
updateWindow,
}),
[windows, activeWindowId, openWindow, closeWindow, minimizeWindow, maximizeWindow, restoreWindow, bringToFront, updateWindow]
);
return <WindowContext.Provider value={value}>{children}</WindowContext.Provider>;
}

Xet Storage Details

Size:
3.84 kB
·
Xet hash:
f4479b8b4743130e4befbea5c267b33a3a2323d91218208918d52b8289a0d6ec

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.