A vue3-based Mac OS simulation
This is a work-in-progress. Please report Bugs at GitHub
- Login screen with video as in Sonoma (works on Safari and Firefox on a Mac, but not on Chrome or Windows, due to the use of remote MOV files) - you can supply your own video (MP4 recommended)
- Menus: graphically functional,
but no action on click(WIP) - Windows:
- functional, except menu buttons: closing/minimizing/full-screen
- background, foreground colors, and opacity can be changed
- resizable and movable
- Text Viewer: shows some predefined text file (ANSI codes handled) or static text
- Photo Viewer: shows one picture
- PDF Viewer: short docs recommended
- Terminal Windows: functional, offers a few commands by default:
- help [cmd]
- ls [-l] [files]
- cd [dir]
- pwd
- cat [file]
- history [-c]
- clear
- you can use your own commands (passed as an array of simple objects)
- Browser: simple predefined URL browser, fully functional (iframe)
- Being migrated to Typescript (WIP)
- everything shown is provided by host, users can't access anything not provided
- browser can follow links (may or not work, depending on destination site [XSS security])
- some URLs won't work, due to Cross-Site Restrictions (e.g. Wikipedia works, Google doesn't...):
- if user figures a way to go to risky sites, he endangers his own computer, not the host
there's no state: if user refreshes the page, he restarts the interface.State is maintained between sessions (localStorage)- alt/ctrl-tab are not captured inside the UI (can't be done, to my knowledge) you can browse a local page from the host itself, but are limited to external sites
- click in menus (WIP)
- more terminal commands
- use of icons in docking bar
- auto-hiding docking bar
browser URL can be changed(cancelled for now)- clickable documents on desktop
- improve moving windows for more fluidity (use draggable?)
% git clone https://github.com/peergum/macos-vue.git
% cd macos-vue
% npm install
% npm run dev
You can then access the demo at http://localhost:5173
npm install --save @peergum/macos-vue
main.js:
import {createApp} from 'vue'
import App from './App.vue'
import MacOS from "macos-vue";
import "macos-vue/dist/style.css";
createApp(App)
.use(MacOS)
.mount('#app')
component usage:
<script setup>
const defs = {
// environment definitions, see below
}
</script>
<template>
...
<MacOS :definitions="defs"/>
...
</template>
See App.vue
for a concrete example.
Notes:
- v1.2: added type=plugin and pluginName=... to windows
- v1.1: extra terminal commands are now passed inside
system
object as'commands
, and no more inside the terminal window parameters.
The configuration parameter describes your whole MacOS environment:
const defs = {
menu: {
logo: <logo_file>, // by default Apple logo
items: <menu_items>,
},
windows: [
<window_list>,
],
system: {
dir: <directory_structure>,
user: "user_name",
host: "host_name",
commands: <command_list>
},
plugins: {
<plugin_name>: [<plugin_component>,<plugin_icon>],
},
saverUrl: <screensaver_mov_url>
};
const menu_items = [
{
name: "menu1", // usually App name
menu: [
{
name: "option1",
menu: [
{
name: "suboption1",
},
{
name: "suboption2",
},
{
name: "---", // horizontal separator
},
{
name: "suboption3",
},
...
],
},
{
name: "option2",
menu: [
...
],
},
{
name: "---", // vertical separator
},
...
]
}
];
const window_list = [
<window1_def>,
<window2_def>,
...
];
// viewer window
const viewer_def: {
name: "View 1",
type: 'viewer',
bg: 'gray', // standard CSS color names or values
text: 'white',
w: 600, // a proportional value to virtual screen width (def: 1000)
h: 400, // a proportional value to virtual screen height (def: 1000)
x: 10, // proportional x (top left corner)
y: 20, // proportional y (top left corner)
contentUrl: './src/example/demo.txt', // a text file
content: "test", // or a default static text
class: 'text-xs', // additional class to pass
};
const picture_viewer = {
name: "My Beautiful Picture",
type: 'photo',
picture: './src/example/designer.png', // picture to show
x: 650, // proportional size and position
y: 50,
w: 150,
h: 200,
};
const browser_window = {
name: "My Browser",
type: 'browser',
w: 600, // proportional size + position
h: 600,
x: 200,
y: 200,
content: "https://wikipedia.org", // URL to browse
};
const terminal = {
name: "Terminal",
type: 'terminal',
w: 600, // proportional size and position
h: 600,
x: 275,
y: 230,
bg: 'black', // colors
text: 'white',
};
const plugin_window = {
name: "My Plugin",
type: "plugin",
pluginName: <plugin_name>,
...
}
const command_list = {
"hello": [hello, "[name]", "say hello"], // function, args description, cmd description
}
// example of command: should return a string ending with \n
// note: command is not passed as args[0]
const hello = (args) => {
if (!args.length) {
return "Hello to you too!\n";
}
return "Hello! But I'm no " + args[0] + "...\n";
};
// file system is simple: directory if an object, path to a file if a string (under /public)
const directory_structure = {
'demo_files': {
'some_text': '/files/some_text',
'blah': '/files/blah',
'more': {"some long filename": '/files/somewhere/something'},
},
'other': {
'blah.csv': '/files/blah.csv>',
'more_blah.csv': '/files/more_blah.csv',
'worse.csv': '/files/worse.csv',
},
'README.md': '/files/README.md',
};
You can find some URLs here, directly from Apple to avoid a copyright infringement (the URL is public, although the certificate is fake if you use HTTPS, which can cause issues)
My recommendation, for this to work on all platforms, is to use your own MP4 video (self-hosted or remote) instead of Apple's ones, that are using .MOV files (only supported by default on Macs in Safari or Firefox). Alternately, you can convert one from Apple to MP4, but if you host it yourself, you may infringe copyright laws.
macos-vue component - This component simulates a Mac OS interface
Copyright (C) 2024 Phil Hilger
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.