frontend/app/app.vue

202 lines
5.9 KiB
Vue
Raw Normal View History

2025-09-10 23:43:41 +00:00
<script setup>
import Taskbar from '~/components/Taskbar.vue';
import AboutMeWindow from '~/components/AboutMeWindow.vue';
import { ref, reactive, onMounted, onUnmounted, computed } from 'vue';
// Reactive array to hold all window states
const windows = reactive([]);
// Keep track of the highest z-index to ensure new/focused windows are on top
const currentZIndex = ref(100);
// Function to generate a unique ID for each window instance
const generateUniqueId = () => {
return Date.now().toString(36) + Math.random().toString(36).substr(2);
};
// Load window states from localStorage on mount
onMounted(() => {
const savedWindows = localStorage.getItem('windows');
if (savedWindows) {
const parsedWindows = JSON.parse(savedWindows);
parsedWindows.forEach(win => {
// Ensure z-index is properly managed on load
if (win.zIndex > currentZIndex.value) {
currentZIndex.value = win.zIndex;
}
windows.push(win);
});
}
});
// Save window states to localStorage whenever windows array changes
const saveWindowsToLocalStorage = () => {
localStorage.setItem('windows', JSON.stringify(windows));
};
// Function to open a new window or bring an existing one to front
const openWindow = (type, titleKey, initialWidth = 400, initialHeight = 300) => {
const existingWindow = windows.find(w => w.type === type);
if (existingWindow) {
bringWindowToFront(existingWindow.id);
if (existingWindow.isMinimized) {
restoreWindow(existingWindow.id);
}
existingWindow.isVisible = true; // Ensure it's visible if it was closed
} else {
currentZIndex.value++;
// Calculate initial position to center the window within the desktop content area
const desktopWidth = window.innerWidth;
const desktopHeight = window.innerHeight - 40; // Minus taskbar height
const initialX = (desktopWidth - initialWidth) / 2;
const initialY = (desktopHeight - initialHeight) / 2 + 40; // Add taskbar height
const newWindow = {
id: generateUniqueId(),
type,
title: titleKey, // Store the translation key here
isVisible: true,
isMinimized: false,
x: initialX,
y: initialY,
width: initialWidth,
height: initialHeight,
zIndex: currentZIndex.value,
};
windows.push(newWindow);
saveWindowsToLocalStorage();
}
};
// Function to close a window
const closeWindow = (id) => {
const index = windows.findIndex(w => w.id === id);
if (index !== -1) {
windows.splice(index, 1);
saveWindowsToLocalStorage();
}
};
// Function to close all windows
const closeAllWindows = () => {
windows.splice(0, windows.length); // Clear the array
saveWindowsToLocalStorage();
};
// Function to minimize a window
const minimizeWindow = (id) => {
const windowToMinimize = windows.find(w => w.id === id);
if (windowToMinimize) {
windowToMinimize.isMinimized = true;
saveWindowsToLocalStorage();
}
};
// Function to restore a minimized window
const restoreWindow = (id) => {
const windowToRestore = windows.find(w => w.id === id);
if (windowToRestore) {
windowToRestore.isMinimized = false;
bringWindowToFront(id);
saveWindowsToLocalStorage();
}
};
// Function to bring a window to the front (update z-index)
const bringWindowToFront = (id) => {
const windowToFront = windows.find(w => w.id === id);
if (windowToFront) {
currentZIndex.value++;
windowToFront.zIndex = currentZIndex.value;
saveWindowsToLocalStorage();
}
};
// Function to update window position (for dragging)
const updateWindowPosition = (id, newX, newY) => {
const windowToUpdate = windows.find(w => w.id === id);
if (windowToUpdate) {
windowToUpdate.x = newX;
windowToUpdate.y = newY;
saveWindowsToLocalStorage();
}
};
// Handle opening About Me window from Taskbar
const openAboutMeWindow = () => {
openWindow('about-me', 'about_me'); // Pass the translation key
};
// Computed property for minimized windows
const minimizedWindows = computed(() => {
return windows.filter(win => win.isMinimized);
});
// Clean up localStorage on component unmount (optional, for development)
onUnmounted(() => {
// localStorage.removeItem('windows');
});
</script>
<template>
<div>
<Taskbar
@open-about-me="openAboutMeWindow"
@close-all-windows="closeAllWindows"
:minimized-windows="minimizedWindows"
@restore-window="restoreWindow"
/>
<div class="desktop-content">
<NuxtPage />
</div>
<!-- Dynamically render windows -->
<template v-for="window in windows" :key="window.id">
<AboutMeWindow
v-if="window.type === 'about-me' && window.isVisible && !window.isMinimized"
:window-data="window"
@close="closeWindow(window.id)"
@minimize="minimizeWindow(window.id)"
@restore="restoreWindow(window.id)"
@bring-to-front="bringWindowToFront(window.id)"
@update-position="updateWindowPosition(window.id, $event.x, $event.y)"
/>
</template>
</div>
</template>
<style>
body {
background-color: #008080; /* Windows 95 teal */
background-image: url('https://picsum.photos/1920/1080'); /* Placeholder wallpaper */
background-size: cover;
background-position: center;
background-repeat: no-repeat;
font-family: 'Courier New', Courier, monospace;
margin: 0;
overflow: hidden; /* Hide scrollbars from the body */
}
/* Adjust Taskbar position */
.taskbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 40px;
z-index: 1000; /* Ensure it's on top of other content */
}
.desktop-content {
/* Push content down by the height of the taskbar */
margin-top: 40px;
height: calc(100vh - 40px); /* Fill remaining height */
width: 100%;
box-sizing: border-box;
overflow-y: auto; /* Allow scrolling for desktop content if needed */
background-color: transparent; /* Changed to transparent */
border: none; /* Removed border */
box-shadow: none; /* Removed shadow */
}
</style>