mirror of
https://github.com/linuxserver/emulatorjs.git
synced 2026-02-23 00:01:26 +08:00
add all funtionality to file browser and style it a bit
This commit is contained in:
parent
2285047e4e
commit
e5e478c3ea
@ -0,0 +1,40 @@
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.right {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.directory, .file {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
button {
|
||||
border: 2px solid #000;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.fileTable {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
td, th {
|
||||
border: 2px solid #ddd;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
tr:nth-child(even){
|
||||
background-color: #f2f2f2;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background-color: #ddd;
|
||||
}
|
||||
|
||||
@ -9,7 +9,13 @@
|
||||
</head>
|
||||
<body>
|
||||
<span id="buttons">
|
||||
<button onclick="downloadBackup()">DL Full Backup</button>
|
||||
<input id="folderName" type="text" placeholder="Enter Directory Name"></input>
|
||||
<button onclick="createFolder()">Create Folder</button>
|
||||
<button onclick="$('#uploadInput').trigger( 'click' )">Upload File</button>
|
||||
<input class="hidden" id="uploadInput" type='file' onchange="upload(this);" />
|
||||
<button class="right" onclick="downloadBackup()">DL Full Backup</button>
|
||||
<button class="right" onclick="$('#uploadBackup').trigger( 'click' )">Upload Full Backup</button>
|
||||
<input class="hidden" id="uploadBackup" type='file' onchange="uploadBackup(this);" />
|
||||
</span>
|
||||
<div id="filebrowser"></div>
|
||||
</body>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
//Default vars
|
||||
var storeName = 'RetroArch';
|
||||
var afs;
|
||||
BrowserFS.install(window);
|
||||
var fs = require('fs');
|
||||
@ -16,21 +17,36 @@ async function renderFiles(directory) {
|
||||
let items = await fs.readdirSync(directory);
|
||||
let baseName = directory.split('/').at(-1);
|
||||
let parentFolder = directory.replace(baseName,'');
|
||||
let parentLink = $('<div>').addClass('directory').attr('onclick', 'renderFiles(\'' + parentFolder + '\');').text('..');
|
||||
if (directory == '/') {
|
||||
directory = '';
|
||||
let parentLink = $('<td>').addClass('directory').attr('onclick', 'renderFiles(\'' + parentFolder + '\');').text('..');
|
||||
if (directoryClean == '/') {
|
||||
directoryClean = '';
|
||||
}
|
||||
$('#filebrowser').append(parentLink);
|
||||
let table = $('<table>').addClass('fileTable');
|
||||
let tableHeader = $('<tr>');
|
||||
for await (name of ['Name', 'Type', 'Delete']) {
|
||||
tableHeader.append($('<th>').text(name));
|
||||
}
|
||||
let parentRow = $('<tr>');
|
||||
for await (item of [parentLink, $('<td>').text('Parent'), $('<td>')]) {
|
||||
parentRow.append(item);
|
||||
}
|
||||
table.append(tableHeader,parentRow);
|
||||
$('#filebrowser').append(table);
|
||||
if (items.length > 0) {
|
||||
for await (let item of items) {
|
||||
let tableRow = $('<tr>');
|
||||
let itemClean = item.replace("'","|");
|
||||
if (fs.lstatSync(directory + '/' + item).isDirectory()) {
|
||||
let link = $('<div>').addClass('directory').attr('onclick', 'renderFiles(\'' + directoryClean + '/' + itemClean + '\');').text(item);
|
||||
$('#filebrowser').append(link);
|
||||
var link = $('<td>').addClass('directory').attr('onclick', 'renderFiles(\'' + directoryClean + '/' + itemClean + '\');').text(item);
|
||||
var type = $('<td>').text('Dir');
|
||||
} else {
|
||||
let link = $('<div>').addClass('file').attr('onclick', 'downloadFile(\'' + directoryClean + '/' + itemClean + '\');').text(item);
|
||||
$('#filebrowser').append(link);
|
||||
var link = $('<td>').addClass('file').attr('onclick', 'downloadFile(\'' + directoryClean + '/' + itemClean + '\');').text(item);
|
||||
var type = $('<td>').text('File');
|
||||
}
|
||||
for await (item of [link, type, $('<td>')]) {
|
||||
tableRow.append(item);
|
||||
}
|
||||
table.append(tableRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -51,6 +67,48 @@ async function downloadFile(file) {
|
||||
$("body").remove(a);
|
||||
}
|
||||
|
||||
// Upload file to current directory
|
||||
async function upload(input) {
|
||||
let directory = $('#filebrowser').data('directory');
|
||||
if (directory == '/') {
|
||||
directoryUp = '';
|
||||
} else {
|
||||
directoryUp = directory;
|
||||
}
|
||||
if (input.files && input.files[0]) {
|
||||
let reader = new FileReader();
|
||||
reader.onload = function(e) {
|
||||
let fileName = input.files[0].name;
|
||||
let data = e.target.result;
|
||||
fs.writeFileSync(directoryUp + '/' + fileName, Buffer.from(data));
|
||||
renderFiles(directory);
|
||||
}
|
||||
reader.readAsArrayBuffer(input.files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Create a directory
|
||||
async function createFolder() {
|
||||
let folderName = $('#folderName').val();
|
||||
$('#folderName').val('');
|
||||
if ((folderName.length == 0) || (folderName.includes('/'))) {
|
||||
alert('Bad or Null Directory Name');
|
||||
return '';
|
||||
}
|
||||
let directory = $('#filebrowser').data('directory');
|
||||
if (directory == '/') {
|
||||
directoryUp = '';
|
||||
} else {
|
||||
directoryUp = directory;
|
||||
}
|
||||
let createD = directoryUp + '/' + folderName;
|
||||
if (!fs.existsSync(createD)){
|
||||
fs.mkdirSync(createD);
|
||||
}
|
||||
renderFiles(directory);
|
||||
}
|
||||
|
||||
|
||||
// Download a full backup of all files
|
||||
async function downloadBackup() {
|
||||
var zip = new JSZip();
|
||||
@ -77,7 +135,7 @@ async function downloadBackup() {
|
||||
let url = window.URL || window.webkitURL;
|
||||
link = url.createObjectURL(blob);
|
||||
let a = $("<a />");
|
||||
a.attr("download", 'emulatorjs.zip');
|
||||
a.attr("download", storeName + '.zip');
|
||||
a.attr("href", link);
|
||||
$("body").append(a);
|
||||
a[0].click();
|
||||
@ -85,7 +143,59 @@ async function downloadBackup() {
|
||||
});
|
||||
}
|
||||
|
||||
// Create IndexDB filestore
|
||||
// Upload a full backup
|
||||
async function uploadBackup(input) {
|
||||
if (input.files && input.files[0]) {
|
||||
let reader = new FileReader();
|
||||
reader.onload = async function(e) {
|
||||
let data = e.target.result;
|
||||
var zip = new JSZip();
|
||||
// Load zip from data
|
||||
zip.loadAsync(data).then(async function(contents) {
|
||||
// Purge current storage
|
||||
async function rmDir(dirPath, removeSelf) {
|
||||
try { var files = fs.readdirSync(dirPath); }
|
||||
catch(e) { return; }
|
||||
if (files.length > 0) {
|
||||
for await (let file of files) {
|
||||
var filePath = dirPath + '/' + file;
|
||||
if (fs.statSync(filePath).isFile()) {
|
||||
fs.unlinkSync(filePath);
|
||||
} else {
|
||||
rmDir(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dirPath !== '/') {
|
||||
fs.rmdirSync(dirPath)
|
||||
}
|
||||
return '';
|
||||
}
|
||||
await rmDir('/');
|
||||
// Unzip the files to the FS by name
|
||||
for await (let fileName of Object.keys(contents.files)) {
|
||||
if (fileName.endsWith('/')) {
|
||||
if (! fs.existsSync('/' + fileName)) {
|
||||
fs.mkdirSync('/' + fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
for await (let fileName of Object.keys(contents.files)) {
|
||||
if (! fileName.endsWith('/')) {
|
||||
zip.file(fileName).async('arraybuffer').then(function(content) {
|
||||
fs.writeFileSync('/' + fileName, Buffer.from(content));
|
||||
});
|
||||
}
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
||||
renderFiles('/');
|
||||
});
|
||||
}
|
||||
reader.readAsArrayBuffer(input.files[0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Create Async filestore
|
||||
async function setupFileSystem() {
|
||||
var imfs = new BrowserFS.FileSystem.InMemory();
|
||||
afs = new BrowserFS.FileSystem.AsyncMirror(imfs,
|
||||
@ -95,7 +205,7 @@ async function setupFileSystem() {
|
||||
setupMounts();
|
||||
});
|
||||
},
|
||||
'RetroArch'));
|
||||
storeName));
|
||||
};
|
||||
|
||||
// Setup mounts
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user