mirror of
https://github.com/ducbao414/win32.run.git
synced 2025-12-15 08:42:49 +09:00
399 lines
10 KiB
JavaScript
399 lines
10 KiB
JavaScript
import { queueProgram, clipboard, selectingItems, hardDrive, clipboard_op } from './store';
|
|
import { recycle_bin_id, protected_items } from './system';
|
|
import * as utils from './utils';
|
|
import { get } from 'svelte/store';
|
|
import short from 'short-uuid';
|
|
import * as util from './utils';
|
|
import * as idb from 'idb-keyval';
|
|
import * as finder from './finder';
|
|
import {Buffer} from 'buffer';
|
|
|
|
export function copy(){
|
|
clipboard_op.set('copy');
|
|
clipboard.set(get(selectingItems));
|
|
console.log('copy');
|
|
}
|
|
|
|
export function cut(){
|
|
clipboard_op.set('cut');
|
|
clipboard.set(get(selectingItems));
|
|
console.log('cut');
|
|
}
|
|
|
|
export function paste(id, new_id=null){
|
|
console.log('paste to', id);
|
|
console.log('clipboard_op', get(clipboard_op));
|
|
console.log(get(hardDrive)[id]);
|
|
if(get(hardDrive)[id] == null || get(hardDrive)[id].type == 'file'){
|
|
console.log('target is not a dir');
|
|
return;
|
|
}
|
|
|
|
if(get(clipboard).length == 0){
|
|
console.log('clipboard is empty');
|
|
return;
|
|
}
|
|
|
|
for(let fs_id of get(clipboard)){
|
|
clone_fs(fs_id, id, new_id);
|
|
|
|
if(get(clipboard_op) == 'cut'){
|
|
del_fs(fs_id);
|
|
}
|
|
}
|
|
|
|
clipboard_op.set('copy')
|
|
clipboard.set([]);
|
|
}
|
|
|
|
export function del_fs(id){
|
|
if(protected_items.includes(id)){
|
|
console.log(id, 'is protected');
|
|
return;
|
|
}
|
|
let obj = get(hardDrive)[id];
|
|
|
|
let child_ids = [
|
|
...obj.files,
|
|
...obj.folders
|
|
]
|
|
if(get(hardDrive)[obj.parent] != null){
|
|
console.log('delete from parent', obj.parent)
|
|
|
|
hardDrive.update(data => {
|
|
data[obj.parent].files = data[obj.parent].files.filter(el => el != obj.id);
|
|
data[obj.parent].folders = data[obj.parent].folders.filter(el => el != obj.id);
|
|
return data;
|
|
})
|
|
}
|
|
|
|
hardDrive.update(data => {
|
|
delete data[id];
|
|
return data;
|
|
})
|
|
|
|
for(let child_id of child_ids){
|
|
del_fs(child_id);
|
|
}
|
|
}
|
|
|
|
export function clone_fs(obj_current_id, parent_id, new_id=null){
|
|
let obj = {...get(hardDrive)[obj_current_id]};
|
|
|
|
if(new_id == null){
|
|
obj.id = short.generate();
|
|
} else {
|
|
obj.id = new_id;
|
|
}
|
|
|
|
obj.parent = parent_id;
|
|
|
|
let parent_items_names = [
|
|
...get(hardDrive)[parent_id].files.map(el => get(hardDrive)[el].name),
|
|
...get(hardDrive)[parent_id].folders.map(el => get(hardDrive)[el].name),
|
|
]
|
|
let appendix = 2;
|
|
let basename = obj.basename;
|
|
while(parent_items_names.includes(basename + obj.ext)){
|
|
basename = obj.basename + ' ' + appendix;
|
|
appendix++;
|
|
}
|
|
obj.basename = basename;
|
|
obj.name = basename + obj.ext;
|
|
|
|
//backup files & folders
|
|
console.log(obj)
|
|
let files = [...obj.files];
|
|
let folders = [...obj.folders];
|
|
obj.files = [];
|
|
obj.folders = [];
|
|
|
|
//save to hard drive
|
|
hardDrive.update(data => {
|
|
data[obj.id] = obj;
|
|
return data;
|
|
})
|
|
console.log('cloning', obj.id)
|
|
|
|
if(obj.type == 'file'){
|
|
|
|
hardDrive.update(data => {
|
|
data[parent_id].files.push(obj.id);
|
|
return data;
|
|
})
|
|
} else if(obj.type == 'folder'){
|
|
hardDrive.update(data => {
|
|
data[parent_id].folders.push(obj.id);
|
|
return data;
|
|
})
|
|
}
|
|
|
|
//recursively clone child items
|
|
for(let child of [...files, ...folders]){
|
|
clone_fs(child, obj.id);
|
|
}
|
|
}
|
|
|
|
|
|
export async function new_fs_item(type, ext, seedname, parent_id, file=null){
|
|
if(type == null || seedname == null || parent_id == null){
|
|
return;
|
|
}
|
|
|
|
let item = {
|
|
"id": short.generate(),
|
|
"type": type,
|
|
"path": "",
|
|
"name": "",
|
|
"storage_type": "local",
|
|
"url": short.generate(),
|
|
"ext": ext,
|
|
"level": 0,
|
|
"parent": parent_id,
|
|
"size": 1,
|
|
"files": [],
|
|
"folders": [],
|
|
"basename": ""
|
|
}
|
|
|
|
let files = get(hardDrive)[parent_id].files.map(el => get(hardDrive)[el]);
|
|
let folders = get(hardDrive)[parent_id].folders.map(el => get(hardDrive)[el]);
|
|
|
|
let parent_items_names = [
|
|
...files.map(el => el.name),
|
|
...folders.map(el => el.name)
|
|
]
|
|
|
|
let appendix = 2;
|
|
seedname = utils.sanitize_filename(seedname);
|
|
let basename = seedname;
|
|
while(parent_items_names.includes(basename + ext)){
|
|
basename = seedname + ' ' + appendix;
|
|
appendix++;
|
|
}
|
|
item.basename = basename;
|
|
item.name = basename + item.ext;
|
|
|
|
if(file != null){
|
|
await idb.set(item.url, file);
|
|
item.size = Math.ceil(file.size/1024);
|
|
|
|
} else if(type == 'file'){
|
|
console.log('fetch empty file')
|
|
file = await file_from_url(`/empty/empty${item.ext}`, item.name);
|
|
await idb.set(item.url, file);
|
|
item.size = Math.ceil(file.size/1024);
|
|
|
|
} else {
|
|
item.url = '';
|
|
}
|
|
|
|
|
|
hardDrive.update(data => {
|
|
data[item.id] = item;
|
|
return data;
|
|
})
|
|
if(type == 'file'){
|
|
hardDrive.update(data => {
|
|
data[parent_id].files.push(item.id);
|
|
return data;
|
|
})
|
|
} else if (type == 'folder'){
|
|
hardDrive.update(data => {
|
|
data[parent_id].folders.push(item.id);
|
|
return data;
|
|
})
|
|
}
|
|
|
|
return item.id;
|
|
}
|
|
|
|
export async function new_fs_item_raw(item, parent_id){
|
|
if(parent_id == null){
|
|
return;
|
|
}
|
|
item.id = short.generate();
|
|
item.parent = parent_id;
|
|
|
|
if(!['file', 'folder'].includes(item.type)){
|
|
item.type = 'file';
|
|
}
|
|
if(item.storage_type == null){
|
|
item.storage_type = 'local'
|
|
}
|
|
if(item.ext == null){
|
|
item.ext = '';
|
|
}
|
|
if(item.icon == null){
|
|
item.icon = '/images/xp/icons/ApplicationWindow.png'
|
|
}
|
|
if(item.files == null){
|
|
item.files = [];
|
|
}
|
|
if(item.folders == null){
|
|
item.folders = [];
|
|
}
|
|
|
|
let files = get(hardDrive)[parent_id].files.map(el => get(hardDrive)[el]);
|
|
let folders = get(hardDrive)[parent_id].folders.map(el => get(hardDrive)[el]);
|
|
|
|
let parent_items_names = [
|
|
...files.map(el => el.name),
|
|
...folders.map(el => el.name)
|
|
]
|
|
|
|
let appendix = 2;
|
|
let seedname = utils.sanitize_filename(item.basename);
|
|
let basename = seedname;
|
|
while(parent_items_names.includes(basename + item.ext)){
|
|
basename = seedname + ' ' + appendix;
|
|
appendix++;
|
|
}
|
|
item.basename = basename;
|
|
item.name = basename + item.ext;
|
|
|
|
if(item.file != null){
|
|
item.url = short.generate();
|
|
await idb.set(item.url, item.file);
|
|
item.size = Math.ceil(file.size/1024);
|
|
delete item.file;
|
|
} else if(item.executable){
|
|
item.url = './programs/webapp.svelte';
|
|
}
|
|
|
|
|
|
hardDrive.update(data => {
|
|
data[item.id] = item;
|
|
return data;
|
|
})
|
|
if(item.type == 'file'){
|
|
hardDrive.update(data => {
|
|
data[parent_id].files.push(item.id);
|
|
return data;
|
|
})
|
|
} else if (item.type == 'folder'){
|
|
hardDrive.update(data => {
|
|
data[parent_id].folders.push(item.id);
|
|
return data;
|
|
})
|
|
}
|
|
|
|
return item.id;
|
|
}
|
|
|
|
export function get_path(id){
|
|
return finder.to_url(id);
|
|
}
|
|
|
|
export async function save_file(fs_id, file){
|
|
if(get(hardDrive)[fs_id] == null){
|
|
console.log(fs_id, 'not exist');
|
|
return;
|
|
}
|
|
let url = short.generate();
|
|
await idb.set(url, file);
|
|
hardDrive.update(data => {
|
|
data[fs_id].url = url;
|
|
data[fs_id].storage_type = 'local';
|
|
return data;
|
|
})
|
|
}
|
|
|
|
export async function save_file_as(basename, ext, file, parent_id, new_id=null){
|
|
ext = ext.toLowerCase();
|
|
if(util.extname(basename) == ext){
|
|
basename = util.basename(basename, ext);
|
|
}
|
|
|
|
let url = short.generate();
|
|
await idb.set(url, file);
|
|
|
|
if(new_id == null){
|
|
new_id = short.generate();
|
|
}
|
|
|
|
let obj = {
|
|
"id": new_id,
|
|
"type": 'file',
|
|
"path": "",
|
|
"name": basename + ext,
|
|
"storage_type": "local",
|
|
"url": url,
|
|
"ext": ext,
|
|
"level": 0,
|
|
"parent": parent_id,
|
|
"size": Math.round(file.size/1024),
|
|
"files": [],
|
|
"folders": [],
|
|
"basename": basename
|
|
}
|
|
|
|
let parent_items_names = [
|
|
...get(hardDrive)[parent_id].files.map(el => get(hardDrive)[el].name),
|
|
...get(hardDrive)[parent_id].folders.map(el => get(hardDrive)[el].name),
|
|
]
|
|
let appendix = 2;
|
|
basename = obj.basename;
|
|
while(parent_items_names.includes(basename + obj.ext)){
|
|
basename = obj.basename + ' ' + appendix;
|
|
appendix++;
|
|
}
|
|
obj.basename = basename;
|
|
obj.name = basename + obj.ext;
|
|
|
|
|
|
hardDrive.update(data => {
|
|
data[obj.id] = obj;
|
|
data[parent_id].files.push(obj.id);
|
|
return data;
|
|
})
|
|
}
|
|
|
|
export async function get_file(id){
|
|
let fs_item = get(hardDrive)[id];
|
|
let file;
|
|
if(fs_item.storage_type == 'remote'){
|
|
file = await file_from_url(fs_item.url);
|
|
} else if(fs_item.storage_type == 'local') {
|
|
file = await idb.get(fs_item.url);
|
|
console.log(file);
|
|
}
|
|
file = new File([file], fs_item.name, {type: file.type})
|
|
return file;
|
|
}
|
|
|
|
export async function get_url(id){
|
|
let fs_item = get(hardDrive)[id];
|
|
|
|
if(fs_item.storage_type == 'remote'){
|
|
return fs_item.url;
|
|
} else if(fs_item.storage_type == 'local') {
|
|
let file = await idb.get(fs_item.url);
|
|
return URL.createObjectURL(file);
|
|
}
|
|
}
|
|
|
|
export async function file_from_url(url, name, defaultType = 'image/jpeg'){
|
|
try {
|
|
const response = await fetch(url);
|
|
const data = await response.blob();
|
|
return new File([data], name, {
|
|
type: data.type || defaultType,
|
|
});
|
|
} catch (error) {
|
|
return new File([''], 'empty.txt', {
|
|
type: 'text/plain'
|
|
})
|
|
}
|
|
}
|
|
|
|
export async function array_buffer_from_url(url){
|
|
let file = await file_from_url(url);
|
|
return await file.arrayBuffer();
|
|
}
|
|
|
|
export async function buffer_from_url(url){
|
|
let array_buffer = await array_buffer_from_url(url);
|
|
console.log(array_buffer)
|
|
return Buffer.from(array_buffer);
|
|
} |