tspace-nfs
Version:
tspace-nfs is a Network File System (NFS) and provides both server and client capabilities for accessing files over a network.
188 lines (143 loc) • 5.82 kB
HTML
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{title}}</title>
{{logo.fav}}
<script src="https://cdn.tailwindcss.com/3.4.14"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.33.0/min/vs/loader.min.js"></script>
<style>
.vscode-bg {
background-color: #1e1e1e;
}
#editor {
height: calc(100vh - 64px);
}
</style>
</head>
<body class="bg-gray-100 flex flex-col h-screen">
<nav class="sticky top-0 bg-gray-300 border-gray-200 dark:bg-gray-900">
<div class="w-screen-xl flex items-center justify-between mx-auto p-4">
<div class="cursor-pointer flex items-center space-x-3 rtl:space-x-reverse" onclick="window.location.reload()">
{{logo.index}}
<h1 class="self-center text-2xl whitespace-nowrap text-gray-800 dark:text-white">
{{name}}
</h1>
</div>
</div>
</nav>
<div id="notify-container" class="space-y-4 fixed right-0 top-0 m-2 items-end justify-end z-50 pointer-events-none"></div>
<div id="editor" class="flex-grow"></div>
<div class="bg-white dark:bg-[#1e1e1e] p-4 flex justify-end">
<button class="bg-gray-300 dark:bg-gray-800 text-gray-800 dark:text-white text-[1.25rem] px-6 py-3 rounded-full"
onclick="saveFile()">
Save File
</button>
</div>
</body>
<script>
const $query = (element) => document.querySelector(element)
const url = window.location.href
const baseUrl = `${window.location.protocol}//${window.location.host}/`
const path = url.replace(baseUrl, '').replace('studio','studio/api')
const filename = path.split('/').pop()
async function save (content) {
try {
const response = await fetch(`${baseUrl}${path}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ content })
})
notify({
type: 'success',
message : `The file '${filename}' has been saved`
})
} catch (err) {
notify({ type : 'error', message : `The file '${filename}' encountered an error '${err.message}'` })
}
}
async function notify({ type, message }) {
const notifyContainer = $query('#notify-container')
const notify = document.createElement('div');
const capitalizedType = type.charAt(0).toUpperCase() + type.slice(1);
switch(type.toLowerCase()) {
case 'success':
notify.className = 'max-w-md text-center bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative';
break;
case 'error':
notify.className = 'max-w-md text-center bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative';
break;
case 'info':
notify.className = 'max-w-md text-center bg-blue-100 border border-blue-400 text-blue-700 px-4 py-3 rounded relative';
break;
case 'warning':
notify.className = 'max-w-md text-center bg-yellow-100 border border-yellow-400 text-yellow-700 px-4 py-3 rounded relative';
break;
default:
notify.className = 'max-w-md text-center bg-gray-100 border border-gray-400 text-gray-700 px-4 py-3 rounded relative';
}
notify.innerHTML = `
<strong class="font-bold">${capitalizedType}</strong>
<span class="block sm:inline">${message}</span>
`;
notifyContainer.appendChild(notify);
setTimeout(() => {
notify.remove()
}, 2500)
}
function themeToggleMode() {
const theme = localStorage.getItem('theme') == null ? 'dark' : localStorage.getItem('theme')
const isDark = theme === 'dark'
const prefixToReplace = isDark ? 'light:' : 'dark:';
const newPrefix = isDark ? 'dark:' : 'light:';
const body = document.body;
body.className = body.className.split(' ').map(className => {
return className.startsWith(prefixToReplace)
? className.replace(prefixToReplace, newPrefix)
: className
}).join(' ');
const elements = document.body.getElementsByTagName('*');
for (let element of elements) {
if(!element.classList) continue
element.classList.forEach(className => {
if (className.startsWith(prefixToReplace)) {
element.classList.replace(className, className.replace(prefixToReplace, newPrefix));
}
})
}
}
document.addEventListener('DOMContentLoaded', () => {
themeToggleMode()
require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.33.0/min/vs' } });
require(['vs/editor/editor.main'], function() {
const theme = localStorage.getItem('theme') == null ? 'dark' : localStorage.getItem('theme')
const editor = monaco.editor.create($query('#editor'), {
language: "{{language}}",
theme: `vs-${theme}`,
automaticLayout: true,
});
fetch(`${baseUrl}${path}`)
.then(response => response.text())
.then(data => {
editor.setValue(data)
})
.catch(err => notify({ type : 'error', message : `The file '${filename}' encountered an error '${err.message}'` }));
document.addEventListener("keydown", (event) => {
if (event.ctrlKey && event.key === "s") {
event.preventDefault();
const content = editor.getValue();
save(content)
return
}
})
window.saveFile = function() {
const content = editor.getValue()
save(content)
}
})
})
</script>
</html>