import { ref, computed } from 'vue'; import { defineStore } from 'pinia'; export interface AppInfo { id: string; name: string; icon: string; component: string; description: string; category: string; } export interface AppInstance { id: string; appId: string; title: string; x: number; y: number; width: number; height: number; zIndex: number; isMinimized: boolean; isMaximized: boolean; isFocused: boolean; maxWidth?: number; maxHeight?: number; minWidth?: number; minHeight?: number; } let appInstanceIdCounter = 0; export const useAppsStore = defineStore('apps', () => { // Available apps registry const availableApps = ref([ { id: 'livestream-hub', name: 'livestream-hub', // Use translation key instead of hardcoded name icon: '📰', component: 'NewsHub', description: 'Discover and watch live streams from popular streamers', category: 'Entertainment' }, // More apps can be added here in the future ]); // Running app instances const appInstances = ref([]); const nextZIndex = ref(100); // Getters const getAppById = computed(() => { return (id: string) => availableApps.value.find(app => app.id === id); }); const getAppInstanceById = computed(() => { return (id: string) => appInstances.value.find(instance => instance.id === id); }); const orderedAppInstances = computed(() => { return [...appInstances.value].sort((a, b) => a.zIndex - b.zIndex); }); const focusedAppInstance = computed(() => { return appInstances.value.find(instance => instance.isFocused); }); // Get default size and constraints for specific app function getAppSizeConstraints(appId: string) { const appConstraints: Record = { 'livestream-hub': { width: 800, height: 600, maxWidth: 1200, // Allow wider view for better content display maxHeight: 800, // Allow taller view for more streamers minWidth: 600, // Minimum usable width minHeight: 500 // Minimum usable height }, 'text-editor': { width: 600, height: 400, maxWidth: 1200, maxHeight: 800, minWidth: 400, minHeight: 300 }, 'file-manager': { width: 800, height: 500, maxWidth: 1400, maxHeight: 900, minWidth: 600, minHeight: 400 }, 'web-browser': { width: 1000, height: 600, maxWidth: 1600, maxHeight: 1000, minWidth: 800, minHeight: 500 }, }; return appConstraints[appId] || { width: 400, height: 300, maxWidth: 800, maxHeight: 600, minWidth: 300, minHeight: 200 }; } // Actions function launchApp(appId: string) { const app = getAppById.value(appId); if (!app) { console.error(`App with id "${appId}" not found`); return null; } const constraints = getAppSizeConstraints(appId); const newInstanceId = appInstanceIdCounter++; const newInstance: AppInstance = { id: `app-${appId}-${newInstanceId}`, appId: appId, title: `${app.name} #${newInstanceId + 1}`, x: Math.random() * 200 + 50, y: Math.random() * 100 + 50 + 48, // Below taskbar width: constraints.width, height: constraints.height, zIndex: nextZIndex.value++, isMinimized: false, isMaximized: false, isFocused: true, maxWidth: constraints.maxWidth, maxHeight: constraints.maxHeight, minWidth: constraints.minWidth, minHeight: constraints.minHeight, }; // Unfocus all other instances appInstances.value.forEach(instance => instance.isFocused = false); appInstances.value.push(newInstance); return newInstance; } function focusAppInstance(instanceId: string) { const instance = appInstances.value.find(i => i.id === instanceId); if (!instance || instance.isFocused) return; // Unfocus all other instances appInstances.value.forEach(i => i.isFocused = false); instance.zIndex = nextZIndex.value++; instance.isFocused = true; if (instance.isMinimized) { instance.isMinimized = false; } } function closeAppInstance(instanceId: string) { appInstances.value = appInstances.value.filter(i => i.id !== instanceId); } function minimizeAppInstance(instanceId: string) { const instance = appInstances.value.find(i => i.id === instanceId); if (instance) { instance.isMinimized = true; instance.isFocused = false; } } function toggleMaximizeAppInstance(instanceId: string) { const instance = appInstances.value.find(i => i.id === instanceId); if (instance) { instance.isMaximized = !instance.isMaximized; focusAppInstance(instanceId); } } function updateAppInstancePosition({ id, x, y }: { id: string; x: number; y: number }) { const instance = appInstances.value.find(i => i.id === id); if (instance && !instance.isMaximized) { instance.x = x; instance.y = y; } } function updateAppInstanceSize({ id, width, height }: { id: string; width: number; height: number }) { const instance = appInstances.value.find(i => i.id === id); if (instance && !instance.isMaximized) { instance.width = width; instance.height = height; } } function closeAllAppInstances() { appInstances.value = []; } return { availableApps, appInstances, nextZIndex, getAppById, getAppInstanceById, orderedAppInstances, focusedAppInstance, launchApp, focusAppInstance, closeAppInstance, minimizeAppInstance, toggleMaximizeAppInstance, updateAppInstancePosition, updateAppInstanceSize, closeAllAppInstances, }; });