Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ repository.

- [v86](https://github.com/copy/v86)
- [xterm.js](https://github.com/xtermjs/xterm.js)
- [tailwindcss](https://tailwindcss.com/)
- [bun](https://bun.sh)
- [vite](https://vitejs.dev/)

Expand Down
27 changes: 23 additions & 4 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,17 @@
<a class="toolbar-button" href="https://github.com/daipham3213" _target="_blank" rel="noopener noreferrer">
<img class="botton-img" id="github" alt="GitHub - daipham3213" src="/img/github.svg" width="16" height="16" />
</a>
<a class="toolbar-button" href="https://review.opendev.org/q/owner:daipham.3213@gmail.com" _target="_blank" rel="noopener noreferrer">
<img class="button-img" id="opendev" alt="OpenDev - daipham.3213@gmail.com" src="/img/opendev.svg" width="16" height="16" />
<a class="toolbar-button" href="https://review.opendev.org/q/owner:daipham.3213@gmail.com" _target="_blank"
rel="noopener noreferrer">
<img class="button-img" id="opendev" alt="OpenDev - daipham.3213@gmail.com" src="/img/opendev.svg" width="16"
height="16" />
</a>
<a class="toolbar-button" href="https://www.linkedin.com/in/daipham-3213" _target="_blank" rel="noopener noreferrer">
<img class="button-img" id="linkedin" alt="LinkedIn - daipham-3213" src="/img/linkedin.svg" width="16" height="16" />
<a class="toolbar-button" href="https://www.linkedin.com/in/daipham-3213" _target="_blank"
rel="noopener noreferrer">
<img class="button-img" id="linkedin" alt="LinkedIn - daipham-3213" src="/img/linkedin.svg" width="16"
height="16" />
</a>
<button id="upload-button" title="Upload File" style="display: none;">Upload</button>
</div>
</div>
<div id="terminal"></div>
Expand All @@ -46,6 +51,20 @@ <h6>Loading resources, please wait...</h6>
<canvas id="serial-canvas" width="800" height="600"></canvas>
</div>
</div>
<div id="modal-overlay">
<div id="upload-modal">
<button id="modal-close-button" title="Close">&times;</button>
<h3>Upload File</h3>
<div class="form-group">
<p> All files will be uploaded to `/home/daiplg` directory. </p>
</div>
<div class="form-group">
<button id="select-file-button">Select File...</button>
<input type="file" id="file-input" style="display: none;" multiple>
<span id="selected-filename">No file selected</span>
</div>
</div>
</div>
<script src="/v86/libv86.js"></script>
<script type="module" src="/src/js/main.js"></script>
</body>
Expand Down
1 change: 1 addition & 0 deletions public/contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"fsroot":[["daiplg",4096,1743524547,16877,0,0,[]]],"version":3,"size":4096}
10 changes: 9 additions & 1 deletion src/js/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { override, loadAddons } from './terminal';
import { loadAddons, override } from './terminal';
import registerUploadFilesModal from './upload-files';

override();

Expand All @@ -22,7 +23,13 @@ const emulator = new window.V86({
url: import.meta.env.VITE_ROOTFS_ISO,
async: false,
},
filesystem: {
basefs: '/contents.json',
baseurl: '/flat',
},
autostart: true,
disable_keyboard: true,
disable_speaker: true,
network_relay_url: import.meta.env.VITE_NETWORK_RELAY,
});

Expand All @@ -41,6 +48,7 @@ emulator.add_listener('serial0-output-byte', (byte) => {
state.textContent = '';

loadAddons(emulator.serial_adapter.term);
registerUploadFilesModal({ emulator });
terminalElement.focus();
}
});
Expand Down
7 changes: 1 addition & 6 deletions src/js/terminal.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@ const override = () => {
black: '#21222C',
brightBlack: '#6272A4',
},
// Tell xterm how many rows/cols (FitAddon will adjust this)
rows: 30,
cols: 80,
allowProposedApi: true,
};
super({ ...defaultOptions, ...options });
Expand Down Expand Up @@ -66,9 +63,7 @@ const loadAddons = (terminal) => {
terminal.loadAddon(unicode11Addon);
terminal.loadAddon(clipboardAddon);

document.addEventListener('DOMContentLoaded', () => {
fitAddon.fit();
});
fitAddon.fit();

// eslint-disable-next-line no-param-reassign
terminal.unicode.activeVersion = '11';
Expand Down
84 changes: 84 additions & 0 deletions src/js/upload-files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
const registerUploadFilesModal = ({ emulator }) => {
const uploadButton = document.getElementById('upload-button');
const modalOverlay = document.getElementById('modal-overlay');
const modalCloseButton = document.getElementById('modal-close-button');
const selectFileButton = document.getElementById('select-file-button');
const fileInput = document.getElementById('file-input');
const selectedFilenameSpan = document.getElementById('selected-filename');

const openModal = () => {
if (modalOverlay) {
modalOverlay.classList.add('modal-visible');
}
};

const closeModal = () => {
if (modalOverlay) {
modalOverlay.classList.remove('modal-visible');
if (selectedFilenameSpan) {
selectedFilenameSpan.textContent = 'No file selected';
}
if (fileInput) {
fileInput.value = '';
}
}
};

if (uploadButton) {
uploadButton.addEventListener('click', openModal);
}

if (modalCloseButton) {
modalCloseButton.addEventListener('click', closeModal);
}
if (modalOverlay) {
modalOverlay.addEventListener('click', (event) => {
if (event.target === modalOverlay) {
closeModal();
}
});
}

document.addEventListener('keydown', (event) => {
if (
event.key === 'Escape' &&
modalOverlay &&
modalOverlay.classList.contains('modal-visible')
) {
closeModal();
}
});

if (selectFileButton && fileInput) {
selectFileButton.addEventListener('click', () => {
fileInput.click();
});
}

if (fileInput && selectedFilenameSpan) {
fileInput.addEventListener('change', () => {
if (fileInput.files.length > 0) {
selectFileButton.textContent = Array.from(fileInput.files).reduce(
(acc, file, i) => {
const separator = i === 0 ? '' : ', ';
return `${separator}${file.name}`;
},
);
Array.from(fileInput.files).forEach((_file) => {
const reader = new FileReader();
const path = `/${_file.name}`;
reader.onload = (f) => {
const data = new Uint8Array(f.target.result);
return emulator.create_file(path, data);
};
reader.readAsArrayBuffer(_file);
});
} else {
selectedFilenameSpan.textContent = 'No file selected';
}
closeModal();
});
}
};

export default registerUploadFilesModal;
112 changes: 112 additions & 0 deletions src/styles/app-modal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#modal-overlay {
display: none;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.7);
z-index: 1000;

justify-content: center;
align-items: center;
}

#modal-overlay.modal-visible {
display: flex;
}

#upload-modal {
background-color: #3a3a3a;
padding: 25px 30px;
border-radius: 5px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
min-width: 350px;
max-width: 90%;
position: relative;
color: #eee;
border: 1px solid #555;
}

#modal-close-button {
position: absolute;
top: 8px;
right: 10px;
background: none;
border: none;
font-size: 24px;
line-height: 1;
color: #aaa;
cursor: pointer;
padding: 0;
}

#modal-close-button:hover {
color: #eee;
}

#upload-modal h3 {
margin-top: 0;
margin-bottom: 20px;
color: #f0f0f0;
text-align: center;
font-family: sans-serif;
}

#upload-modal .form-group {
margin-bottom: 15px;
}

#upload-modal label {
display: block;
margin-bottom: 5px;
font-size: 14px;
color: #ccc;
font-family: sans-serif;
}

#upload-modal input[type='text'] {
width: 100%;
padding: 10px;
background-color: #2d2d2d;
border: 1px solid #555;
color: #eee;
border-radius: 3px;
font-family: monospace;
font-size: 14px;
}

#upload-modal input[type='text']:focus {
outline: none;
border-color: #777;
box-shadow: 0 0 5px rgba(150, 150, 150, 0.2);
}

#upload-modal #select-file-button {
background-color: #5a5a5a;
border: 1px solid #777;
color: #eee;
padding: 8px 12px;
margin-right: 10px;
cursor: pointer;
border-radius: 3px;
font-size: 14px;
font-family: sans-serif;
transition: background-color 0.2s ease;
}

#upload-modal #select-file-button:hover {
background-color: #6a6a6a;
}

#upload-modal #selected-filename {
font-size: 13px;
color: #aaa;
font-family: sans-serif;
display: inline-block;
max-width: 180px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
vertical-align: middle;
}
1 change: 1 addition & 0 deletions src/styles/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
@import 'terminal.css';
@import 'terminal-toolbar.css';
@import 'serial.css';
@import 'app-modal.css';

html,
body {
Expand Down