Skip to content
Snippets Groups Projects
Commit 33a0d94b authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Add ability to add files, display/edit extended descriptions

(yes, I know, unzip for DIZ can corrupt the TUI display when adding files)

Add ability to display and edit extended file descriptions (including
inserting and deleting lines.

Fixed bug with moving files between dirs.

F2 is now just a shortcut for renaming files, ENTER is the main edit/display
option key now.

This really requires an updated sbbs/jsexec to work fully correct (e.g.
display/edit extended descriptions that contain blank lines).
parent 91059084
No related branches found
No related tags found
1 merge request!455Update branch with changes from master
Pipeline #6472 passed
...@@ -14,6 +14,10 @@ if(!uifc.init("Synchronet File Manager")) { ...@@ -14,6 +14,10 @@ if(!uifc.init("Synchronet File Manager")) {
} }
js.on_exit("uifc.bail()"); js.on_exit("uifc.bail()");
// TODO: make these configurable
var uploader = system.operator;
var use_diz = false;
const main_ctx = new uifc.list.CTX; const main_ctx = new uifc.list.CTX;
while(!js.terminated) { while(!js.terminated) {
const items = [ const items = [
...@@ -112,6 +116,8 @@ function search(prompt, func) ...@@ -112,6 +116,8 @@ function search(prompt, func)
uifc.pop(); uifc.pop();
if(found.length) if(found.length)
list_files(found.length + " " + (pattern || "offline") + " files found", found); list_files(found.length + " " + (pattern || "offline") + " files found", found);
else
uifc.msg("No files found");
} }
function find_filename(dircode, pattern) function find_filename(dircode, pattern)
...@@ -226,12 +232,16 @@ function browse_dir(dircode) ...@@ -226,12 +232,16 @@ function browse_dir(dircode)
list_files(file_area.dir[dircode].name + format(" Files (%u)", list.length), list, dircode); list_files(file_area.dir[dircode].name + format(" Files (%u)", list.length), list, dircode);
} }
function list_files(title, list, dircode) function find_file(fname, list)
{ {
if(!list || !list.length) { for(var i = 0; i < list.length; ++i)
uifc.msg("No files in " + title); if(list[i].name == fname)
return; return i;
return -1;
} }
function list_files(title, list, dircode)
{
const wide_screen = uifc.screen_width >= 100; const wide_screen = uifc.screen_width >= 100;
const ctx = new uifc.list.CTX; const ctx = new uifc.list.CTX;
while(!js.terminated) { while(!js.terminated) {
...@@ -249,9 +259,13 @@ function list_files(title, list, dircode) ...@@ -249,9 +259,13 @@ function list_files(title, list, dircode)
,tagged ? 2:0 ,tagged ? 2:0
,list[i].tagged ? ascii(251):"" ,list[i].tagged ? ascii(251):""
,namelen, wide_screen ? list[i].name : FileBase().format_name(list[i].name) ,namelen, wide_screen ? list[i].name : FileBase().format_name(list[i].name)
,list[i].desc || list[i].extdesc || "")); ,list[i].desc || ""));
var result = uifc.list(WIN_SAV | WIN_RHT | WIN_ACT | WIN_DEL | WIN_DELACT | WIN_TAG var win_mode = WIN_SAV | WIN_RHT | WIN_ACT | WIN_DEL | WIN_DELACT | WIN_TAG;
,title, items, ctx); if(dircode)
win_mode |= WIN_INS | WIN_INSACT;
if(!tagged)
win_mode |= WIN_EDIT;
var result = uifc.list(win_mode, title, items, ctx);
if(result == -1) if(result == -1)
break; break;
if(result == MSK_TAGALL) { if(result == MSK_TAGALL) {
...@@ -270,6 +284,9 @@ function list_files(title, list, dircode) ...@@ -270,6 +284,9 @@ function list_files(title, list, dircode)
++ctx.cur; ++ctx.cur;
++ctx.bar; ++ctx.bar;
break; break;
case MSK_INS:
add_files(list, dircode);
break;
case MSK_DEL: case MSK_DEL:
var opts = [ "No", "Yes" ]; var opts = [ "No", "Yes" ];
if(tagged > 0) { if(tagged > 0) {
...@@ -296,19 +313,80 @@ function list_files(title, list, dircode) ...@@ -296,19 +313,80 @@ function list_files(title, list, dircode)
list.splice(result, /* deleteCount: */1); list.splice(result, /* deleteCount: */1);
} }
break; break;
case MSK_EDIT:
var orig_name = file.name;
if(edit_filename(file))
save(file, dircode, orig_name);
break;
} }
continue; continue;
} }
if(tagged > 0) { if(tagged > 0) {
multi(list, dircode, tagged); multi(list, dircode, tagged);
} else { // Single-file selected } else { // Single-file selected
var file = list[result]; if(edit(list[result], dircode)) // file (re)moved?
if(edit(file, dircode)) // file (re)moved?
list.splice(result, /* deleteCount: */1); list.splice(result, /* deleteCount: */1);
} }
} }
} }
function add_files(list, dircode)
{
var all_files = directory(file_area.dir[dircode].path + "*");
var new_files = [];
for(var i in all_files) {
if(!file_isdir(all_files[i])) {
var fname = file_getname(all_files[i]);
if(find_file(fname, list) < 0)
new_files.push(fname);
}
}
if(new_files.length < 1) {
uifc.msg("No new files to add in " + file_area.dir[dircode].path);
return;
}
const ctx = new uifc.list.CTX;
var tagged = [];
while(!js.terminated && new_files.length > 0) {
const new_title = new_files.length + " New Files in " + file_area.dir[dircode].path;
var opts = [];
for(var i in new_files)
opts[i] = format("%-*s%s", tagged.length ? 2:0, tagged.indexOf(new_files[i]) >= 0 ? ascii(251):"", new_files[i]);
var choice = uifc.list(WIN_SAV|WIN_ACT|WIN_TAG, new_title, opts, ctx);
if(choice < 0)
break;
if(choice == MSK_TAGALL) {
if(tagged.length)
tagged = [];
else
for(var i in new_files)
tagged[i] = new_files[i];
continue;
}
if((choice & MSK_ON) == MSK_TAG) {
choice &= MSK_OFF;
var i = tagged.indexOf(new_files[choice]);
if(i >= 0)
tagged.splice(i, /* deleteCount: */1);
else
tagged.push(new_files[choice]);
++ctx.cur;
++ctx.bar;
continue;
}
var files = tagged;
if(!files.length)
files = [new_files[choice]];
for(var i in files) {
var new_file = add_file(files[i], dircode);
if(!new_file)
break;
list.push(new_file);
new_files.splice(i, /* deleteCount: */1);
}
}
}
function fexists(file, dircode) function fexists(file, dircode)
{ {
if(!dircode) if(!dircode)
...@@ -342,7 +420,7 @@ function remove(file, del, dircode) ...@@ -342,7 +420,7 @@ function remove(file, del, dircode)
return result; return result;
} }
function dump(file, dircode) function view_details(file, dircode)
{ {
if(!dircode) if(!dircode)
dircode = file.dircode; dircode = file.dircode;
...@@ -351,10 +429,10 @@ function dump(file, dircode) ...@@ -351,10 +429,10 @@ function dump(file, dircode)
uifc.msg("Unable to open base: " + dircode); uifc.msg("Unable to open base: " + dircode);
return; return;
} }
// file = base.get(file, FileBase.DETAIL.AUXDATA); var dir = file_area.dir[dircode];
var buf = []; var buf = [];
if(file.extdesc) buf.push(format("Library " + file_area.lib[dir.lib_name].description));
buf = buf.concat(truncsp(file.extdesc).split('\n')); buf.push(format("Directory " + dir.description));
buf.push(format("Size " + file_size_float(base.get_size(file), 1, 1))); buf.push(format("Size " + file_size_float(base.get_size(file), 1, 1)));
buf.push(format("Time " + system.timestr(base.get_time(file)))); buf.push(format("Time " + system.timestr(base.get_time(file))));
uifc.showbuf(WIN_MID|WIN_HLP, base.get_path(file), buf.concat(base.dump(file.name)).join('\n')); uifc.showbuf(WIN_MID|WIN_HLP, base.get_path(file), buf.concat(base.dump(file.name)).join('\n'));
...@@ -396,12 +474,49 @@ function confirm(prompt) ...@@ -396,12 +474,49 @@ function confirm(prompt)
return choice; return choice;
} }
function edit_filename(file)
{
var name = uifc.input(WIN_MID|WIN_SAV, "Filename", file.name, 100, K_EDIT);
if(!name)
return false;
name = file_getname(name);
if(name == file.name)
return false;
file.name = name;
return true;
}
function edit_desc(file)
{
var desc = uifc.input(WIN_MID|WIN_SAV, "Description", file.desc, LEN_FDESC, K_EDIT);
if(desc !== undefined)
file.desc = desc;
}
function edit_uploader(file)
{
var from = uifc.input(WIN_MID|WIN_SAV, "Uploader", file.from, LEN_ALIAS, K_EDIT);
if(from !== undefined)
file.from = from;
return file.from;
}
function edit_cost(file)
{
var cost = uifc.input(WIN_MID|WIN_SAV, "Download Cost (in credits)", String(file.cost), 15, K_NUMBER|K_EDIT);
if(cost !== undefined)
file.cost = cost;
}
function edit(file, dircode) function edit(file, dircode)
{ {
file.extdesc = get_extdesc(file, dircode);
const ctx = new uifc.list.CTX; const ctx = new uifc.list.CTX;
var orig = JSON.parse(JSON.stringify(file)); var orig = JSON.parse(JSON.stringify(file));
while(!js.terminated) { while(!js.terminated) {
var opts = [ var opts = [
"Move File...",
"Remove File...",
"View Details...", "View Details...",
"View Archive...", "View Archive...",
"Filename: " + file.name, "Filename: " + file.name,
...@@ -409,90 +524,131 @@ function edit(file, dircode) ...@@ -409,90 +524,131 @@ function edit(file, dircode)
"Uploader: " + (file.from || ""), "Uploader: " + (file.from || ""),
"Added: " + system.timestr(file.added).slice(4), "Added: " + system.timestr(file.added).slice(4),
"Cost: " + file.cost, "Cost: " + file.cost,
"Move File...", "|---------- Extended Description -----------|"
"Remove File..."
]; ];
if(JSON.stringify(file) != JSON.stringify(orig)) if(file.extdesc) {
opts.push("Save changes..."); var extdesc = strip_ctrl_a(file.extdesc).split('\r\n');
opts = opts.concat(extdesc);
}
const title = (dircode || file.dircode) + "/" + orig.name; const title = (dircode || file.dircode) + "/" + orig.name;
var choice = uifc.list(WIN_SAV|WIN_ACT, title, opts, ctx); var choice = uifc.list(WIN_SAV|WIN_ACT|WIN_ESC|WIN_XTR|WIN_INS|WIN_DEL, title, opts, ctx);
if(choice == -1) {
if(JSON.stringify(file) != JSON.stringify(orig)) {
var choice = confirm("Save Changes?");
if(choice < 0) if(choice < 0)
continue;
if(choice && save(file, dircode, orig.name))
return false;
}
break; break;
}
var mask = choice & MSK_ON;
choice &= MSK_OFF;
if(mask && choice < 10)
continue;
switch(choice) { switch(choice) {
case 0: case 0:
dump(file, dircode); var dest = select_dir();
if(!dest)
break;
if(dest == dircode) {
uifc.msg("Destination directory must be different");
break;
}
if(move(file, dircode, dest))
return true;
break; break;
case 1: case 1:
view_archive(file, dircode); var del = confirm("Delete File Also");
if(del < 0)
break; break;
case 2: if(remove(file, del, dircode))
var name = uifc.input(WIN_MID|WIN_SAV, "Filename", file.name, 100, K_EDIT); return true;
if(!name)
break; break;
file.name = name; case 2:
view_details(file, dircode);
break; break;
case 3: case 3:
var desc = uifc.input(WIN_MID|WIN_SAV, "Description", file.desc, LEN_FDESC, K_EDIT); view_archive(file, dircode);
if(!desc)
break;
file.desc = desc;
break; break;
case 4: case 4:
var from = uifc.input(WIN_MID|WIN_SAV, "Uploader", file.from, LEN_ALIAS, K_EDIT); edit_filename(file);
if(!from)
break;
file.from = from;
break; break;
case 5: case 5:
var date = uifc.input(WIN_MID|WIN_SAV, "Added", new Date(file.added * 1000).toString().slice(4), 20, K_EDIT); edit_desc(file);
if(date)
file.added = Date.parse(date) / 1000;
break; break;
case 6: case 6:
var cost = uifc.input(WIN_MID|WIN_SAV, "Download Cost (in credits)", String(file.cost), 15, K_NUMBER|K_EDIT); edit_uploader(file);
if(cost !== undefined)
file.cost = cost;
break; break;
case 7: case 7:
var dest = select_dir(); var date = uifc.input(WIN_MID|WIN_SAV, "Added", new Date(file.added * 1000).toString().slice(4), 20, K_EDIT);
if(!dest) if(date)
break; file.added = Date.parse(date) / 1000;
if(dest == dircode) {
uifc.msg("Destination directory must be different");
break;
}
if(move(file, dircode, dest))
return true;
break; break;
case 8: case 8:
var del = confirm("Delete File Also"); edit_cost(file);
if(del < 0)
break;
if(remove(file, del, dircode))
return true;
break; break;
case 9: case 9:
if(save(file, dircode, orig.name))
orig = JSON.parse(JSON.stringify(file));
break; break;
default: // Extended description
var extdesc = file.extdesc ? file.extdesc.split('\r\n') : [];
var index = choice - 10;
if(mask & MSK_DEL) {
extdesc.splice(index, /* deleteCount: */1);
} }
else if(mask & MSK_INS) {
var str = uifc.input(WIN_SAV, 1, ctx.bar + 2, "", 79, K_MSG);
if(str !== undefined)
extdesc.splice(index, /* deleteCount: */0, str);
}
else if(extdesc.length <= index) {
var str = uifc.input(WIN_SAV, 1, ctx.bar + 2, "", 79, K_MSG);
if(str !== undefined)
extdesc.push(str);
}
else {
var str = uifc.input(WIN_SAV, 1, ctx.bar + 2, "", extdesc[index], 79, K_EDIT|K_MSG);
if(str !== undefined)
extdesc[index] = str;
} }
file.name = orig.name; file.extdesc = extdesc.join('\r\n');
break;
}
}
for(var i in file)
file[i] = orig[i];
return false; return false;
} }
function move(file, dircode, dest) function get_extdesc(file, dircode)
{ {
var result = false; if(file.extdesc)
var base = new FileBase(dest); return file.extdesc;
if(!dircode)
dircode = file.dircode;
var base = new FileBase(dircode);
if(!base.open()) { if(!base.open()) {
uifc.msg("Unable to open base: " + dest); uifc.msg("Unable to open base: " + dircode);
return false; return false;
} }
var dest_path = base.get_path(file); var f = base.get(file, FileBase.DETAIL.EXTENDED);
if(f) file = f;
base.close();
return file.extdesc;
}
function move(file, dircode, dest)
{
var dest_path = file_area.dir[dest].path + file.name;
if(file_exists(dest_path)) { if(file_exists(dest_path)) {
uifc.msg("File already exists: " + dest_path); uifc.msg("File already exists: " + dest_path);
base.close(); return false;
}
var result = false;
var base = new FileBase(dest);
if(!base.open()) {
uifc.msg("Unable to open base: " + dest);
return false; return false;
} }
result = base.add(file, /* use_diz: */false); result = base.add(file, /* use_diz: */false);
...@@ -510,6 +666,12 @@ function move(file, dircode, dest) ...@@ -510,6 +666,12 @@ function move(file, dircode, dest)
} }
try { try {
var src_path = base.get_path(file); var src_path = base.get_path(file);
if(!src_path) {
uifc.msg(format("Error %d (%s) getting source path for: %s"
,base.status, base.error, file.name));
base.close();
return false;
}
result = base.remove(file.name); result = base.remove(file.name);
if(!result) if(!result)
uifc.msg("remove failure " + base.status + ": " + file.name); uifc.msg("remove failure " + base.status + ": " + file.name);
...@@ -586,3 +748,57 @@ function save(file, dircode, filename) ...@@ -586,3 +748,57 @@ function save(file, dircode, filename)
base.close(); base.close();
return result; return result;
} }
function add_file(filename, dircode)
{
var base = new FileBase(dircode);
if(!base.open()) {
uifc.msg("Unable to open base: " + dircode);
return false;
}
var result = false;
var file = {
name: filename,
from: uploader,
cost: file_size(file_area.dir[dircode].path + filename)
};
const ctx = new uifc.list.CTX;
const title = "Adding " + filename + " to " + dircode;
while(!js.terminated) {
var opts = [
"Add File...",
"Description: " + (file.desc || ""),
"Uploader: " + (file.from || ""),
"Cost: " + file.cost,
"Extract/Import DIZ: " + ((file_area.dir[dircode].settings & DIR_DIZ) ? (use_diz ? "Yes" : "No") : "N/A"),
];
var choice = uifc.list(WIN_MID|WIN_SAV|WIN_ACT, title, opts, ctx);
if(choice < 0)
break;
switch(choice) {
case 1:
edit_desc(file);
continue;
case 2:
uploader = edit_uploader(file);
continue;
case 3:
edit_cost(file);
continue;
case 4:
if(file_area.dir[dircode].settings & DIR_DIZ)
use_diz = !use_diz;
continue;
}
uifc.pop(title);
result = base.add(file, use_diz);
uifc.pop();
if(result) {
file = base.get(filename);
} else
uifc.msg(format("Error %d (%s) adding file", base.status, base.error));
break;
}
base.close();
return result ? file : false;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment