hfos / index.html
TechITProfessional's picture
The app doesn't function now - Initial Deployment
7c3dc3f verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BrowserOS</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
'os-primary': '#4f46e5',
'os-secondary': '#6366f1',
'os-dark': '#1e293b',
'os-darker': '#0f172a',
'os-light': '#f1f5f9',
'os-accent': '#8b5cf6'
}
}
}
}
</script>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Inter', sans-serif;
user-select: none;
}
body {
overflow: hidden;
background-color: #0f172a;
height: 100vh;
width: 100vw;
}
#desktop {
background-image: url('https://images.unsplash.com/photo-1505506874110-0a3a6a03b9c3?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1887&q=80');
background-size: cover;
background-position: center;
height: calc(100vh - 50px);
position: relative;
overflow: hidden;
}
.desktop-icon {
position: absolute;
width: 80px;
height: 80px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s ease;
text-align: center;
color: white;
text-shadow: 0 1px 3px rgba(0,0,0,0.5);
}
.desktop-icon:hover {
background: rgba(255,255,255,0.1);
border-radius: 5px;
}
.desktop-icon i {
font-size: 32px;
margin-bottom: 5px;
}
.desktop-icon span {
font-size: 12px;
font-weight: 500;
}
.window {
position: absolute;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
display: flex;
flex-direction: column;
min-width: 400px;
min-height: 300px;
background: #f8fafc;
resize: both;
overflow: auto;
}
.window-header {
background: linear-gradient(to right, #4f46e5, #6366f1);
color: white;
padding: 8px 12px;
display: flex;
justify-content: space-between;
align-items: center;
cursor: move;
}
.window-title {
font-weight: 600;
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.window-controls {
display: flex;
gap: 8px;
}
.window-control {
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.2s ease;
}
.window-control:hover {
background: rgba(255,255,255,0.2);
}
.window-content {
flex: 1;
padding: 15px;
overflow: auto;
}
#taskbar {
height: 50px;
background: rgba(30, 41, 59, 0.9);
backdrop-filter: blur(10px);
display: flex;
align-items: center;
padding: 0 10px;
position: relative;
z-index: 1000;
}
#start-menu-btn {
background: linear-gradient(to right, #4f46e5, #6366f1);
color: white;
border: none;
border-radius: 5px;
padding: 5px 15px;
display: flex;
align-items: center;
gap: 8px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
#start-menu-btn:hover {
transform: scale(1.05);
}
#app-tray {
display: flex;
gap: 5px;
margin-left: 15px;
}
.tray-app {
width: 40px;
height: 40px;
border-radius: 5px;
display: flex;
align-items: center;
justify-content: center;
color: white;
background: rgba(255,255,255,0.1);
cursor: pointer;
transition: all 0.2s ease;
}
.tray-app:hover {
background: rgba(255,255,255,0.2);
}
.tray-app.active {
background: rgba(79, 70, 229, 0.5);
}
#system-tray {
margin-left: auto;
display: flex;
align-items: center;
gap: 10px;
color: white;
padding: 0 10px;
}
.tray-icon {
padding: 5px;
cursor: pointer;
border-radius: 3px;
transition: all 0.2s ease;
}
.tray-icon:hover {
background: rgba(255,255,255,0.1);
}
#clock {
font-size: 14px;
font-weight: 500;
}
#start-menu {
position: absolute;
bottom: 50px;
left: 10px;
width: 350px;
height: 450px;
background: rgba(30, 41, 59, 0.95);
backdrop-filter: blur(10px);
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0,0,0,0.3);
display: none;
flex-direction: column;
overflow: hidden;
z-index: 999;
}
.app-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 15px;
padding: 20px;
flex: 1;
}
.app-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
color: white;
padding: 15px 5px;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s ease;
}
.app-item:hover {
background: rgba(255,255,255,0.1);
}
.app-item i {
font-size: 28px;
}
.app-item span {
font-size: 12px;
font-weight: 500;
}
.file-item {
display: flex;
align-items: center;
padding: 8px 12px;
border-radius: 5px;
cursor: pointer;
transition: all 0.2s ease;
}
.file-item:hover {
background: #e2e8f0;
}
.context-menu {
position: absolute;
background: white;
border-radius: 5px;
box-shadow: 0 5px 15px rgba(0,0,0,0.2);
min-width: 200px;
z-index: 1001;
display: none;
}
.context-menu-item {
padding: 8px 15px;
cursor: pointer;
transition: all 0.2s ease;
display: flex;
align-items: center;
gap: 8px;
}
.context-menu-item:hover {
background: #f1f5f9;
}
.tab-container {
display: flex;
border-bottom: 1px solid #cbd5e1;
padding: 0 15px;
}
.tab {
padding: 10px 20px;
cursor: pointer;
border-bottom: 2px solid transparent;
transition: all 0.2s ease;
}
.tab.active {
border-bottom: 2px solid #4f46e5;
color: #4f46e5;
font-weight: 500;
}
.tab-content {
display: none;
}
.tab-content.active {
display: block;
}
.file-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
gap: 15px;
padding: 15px;
}
.file-grid-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
padding: 10px;
border-radius: 5px;
cursor: pointer;
transition: all 0.2s ease;
}
.file-grid-item:hover {
background: #e2e8f0;
}
.file-grid-item i {
font-size: 32px;
}
.file-grid-item span {
font-size: 12px;
text-align: center;
word-break: break-word;
}
.settings-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 15px;
padding: 15px;
}
.wallpaper-preview {
width: 100%;
aspect-ratio: 16/9;
border-radius: 5px;
overflow: hidden;
cursor: pointer;
border: 2px solid transparent;
transition: all 0.2s ease;
}
.wallpaper-preview:hover {
transform: scale(1.03);
}
.wallpaper-preview.selected {
border-color: #4f46e5;
}
.wallpaper-preview img {
width: 100%;
height: 100%;
object-fit: cover;
}
.editor-toolbar {
display: flex;
gap: 5px;
padding: 8px;
background: #e2e8f0;
border-bottom: 1px solid #cbd5e1;
}
.editor-btn {
padding: 5px 10px;
border-radius: 3px;
background: white;
border: 1px solid #cbd5e1;
cursor: pointer;
transition: all 0.2s ease;
}
.editor-btn:hover {
background: #f1f5f9;
}
#editor-content {
width: 100%;
height: 100%;
padding: 15px;
border: none;
resize: none;
font-family: 'Inter', sans-serif;
font-size: 14px;
}
#editor-content:focus {
outline: none;
}
.browser-nav {
display: flex;
gap: 10px;
padding: 10px;
background: #e2e8f0;
border-bottom: 1px solid #cbd5e1;
}
.browser-input {
flex: 1;
padding: 8px 15px;
border-radius: 20px;
border: 1px solid #cbd5e1;
}
.browser-btn {
padding: 8px 15px;
border-radius: 5px;
background: #4f46e5;
color: white;
border: none;
cursor: pointer;
}
#browser-frame {
flex: 1;
border: none;
}
.minimized-window {
opacity: 0.7;
}
.window.snapped-left {
width: 50% !important;
height: calc(100vh - 50px) !important;
top: 0 !important;
left: 0 !important;
resize: none;
}
.window.snapped-right {
width: 50% !important;
height: calc(100vh - 50px) !important;
top: 0 !important;
left: 50% !important;
resize: none;
}
.window.maximized {
width: 100% !important;
height: calc(100vh - 50px) !important;
top: 0 !important;
left: 0 !important;
resize: none;
}
.window.maximized .window-control.maximize i:before {
content: "\f2d0";
}
@media (max-width: 768px) {
.window {
min-width: 300px;
min-height: 250px;
}
#start-menu {
width: 300px;
height: 400px;
}
.app-grid {
grid-template-columns: repeat(2, 1fr);
}
}
</style>
</head>
<body>
<!-- Desktop with icons -->
<div id="desktop">
<div class="desktop-icon" style="top: 20px; left: 20px;" data-app="file-manager">
<i class="fas fa-folder"></i>
<span>Files</span>
</div>
<div class="desktop-icon" style="top: 20px; left: 120px;" data-app="text-editor">
<i class="fas fa-file-alt"></i>
<span>Notes</span>
</div>
<div class="desktop-icon" style="top: 120px; left: 20px;" data-app="browser">
<i class="fas fa-globe"></i>
<span>Browser</span>
</div>
<div class="desktop-icon" style="top: 120px; left: 120px;" data-app="settings">
<i class="fas fa-cog"></i>
<span>Settings</span>
</div>
<!-- Windows will be appended here dynamically -->
</div>
<!-- Taskbar -->
<div id="taskbar">
<button id="start-menu-btn">
<i class="fas fa-logo"></i>
<span>Start</span>
</button>
<div id="app-tray">
<!-- App icons will be added here when apps are opened -->
</div>
<div id="system-tray">
<div class="tray-icon" id="wifi-icon" title="WiFi: Connected">
<i class="fas fa-wifi"></i>
</div>
<div class="tray-icon" id="volume-icon" title="Volume: 75%">
<i class="fas fa-volume-up"></i>
<div class="volume-control hidden absolute bottom-10 right-0 bg-white p-3 rounded shadow-lg w-40">
<input type="range" min="0" max="100" value="75" class="w-full">
</div>
</div>
<div class="tray-icon" id="battery-icon" title="Battery: 85%">
<i class="fas fa-battery-three-quarters"></i>
</div>
<div id="clock">10:30 AM</div>
</div>
</div>
<!-- Start Menu -->
<div id="start-menu">
<div class="bg-gradient-to-r from-os-primary to-os-secondary p-4 text-white">
<div class="text-xl font-bold">BrowserOS</div>
<div class="text-sm opacity-80">v1.0.0</div>
</div>
<div class="app-grid">
<div class="app-item" data-app="file-manager">
<i class="fas fa-folder"></i>
<span>File Manager</span>
</div>
<div class="app-item" data-app="text-editor">
<i class="fas fa-file-alt"></i>
<span>Text Editor</span>
</div>
<div class="app-item" data-app="browser">
<i class="fas fa-globe"></i>
<span>Web Browser</span>
</div>
<div class="app-item" data-app="settings">
<i class="fas fa-cog"></i>
<span>Settings</span>
</div>
<div class="app-item" data-app="terminal">
<i class="fas fa-terminal"></i>
<span>Terminal</span>
</div>
<div class="app-item" data-app="calculator">
<i class="fas fa-calculator"></i>
<span>Calculator</span>
</div>
</div>
<div class="mt-auto bg-os-dark p-3 text-white flex justify-between">
<div class="flex items-center gap-2">
<i class="fas fa-user"></i>
<span>User</span>
</div>
<div class="flex items-center gap-2">
<i class="fas fa-power-off"></i>
<span>Power</span>
</div>
</div>
</div>
<!-- Notifications -->
<div id="notifications" class="fixed bottom-16 right-4 w-80 z-1002"></div>
<!-- Power Menu -->
<div id="power-menu" class="fixed bottom-16 left-4 bg-white rounded-lg shadow-lg p-2 hidden z-1001">
<div class="power-option p-2 hover:bg-gray-100 rounded cursor-pointer">
<i class="fas fa-moon mr-2"></i> Sleep
</div>
<div class="power-option p-2 hover:bg-gray-100 rounded cursor-pointer">
<i class="fas fa-redo mr-2"></i> Restart
</div>
<div class="power-option p-2 hover:bg-gray-100 rounded cursor-pointer text-red-500">
<i class="fas fa-power-off mr-2"></i> Shut Down
</div>
</div>
<!-- Context Menu -->
<div class="context-menu">
<div class="context-menu-item" id="context-new-folder">
<i class="fas fa-folder-plus"></i>
<span>New Folder</span>
</div>
<div class="context-menu-item" id="context-new-file">
<i class="fas fa-file"></i>
<span>New File</span>
</div>
<div class="context-menu-divider border-t border-gray-200 my-1"></div>
<div class="context-menu-item" id="context-cut">
<i class="fas fa-cut"></i>
<span>Cut</span>
</div>
<div class="context-menu-item" id="context-copy">
<i class="fas fa-copy"></i>
<span>Copy</span>
</div>
<div class="context-menu-item" id="context-paste">
<i class="fas fa-paste"></i>
<span>Paste</span>
</div>
<div class="context-menu-divider border-t border-gray-200 my-1"></div>
<div class="context-menu-item" id="context-refresh">
<i class="fas fa-sync"></i>
<span>Refresh</span>
</div>
<div class="context-menu-item" id="context-properties">
<i class="fas fa-info-circle"></i>
<span>Properties</span>
</div>
</div>
<!-- File Manager Template -->
<template id="file-manager-template">
<div class="window">
<div class="window-header">
<div class="window-title">
<i class="fas fa-folder"></i>
<span>File Manager</span>
</div>
<div class="window-controls">
<div class="window-control minimize">
<i class="fas fa-minus"></i>
</div>
<div class="window-control maximize">
<i class="fas fa-square"></i>
</div>
<div class="window-control close">
<i class="fas fa-times"></i>
</div>
</div>
</div>
<div class="window-content">
<div class="tab-container">
<div class="tab active" data-tab="home">Home</div>
<div class="tab" data-tab="documents">Documents</div>
<div class="tab" data-tab="pictures">Pictures</div>
<div class="tab" data-tab="downloads">Downloads</div>
</div>
<div class="tab-content active" id="home-tab">
<div class="file-grid">
<div class="file-grid-item">
<i class="fas fa-folder text-yellow-500"></i>
<span>Documents</span>
</div>
<div class="file-grid-item">
<i class="fas fa-folder text-blue-500"></i>
<span>Downloads</span>
</div>
<div class="file-grid-item">
<i class="fas fa-folder text-green-500"></i>
<span>Pictures</span>
</div>
<div class="file-grid-item">
<i class="fas fa-folder text-purple-500"></i>
<span>Music</span>
</div>
<div class="file-grid-item">
<i class="fas fa-file-pdf text-red-500"></i>
<span>Report.pdf</span>
</div>
<div class="file-grid-item">
<i class="fas fa-file-word text-blue-600"></i>
<span>Document.docx</span>
</div>
</div>
</div>
<div class="tab-content" id="documents-tab">
<div class="p-4">Documents folder content</div>
</div>
</div>
</div>
</template>
<!-- Text Editor Template -->
<template id="text-editor-template">
<div class="window">
<div class="window-header">
<div class="window-title">
<i class="fas fa-file-alt"></i>
<span>Text Editor - Untitled</span>
</div>
<div class="window-controls">
<div class="window-control minimize">
<i class="fas fa-minus"></i>
</div>
<div class="window-control maximize">
<i class="fas fa-square"></i>
</div>
<div class="window-control close">
<i class="fas fa-times"></i>
</div>
</div>
</div>
<div class="editor-toolbar">
<button class="editor-btn"><i class="fas fa-bold"></i></button>
<button class="editor-btn"><i class="fas fa-italic"></i></button>
<button class="editor-btn"><i class="fas fa-underline"></i></button>
<button class="editor-btn"><i class="fas fa-list-ul"></i></button>
<button class="editor-btn"><i class="fas fa-list-ol"></i></button>
</div>
<textarea id="editor-content">Welcome to BrowserOS Text Editor!
Start typing your notes here...</textarea>
</div>
</template>
<!-- Browser Template -->
<template id="browser-template">
<div class="window">
<div class="window-header">
<div class="window-title">
<i class="fas fa-globe"></i>
<span>Web Browser</span>
</div>
<div class="window-controls">
<div class="window-control minimize">
<i class="fas fa-minus"></i>
</div>
<div class="window-control maximize">
<i class="fas fa-square"></i>
</div>
<div class="window-control close">
<i class="fas fa-times"></i>
</div>
</div>
</div>
<div class="browser-nav">
<button class="browser-btn"><i class="fas fa-arrow-left"></i></button>
<button class="browser-btn"><i class="fas fa-arrow-right"></i></button>
<button class="browser-btn"><i class="fas fa-sync"></i></button>
<input type="text" class="browser-input" value="https://browseros.com" placeholder="Search or enter address">
<button class="browser-btn"><i class="fas fa-search"></i></button>
</div>
<iframe id="browser-frame" src="about:blank"></iframe>
</div>
</template>
<!-- Terminal Template -->
<template id="terminal-template">
<div class="window">
<div class="window-header">
<div class="window-title">
<i class="fas fa-terminal"></i>
<span>Terminal</span>
</div>
<div class="window-controls">
<div class="window-control minimize">
<i class="fas fa-minus"></i>
</div>
<div class="window-control maximize">
<i class="fas fa-square"></i>
</div>
<div class="window-control close">
<i class="fas fa-times"></i>
</div>
</div>
</div>
<div class="window-content bg-os-darker text-white p-4 font-mono">
<div id="terminal-output"></div>
<div class="flex items-center">
<span class="text-green-400 mr-2">user@browseros:~$</span>
<input type="text" id="terminal-input" class="bg-transparent border-none text-white outline-none flex-1" autofocus>
</div>
</div>
</div>
</template>
<!-- Calculator Template -->
<template id="calculator-template">
<div class="window">
<div class="window-header">
<div class="window-title">
<i class="fas fa-calculator"></i>
<span>Calculator</span>
</div>
<div class="window-controls">
<div class="window-control minimize">
<i class="fas fa-minus"></i>
</div>
<div class="window-control maximize">
<i class="fas fa-square"></i>
</div>
<div class="window-control close">
<i class="fas fa-times"></i>
</div>
</div>
</div>
<div class="window-content p-4">
<div class="bg-gray-100 rounded p-3 mb-3 text-right text-2xl font-semibold" id="calc-display">0</div>
<div class="grid grid-cols-4 gap-2">
<button class="calc-btn bg-gray-200">C</button>
<button class="calc-btn bg-gray-200">±</button>
<button class="calc-btn bg-gray-200">%</button>
<button class="calc-btn bg-os-primary text-white">÷</button>
<button class="calc-btn">7</button>
<button class="calc-btn">8</button>
<button class="calc-btn">9</button>
<button class="calc-btn bg-os-primary text-white">×</button>
<button class="calc-btn">4</button>
<button class="calc-btn">5</button>
<button class="calc-btn">6</button>
<button class="calc-btn bg-os-primary text-white">-</button>
<button class="calc-btn">1</button>
<button class="calc-btn">2</button>
<button class="calc-btn">3</button>
<button class="calc-btn bg-os-primary text-white">+</button>
<button class="calc-btn col-span-2">0</button>
<button class="calc-btn">.</button>
<button class="calc-btn bg-green-500 text-white">=</button>
</div>
</div>
</div>
</template>
<!-- Settings Template -->
<template id="settings-template">
<div class="window">
<div class="window-header">
<div class="window-title">
<i class="fas fa-cog"></i>
<span>System Settings</span>
</div>
<div class="window-controls">
<div class="window-control minimize">
<i class="fas fa-minus"></i>
</div>
<div class="window-control maximize">
<i class="fas fa-square"></i>
</div>
<div class="window-control close">
<i class="fas fa-times"></i>
</div>
</div>
</div>
<div class="window-content">
<h2 class="text-xl font-bold mb-4">Personalization</h2>
<div class="mb-6">
<h3 class="font-semibold mb-2">Wallpaper</h3>
<div class="settings-grid">
<div class="wallpaper-preview selected" data-wallpaper="1">
<img src="https://images.unsplash.com/photo-1505506874110-0a3a6a03b9c3?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1887&q=80" alt="Mountain Landscape">
</div>
<div class="wallpaper-preview" data-wallpaper="2">
<img src="https://images.unsplash.com/photo-1501854140801-50d01698950b?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2048&q=80" alt="Forest">
</div>
<div class="wallpaper-preview" data-wallpaper="3">
<img src="https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2048&q=80" alt="Nature">
</div>
<div class="wallpaper-preview" data-wallpaper="4">
<img src="https://images.unsplash.com/photo-1469474968028-56623f02e42e?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2048&q=80" alt="Landscape">
</div>
</div>
</div>
<div class="mb-6">
<h3 class="font-semibold mb-2">Theme</h3>
<div class="flex gap-4">
<div class="cursor-pointer p-3 rounded border-2 border-transparent bg-gradient-to-r from-blue-500 to-purple-500 w-16 h-16" data-theme="default"></div>
<div class="cursor-pointer p-3 rounded border-2 border-transparent bg-gradient-to-r from-green-500 to-teal-500 w-16 h-16" data-theme="green"></div>
<div class="cursor-pointer p-3 rounded border-2 border-transparent bg-gradient-to-r from-red-500 to-orange-500 w-16 h-16" data-theme="red"></div>
<div class="cursor-pointer p-3 rounded border-2 border-transparent bg-gradient-to-r from-gray-700 to-gray-900 w-16 h-16" data-theme="dark"></div>
</div>
</div>
</div>
</div>
</template>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Add to getAppIcon function
function getAppIcon(appName) {
const icons = {
'file-manager': 'fa-folder',
'text-editor': 'fa-file-alt',
'browser': 'fa-globe',
'settings': 'fa-cog',
'terminal': 'fa-terminal',
'calculator': 'fa-calculator'
};
return icons[appName] || 'fa-question';
}
// Add power menu functionality
document.querySelector('.fa-power-off').addEventListener('click', function() {
document.getElementById('power-menu').classList.toggle('hidden');
});
// Add window snapping
document.addEventListener('keydown', function(e) {
if (e.key === 'ArrowLeft' && e.altKey && activeWindow) {
activeWindow.classList.remove('snapped-right', 'maximized');
activeWindow.classList.add('snapped-left');
} else if (e.key === 'ArrowRight' && e.altKey && activeWindow) {
activeWindow.classList.remove('snapped-left', 'maximized');
activeWindow.classList.add('snapped-right');
} else if (e.key === 'ArrowUp' && e.altKey && activeWindow) {
activeWindow.classList.remove('snapped-left', 'snapped-right');
activeWindow.classList.add('maximized');
}
});
// Add terminal functionality
function setupTerminal(terminalWindow) {
const terminalInput = terminalWindow.querySelector('#terminal-input');
const terminalOutput = terminalWindow.querySelector('#terminal-output');
terminalInput.addEventListener('keydown', function(e) {
if (e.key === 'Enter') {
const command = terminalInput.value.trim();
terminalInput.value = '';
// Add command to output
terminalOutput.innerHTML += `
<div class="mb-1">
<span class="text-green-400">user@browseros:~$</span> ${command}
</div>
`;
// Process command
let output = '';
if (command === 'help') {
output = `Available commands: help, clear, about, echo`;
} else if (command === 'clear') {
terminalOutput.innerHTML = '';
return;
} else if (command.startsWith('echo ')) {
output = command.substring(5);
} else if (command === 'about') {
output = 'BrowserOS Terminal v1.0';
} else if (command) {
output = `Command not found: ${command}`;
}
if (output) {
terminalOutput.innerHTML += `<div class="mb-2">${output}</div>`;
}
// Scroll to bottom
terminalOutput.scrollTop = terminalOutput.scrollHeight;
}
});
}
// Add calculator functionality
function setupCalculator(calcWindow) {
const display = calcWindow.querySelector('#calc-display');
const buttons = calcWindow.querySelectorAll('.calc-btn');
let currentInput = '0';
let previousInput = '';
let operation = null;
let resetInput = false;
function updateDisplay() {
display.textContent = currentInput;
}
buttons.forEach(button => {
button.addEventListener('click', function() {
const value = this.textContent;
if (value >= '0' && value <= '9') {
if (currentInput === '0' || resetInput) {
currentInput = value;
resetInput = false;
} else {
currentInput += value;
}
} else if (value === '.') {
if (!currentInput.includes('.')) {
currentInput += '.';
}
} else if (value === 'C') {
currentInput = '0';
previousInput = '';
operation = null;
} else if (value === '±') {
currentInput = (parseFloat(currentInput) * -1).toString();
} else if (value === '%') {
currentInput = (parseFloat(currentInput) / 100).toString();
} else if (['+', '-', '×', '÷'].includes(value)) {
if (operation !== null) calculate();
previousInput = currentInput;
operation = value;
resetInput = true;
} else if (value === '=') {
calculate();
}
updateDisplay();
});
});
function calculate() {
let result;
const prev = parseFloat(previousInput);
const current = parseFloat(currentInput);
if (isNaN(prev) || isNaN(current)) return;
switch (operation) {
case '+': result = prev + current; break;
case '-': result = prev - current; break;
case '×': result = prev * current; break;
case '÷': result = prev / current; break;
default: return;
}
currentInput = result.toString();
operation = null;
resetInput = true;
}
}
// DOM Elements
const desktop = document.getElementById('desktop');
const taskbar = document.getElementById('taskbar');
const startMenuBtn = document.getElementById('start-menu-btn');
const startMenu = document.getElementById('start-menu');
const appTray = document.getElementById('app-tray');
const clock = document.getElementById('clock');
const contextMenu = document.querySelector('.context-menu');
// State management
let openWindows = [];
let activeWindow = null;
let dragOffset = {x: 0, y: 0};
let isDragging = false;
let currentDraggedElement = null;
// Initialize clock
function updateClock() {
const now = new Date();
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
clock.textContent = `${hours}:${minutes}`;
}
updateClock();
setInterval(updateClock, 60000);
// Start menu toggle
startMenuBtn.addEventListener('click', function(e) {
e.stopPropagation();
startMenu.style.display = startMenu.style.display === 'flex' ? 'none' : 'flex';
});
// Close start menu when clicking elsewhere
document.addEventListener('click', function(e) {
if (!startMenu.contains(e.target) && e.target !== startMenuBtn) {
startMenu.style.display = 'none';
}
});
// Desktop icon click handler
document.querySelectorAll('.desktop-icon, .app-item').forEach(icon => {
icon.addEventListener('click', function(e) {
e.stopPropagation();
const appName = this.getAttribute('data-app');
openApp(appName);
});
});
// Context menu handling
desktop.addEventListener('contextmenu', function(e) {
e.preventDefault();
contextMenu.style.display = 'block';
contextMenu.style.left = `${e.pageX}px`;
contextMenu.style.top = `${e.pageY}px`;
});
document.addEventListener('click', function() {
contextMenu.style.display = 'none';
});
// Open application function
function openApp(appName) {
// Setup app-specific functionality
if (appName === 'terminal') {
setupTerminal(windowElement);
} else if (appName === 'calculator') {
setupCalculator(windowElement);
}
// Close start menu
startMenu.style.display = 'none';
// Check if app is already open
const existingWindow = openWindows.find(win => win.appName === appName);
if (existingWindow) {
// Bring to front
bringToFront(existingWindow.element);
return;
}
// Create new window
const template = document.getElementById(`${appName}-template`);
if (!template) return;
const clone = template.content.cloneNode(true);
const windowElement = clone.querySelector('.window');
// Position window randomly but within view
const maxX = window.innerWidth - 400;
const maxY = window.innerHeight - 300 - 50; // Account for taskbar
const x = Math.max(50, Math.min(maxX, Math.floor(Math.random() * maxX)));
const y = Math.max(50, Math.min(maxY, Math.floor(Math.random() * maxY)));
windowElement.style.left = `${x}px`;
windowElement.style.top = `${y}px`;
// Add to desktop
desktop.appendChild(windowElement);
// Add to app tray
const trayApp = document.createElement('div');
trayApp.className = 'tray-app';
trayApp.innerHTML = `<i class="fas ${getAppIcon(appName)}"></i>`;
trayApp.setAttribute('data-app', appName);
trayApp.addEventListener('click', function() {
const win = openWindows.find(w => w.appName === appName);
if (win) {
if (win.element.classList.contains('minimized-window')) {
win.element.classList.remove('minimized-window');
win.element.style.display = 'flex';
} else {
win.element.classList.add('minimized-window');
win.element.style.display = 'none';
}
}
});
appTray.appendChild(trayApp);
// Store window reference
const windowObj = {
element: windowElement,
appName: appName,
trayElement: trayApp
};
openWindows.push(windowObj);
// Set as active window
bringToFront(windowElement);
// Add window controls
const header = windowElement.querySelector('.window-header');
const minimizeBtn = windowElement.querySelector('.window-control.minimize');
const maximizeBtn = windowElement.querySelector('.window-control.maximize');
const closeBtn = windowElement.querySelector('.window-control.close');
// Window dragging
header.addEventListener('mousedown', function(e) {
if (e.target.classList.contains('window-control')) return;
isDragging = true;
currentDraggedElement = windowElement;
dragOffset.x = e.clientX - windowElement.offsetLeft;
dragOffset.y = e.clientY - windowElement.offsetTop;
bringToFront(windowElement);
});
// Minimize window
minimizeBtn.addEventListener('click', function(e) {
e.stopPropagation();
windowElement.classList.add('minimized-window');
windowElement.style.display = 'none';
});
// Maximize window
maximizeBtn.addEventListener('click', function(e) {
e.stopPropagation();
windowElement.classList.toggle('maximized');
// Update maximize icon
const icon = maximizeBtn.querySelector('i');
if (windowElement.classList.contains('maximized')) {
icon.classList.remove('fa-square');
icon.classList.add('fa-clone');
} else {
icon.classList.add('fa-square');
icon.classList.remove('fa-clone');
}
});
// Close window
closeBtn.addEventListener('click', function(e) {
e.stopPropagation();
windowElement.remove();
trayApp.remove();
// Remove from open windows
openWindows = openWindows.filter(win => win.element !== windowElement);
// Activate next window if available
if (openWindows.length > 0) {
bringToFront(openWindows[openWindows.length - 1].element);
}
});
// Tab switching for file manager
if (appName === 'file-manager') {
const tabs = windowElement.querySelectorAll('.tab');
tabs.forEach(tab => {
tab.addEventListener('click', function() {
// Remove active class from all tabs
tabs.forEach(t => t.classList.remove('active'));
// Add active class to clicked tab
this.classList.add('active');
// Hide all tab content
const tabContents = windowElement.querySelectorAll('.tab-content');
tabContents.forEach(content => content.classList.remove('active'));
// Show corresponding tab content
const tabName = this.getAttribute('data-tab');
const content = windowElement.querySelector(`#${tabName}-tab`);
if (content) content.classList.add('active');
});
});
}
// Wallpaper selection for settings
if (appName === 'settings') {
const wallpaperPreviews = windowElement.querySelectorAll('.wallpaper-preview');
wallpaperPreviews.forEach(preview => {
preview.addEventListener('click', function() {
// Remove selected class from all
wallpaperPreviews.forEach(p => p.classList.remove('selected'));
// Add selected class to clicked
this.classList.add('selected');
// Change desktop background
const img = this.querySelector('img');
desktop.style.backgroundImage = `url('${img.src}')`;
});
});
}
}
// Get app icon based on app name
function getAppIcon(appName) {
const icons = {
'file-manager': 'fa-folder',
'text-editor': 'fa-file-alt',
'browser': 'fa-globe',
'settings': 'fa-cog',
'terminal': 'fa-terminal',
'calculator': 'fa-calculator'
};
return icons[appName] || 'fa-question';
}
// Bring window to front
function bringToFront(windowElement) {
// Move to top of z-index stack
const windows = document.querySelectorAll('.window');
let maxZ = 10;
windows.forEach(win => {
const z = parseInt(win.style.zIndex) || 0;
if (z > maxZ) maxZ = z;
win.style.zIndex = z;
});
windowElement.style.zIndex = maxZ + 1;
activeWindow = windowElement;
// Update tray app active state
const appName = openWindows.find(win => win.element === windowElement)?.appName;
if (appName) {
document.querySelectorAll('.tray-app').forEach(app => {
app.classList.remove('active');
});
const trayApp = document.querySelector(`.tray-app[data-app="${appName}"]`);
if (trayApp) trayApp.classList.add('active');
}
}
// Global mouse events for dragging
document.addEventListener('mousemove', function(e) {
if (isDragging && currentDraggedElement) {
const x = e.clientX - dragOffset.x;
const y = e.clientY - dragOffset.y;
// Keep window within bounds
const maxX = window.innerWidth - currentDraggedElement.offsetWidth;
const maxY = window.innerHeight - currentDraggedElement.offsetHeight - 50; // Account for taskbar
currentDraggedElement.style.left = `${Math.max(0, Math.min(maxX, x))}px`;
currentDraggedElement.style.top = `${Math.max(0, Math.min(maxY, y))}px`;
}
});
document.addEventListener('mouseup', function() {
isDragging = false;
currentDraggedElement = null;
});
// Window click to bring to front
desktop.addEventListener('click', function(e) {
const windowElement = e.target.closest('.window');
if (windowElement) {
bringToFront(windowElement);
}
});
// Context menu actions
document.getElementById('context-new-folder').addEventListener('click', function() {
alert('New folder created!');
contextMenu.style.display = 'none';
});
document.getElementById('context-new-file').addEventListener('click', function() {
alert('New file created!');
contextMenu.style.display = 'none';
});
// Initialize with File Manager open
openApp('file-manager');
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=TechITProfessional/hfos" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>