| 19 | providedIn: 'root' |
| 20 | }) |
| 21 | export class WindowManagerService { |
| 22 | private windows = signal<Map<string, WindowState>>(new Map()); |
| 23 | private nextZIndex = signal(1000); |
| 24 | private backgroundImage = signal('wall-1'); |
| 25 | |
| 26 | getWindows() { |
| 27 | return this.windows(); |
| 28 | } |
| 29 | |
| 30 | getBackgroundImage() { |
| 31 | return this.backgroundImage(); |
| 32 | } |
| 33 | |
| 34 | setBackgroundImage(image: string) { |
| 35 | this.backgroundImage.set(image); |
| 36 | localStorage.setItem('bg-image', image); |
| 37 | } |
| 38 | |
| 39 | openWindow(app: App) { |
| 40 | const windows = new Map(this.windows()); |
| 41 | const existingWindow = windows.get(app.id); |
| 42 | |
| 43 | if (existingWindow && existingWindow.isMinimized) { |
| 44 | // Restore minimized window |
| 45 | existingWindow.isMinimized = false; |
| 46 | existingWindow.isFocused = true; |
| 47 | existingWindow.zIndex = this.nextZIndex(); |
| 48 | this.nextZIndex.update(v => v + 1); |
| 49 | windows.set(app.id, existingWindow); |
| 50 | this.windows.set(windows); |
| 51 | this.trackFrequentApp(app.id); |
| 52 | return; |
| 53 | } |
| 54 | |
| 55 | if (existingWindow && existingWindow.isOpen) { |
| 56 | // Focus existing window |
| 57 | this.focusWindow(app.id); |
| 58 | return; |
| 59 | } |
| 60 | |
| 61 | // Track frequent apps for new windows |
| 62 | this.trackFrequentApp(app.id); |
| 63 | |
| 64 | // Create new window - center it on screen with slight offset for multiple windows |
| 65 | const openWindows = Array.from(windows.values()).filter(w => w.isOpen && !w.isMinimized); |
| 66 | const windowCount = openWindows.length; |
| 67 | |
| 68 | // Window dimensions (percentage) - responsive based on screen size |
| 69 | const isMobile = window.innerWidth < 640; // Tailwind's sm breakpoint |
| 70 | const windowWidthPercent = isMobile ? 85 : 60; |
| 71 | const windowHeightPercent = isMobile ? 60 : 70; |
| 72 | |
| 73 | // Calculate centered position |
| 74 | const centerX = (100 - windowWidthPercent) / 2; |
| 75 | const centerY = (100 - windowHeightPercent) / 2; |
| 76 | |
| 77 | // Add offset for multiple windows (cascade effect) |
| 78 | const offsetPercent = 3; // 3% offset per window |
nothing calls this directly
no outgoing calls
no test coverage detected