Compare commits

...

49 Commits

Author SHA1 Message Date
Kit Kasune efdbdb04fe decompression 2 years ago
Kit Kasune d0aabd30bb decompress in ctx 2 years ago
Kit Kasune 271f17c829 zip detection 2 years ago
Kit Kasune 3634033ee6 compress selected; bugfix for name checking 2 years ago
Kit Kasune 5b6b9c1947 1.7.1 -> Zipping 3 years ago
Kit Kasune 1446b04319 fancy compression modal 3 years ago
Kit Kasune 5e04744317 literally zip folders kek 3 years ago
Kit Kasune d8f4ff3267 add a meta tag so my linter stops yelling at me 3 years ago
Kit Kasune c24d40317f unselectable button text 3 years ago
Kit Kasune 17bfc3b1d0 1.7.0 -> File opening! 3 years ago
Kit Kasune 247abefe2b 1.6.4 -> QOL stuff 3 years ago
Kit Kasune 341ce45745 folder now selects after creation 3 years ago
Kit Kasune c5eeedd2a5 finally fix double click bug 3 years ago
Kit Kasune aff2356efc invisible input to prevent repeated deletion 3 years ago
Kit Kasune 1d8e370914 folder selection util 3 years ago
Kit Kasune e480605934 remove log from enter keybind 3 years ago
Kit Kasune ebcd95a76e 1.6.3 -> Deletable folders and stable modals 3 years ago
Kit Kasune 0f5e7eeb73 keybinds for delete modal + bugs 3 years ago
Kit Kasune 0bfd17bec5 folder deletion 3 years ago
Kit Kasune 2a3bd672a1 Merge branch 'modals' 3 years ago
Kit Kasune f9dd980c31 error modal is actually closable 3 years ago
Kit Kasune 5d854ec6c4 Merge branch 'toast' 3 years ago
Kit Kasune a2bfe3a5c1 ctx properly recognizes folders 3 years ago
Kit Kasune 7c70870beb ignore favorites 3 years ago
Kit Kasune 7f221c62a5 1.6.2 -> Favorites pinning 3 years ago
Kit Kasune da9caf91e8 1.6.1 -> Toast improvements 3 years ago
Kit Kasune 05491d39eb Merge branch 'toast' 3 years ago
Kit Kasune 8b3adf55e0 close button css 3 years ago
Kit Kasune 7e9b729a33 make configs dir if it doesn't exist 3 years ago
Kit Kasune 372147a9f8 Merge branch 'sidebar' 3 years ago
Kit Kasune 9bf66e72c0 fix header margins 3 years ago
Kit Kasune 28262c8c60 load folder pins on init 3 years ago
Kit Kasune 0876d9fb4b pin folder to sidebar 3 years ago
Kit Kasune 8ac089fbe5 1.6.0 -> Folder ctx 3 years ago
Kit Kasune ceb5dc1925 Merge branch 'master' into sidebar 3 years ago
Kit Kasune b8705723bb folder renaming pt. 2 3 years ago
Kit Kasune 8f9c30b89b folder renaming 3 years ago
Kit Kasune 45ffea9c0e folder part of ctx 3 years ago
Kit Kasune 5c7d78d324 favorites group in sidebar 3 years ago
Kit Kasune 1a79778d08 Merge branch 'master' into sidebar 3 years ago
Kit Kasune 0a21a13b17 1.5.1 -> Fix changelogs in prod 3 years ago
Kit Kasune c9ae623c08 1.5.0 -> Bring sidebar into prod 3 years ago
Kit Kasune a43921c026 Merge branch 'sidebar' 3 years ago
Kit Kasune 9c3d43513e 1.4.4 -> Toast timers 3 years ago
Kit Kasune 8ee91f9acb sidebar quick access 3 years ago
Kit Kasune fde3a63e70 Merge branch 'toast' 3 years ago
Kit Kasune bcde3903c4 fixed sidebar; reflow z css and main container 3 years ago
Kit Kasune be92c82f4f base sidebar css 3 years ago
Kit Kasune 310fdd728c reorganize html for sidebar 3 years ago
  1. 3
      .gitignore
  2. 55
      index.html
  3. 1
      json/changelogs/1.4.4.json
  4. 1
      json/changelogs/1.5.0.json
  5. 1
      json/changelogs/1.5.1.json
  6. 1
      json/changelogs/1.6.0.json
  7. 1
      json/changelogs/1.6.1.json
  8. 1
      json/changelogs/1.6.2.json
  9. 1
      json/changelogs/1.6.3.json
  10. 1
      json/changelogs/1.6.4.json
  11. 1
      json/changelogs/1.7.0.json
  12. 1
      json/changelogs/1.7.1.json
  13. 10
      json/ctx.json
  14. 23
      json/qa.json
  15. 18
      package-lock.json
  16. 3
      package.json
  17. 5
      scripts/contextmenu/compress-selected.js
  18. 105
      scripts/contextmenu/compress.js
  19. 23
      scripts/contextmenu/createcontext.js
  20. 105
      scripts/contextmenu/decompress.js
  21. 79
      scripts/contextmenu/delete-folder.js
  22. 1
      scripts/contextmenu/hidecontext.js
  23. 5
      scripts/contextmenu/newfolder.js
  24. 36
      scripts/contextmenu/pin.js
  25. 94
      scripts/contextmenu/rename-folder.js
  26. 1
      scripts/fileview/load/load.js
  27. 20
      scripts/fileview/load/render.js
  28. 12
      scripts/fileview/selectfolder.js
  29. 35
      scripts/modal/common/error.js
  30. 10
      scripts/modal/post.js
  31. 8
      scripts/startup/changelog.js
  32. 1
      scripts/startup/initcontext.js
  33. 41
      scripts/startup/initsidebar.js
  34. 1
      scripts/startup/preload.js
  35. 3
      scripts/startup/setbuttons.js
  36. 6
      styles/context.css
  37. 2
      styles/files.css
  38. 20
      styles/modal.css
  39. 42
      styles/sidebar.css
  40. 52
      styles/styles.css

3
.gitignore vendored

@ -1,2 +1,3 @@
node_modules/
out/
out/
favorites.json

@ -3,6 +3,7 @@
<head>
<meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="./styles/styles.css" rel="stylesheet">
<link href='./styles/files.css' rel='stylesheet'>
@ -10,28 +11,56 @@
<link href='./styles/context.css' rel='stylesheet'>
<link href='./styles/modal.css' rel='stylesheet'>
<link href="./styles/toast.css" rel="stylesheet">
<link href="./styles/sidebar.css" rel="stylesheet">
<title>FileKade</title>
</head>
<body>
<div id="title-container">
<div id="title-sub-container">
<p id="title" class="nosel">FileKade</p>
<div id="title-container-wrapper">
<div id="title-sub-container">
<p id="title" class="nosel">FileKade</p>
</div>
<div id="title-controls-container">
<div class="close-button-wrapper">
<div id="close-window" class="close-button"></div>
</div>
</div>
</div>
</div>
<div id='container'>
<div id='controls' class='controls'>
<div id='header-buttons'></div>
<div id='header-nav'></div>
<div id="master">
<div id="sidebar">
<div id="favorites">
<div id="favorites-wrapper">
<div>
<div>
<h2 class="favorites-header nosel">Quick Access</h2>
</div>
<div id="favorites-container"></div>
</div>
<div>
<div>
<h2 class="favorites-header nosel">Favorites</h2>
</div>
<div id="custom-favorites-container"></div>
</div>
</div>
</div>
</div>
<div id='files' class='files'>
<div id='file-header' class='file-header'>
<p></p>
<p>Name</p>
<p>Type</p>
<p>Last Modified</p>
<p>Size</p>
<div id='container'>
<div id='controls' class='controls'>
<div id='header-buttons'></div>
<div id='header-nav'></div>
</div>
<div id='files' class='files'>
<div id='file-header' class='file-header'>
<p></p>
<p>Name</p>
<p>Type</p>
<p>Last Modified</p>
<p>Size</p>
</div>
</div>
</div>
</div>

@ -0,0 +1 @@
{"log":{"Toasts":["Toasts now have moving timers","They'll soon pause on hover. (Soon:tm:)"]},"version":{"name":"Alpha","semver":"1.4.4"}}

@ -0,0 +1 @@
{"log":{"Sidebar":["There's now a sidebar! :D","The sidebar properly flows with other elements. Have to add this as a changelog cause it took some love","There are some default quick access buttons for Windows","The quick access buttons do in fact work"]},"version":{"name":"Alpha","semver":"1.5.0"}}

@ -0,0 +1 @@
{"log":{"Bugs":["Changelogs work in production","My brain is quite small yes yes","Hope this doesn't break anything else *shrug*"]},"version":{"name":"Alpha","semver":"1.5.1"}}

@ -0,0 +1 @@
{"log":{"Context Menu":["The right click menu now recognizes when you're on a folder","The 'rename' feature in context menu works!"],"Sidebar":["Added the custom favorites group","Doesn't work yet though"]},"version":{"name":"Alpha","semver":"1.6.0"}}

@ -0,0 +1 @@
{"log":{"Toasts":["Toasts now pause when you hover over them","This feature is somewhat experimental","Changed the internals of toasts. More butter. Mmmmmmbutter"]},"version":{"name":"Alpha","semver":"1.6.1"}}

@ -0,0 +1 @@
{"log":{"Sidebar":["The option to pin a folder to the sidebar now works","These pins save between restarts!"]},"version":{"name":"Alpha","semver":"1.6.2"}}

@ -0,0 +1 @@
{"log":{"Folder Deletion":["You can now delete folders by right clicking on them","Includes an obligatory confirmation to make sure you're sure you want to delete the folder :)"],"Bugs":["Error modals are actually closable now kekw","Right click will only show folder options on folders now"]},"version":{"name":"Alpha","semver":" 1.6.3"}}

@ -0,0 +1 @@
{"log":{"Misc":["Small update here","Cleaned up a few bugs too small to really talk about here","Fixed a really nasty bug where the app would try to delete a folder a whole bunch of times","Clicking on the same file again won't make it visibly un-click","A folder will select itself after it's created"]},"version":{"name":"Alpha","semver":"1.6.4"}}

@ -0,0 +1 @@
{"log":{"File opening":["Files now open!!","I know right, a file explorer that opens files. Revolutionary.","This feature is dependent on you being on a version of Windows where PowerShell exists. Whether or not it works every single time is a bit untested, so it could cause some twitchy stuff to happen. This has not been written for Linux or Mac yet."]},"version":{"name":"Alpha","semver":"1.7.0"}}

@ -0,0 +1 @@
{"log":{"Zipping":["You can now zip folders!","So far, this only applies to the directory you're currently viewing. It will not *yet* zip the directory you have selected"]},"version":{"name":"Alpha","semver":"1.7.1"}}

@ -1,6 +1,9 @@
[
[
{"name": "New Folder", "id": "ctx-new-folder", "onclick": "newfolder"}
{"name": "New Folder", "id": "ctx-new-folder", "onclick": "newfolder"},
{"name": "Compress", "id": "ctx-compress", "onclick": "compress"},
{"name": "Compress Selected", "id": "ctx-compress-selected", "onclick": "compress-selected"},
{"name": "Decompress", "id": "ctx-decompress", "onclick": "decompress"}
],
[
{"name": "Sort by: Name", "id": "ctx-sort-by", "onclick": "changesort"},
@ -10,5 +13,10 @@
{"name": "Reload", "id": "ctx-reload", "onclick": "reload"},
{"name": "Refresh", "id": "ctx-refresh", "onclick": "refresh"},
{"name": "Options", "id": "ctx-options", "onclick": "options"}
],
[
{"name": "Rename", "id": "ctx-rename-folder", "onclick": "rename-folder"},
{"name": "Pin to Favorites", "id": "ctx-pin", "onclick": "pin"},
{"name": "Delete", "id": "ctx-delete-folder", "onclick": "delete-folder"}
]
]

@ -0,0 +1,23 @@
{
"default": [
{
"name": "Desktop",
"win32": "{r}\\Desktop"
}, {
"name": "Documents",
"win32": "{r}\\Documents"
}, {
"name": "Pictures",
"win32": "{r}\\Pictures"
}, {
"name": "Videos",
"win32": "{r}\\Videos"
}, {
"name": "Music",
"win32": "{r}\\Music"
}, {
"name": "Downloads",
"win32": "{r}\\Downloads"
}
]
}

18
package-lock.json generated

@ -1,14 +1,15 @@
{
"name": "filekade",
"version": "1.4.3",
"version": "1.7.1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "filekade",
"version": "1.4.3",
"version": "1.7.1",
"license": "ISC",
"dependencies": {
"adm-zip": "^0.5.9",
"chalk": "^4.1.2",
"electron-squirrel-startup": "^1.0.0",
"generator-code": "^1.6.5"
@ -1993,6 +1994,14 @@
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true
},
"node_modules/adm-zip": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
"integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg==",
"engines": {
"node": ">=6.0"
}
},
"node_modules/agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
@ -15218,6 +15227,11 @@
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true
},
"adm-zip": {
"version": "0.5.9",
"resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.5.9.tgz",
"integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg=="
},
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",

@ -1,6 +1,6 @@
{
"name": "filekade",
"version": "1.4.3",
"version": "1.7.1",
"description": "A file explorer (primarily a learning experience for me)",
"main": "main.js",
"scripts": {
@ -14,6 +14,7 @@
"author": "WubzyGD",
"license": "ISC",
"dependencies": {
"adm-zip": "^0.5.9",
"chalk": "^4.1.2",
"electron-squirrel-startup": "^1.0.0",
"generator-code": "^1.6.5"

@ -0,0 +1,5 @@
const path = require('path');
module.exports = () => {
return require('./compress')(undefined, path.join(window.kade.cpath, window.kade.currentFolder));
};

@ -0,0 +1,105 @@
const fs = require('fs');
const path = require('path');
const az = require('adm-zip');
const Mousetrap = require('../dep/mousetrap');
const lightRefresh = require('../fileview/lightrefresh');
const preModal = require('../modal/pre');
const postModal = require('../modal/post');
const showError = require('../modal/common/error');
const clearModals = require('../modal/clearmodals');
const newToast = require('../toast/createtoast');
const refresh = require('../fileview/refresh');
module.exports = (event, pathToCompress) => {
let zip = new az();
if (!pathToCompress) {pathToCompress = window.kade.cpath;}
if (window.kade.modal) {return;}
preModal('compress-folder-modal-container');
let modalOut = document.createElement('div');
modalOut.className = 'modal';
modalOut.id = 'compress-folder-modal-container';
document.body.appendChild(modalOut);
let modal = document.createElement('div');
modal.className = 'modal-wrapper';
modalOut.appendChild(modal);
let title = document.createElement('h2');
title.innerHTML = 'Compress Folder';
modal.appendChild(title);
let text = document.createElement('p');
text.innerHTML = "Please name the zip you'd like to compress to.";
modal.appendChild(text);
let cont = document.createElement('div');
cont.className = 'button-container';
modal.appendChild(cont);
let input = document.createElement('input');
input.placeholder = pathToCompress.split(/\\+|\/+/gm).reverse()[0];
input.value = input.placeholder;
input.id = 'compress-folder-input';
let lastIn = '';
input.oninput = () => {
if (!input.value.match(/^[a-zA-Z0-9-_() ]*$/gm)) {input.value = lastIn;}
else {lastIn = input.value;}
};
cont.appendChild(input);
let conf = document.createElement('button');
conf.innerHTML = 'Create';
conf.onclick = () => {
try {
input.value = input.value.trim();
if (input.value.endsWith('.zip')) {input.value = input.value.slice(0, input.value.length - 4);}
if (!input.value.length) {return;}
if (fs.existsSync(path.join(window.kade.cpath, `${input.value}.zip`))) {
if (!input.value.match(/^.+\(\d\)$/gm)) {input.value += ' (1)';}
else {
let tempstr = input.value.split('');
tempstr[input.value.length - 2] = `${Number(input.value.charAt(input.value.length - 2)) + 1}`;
input.value = tempstr.join('');
}
return;
}
input.style.display = 'none';
conf.style.display = 'none';
cont.style.display = 'none';
text.innerHTML = "Please wait a moment...";
closeWrap.style.display = 'none';
zip.addLocalFolderPromise(pathToCompress).then(() => {
title.innerHTML += " - In Progress..."
text.innerHTML = "Your folder is being compressed. Please wait a moment.<br><br>This may take some time...";
let bar = document.createElement('div');
bar.className = "loading-bar";
modal.appendChild(bar);
zip.writeZipPromise(`${window.kade.cpath}/${input.value}${input.value.endsWith('.zip') ? '' : '.zip'}`, {overwrite: true}).then(() => {
newToast("Folder compressed", [`The current folder was compressed into "${input.value}" successfully`, `<em>${window.kade.cpath}/${input.value}</em>`], undefined, false, 5);
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
});
});
} catch {
newToast("Folder not Compressed", "An error caused that folder to not be compressed.", "#b24355", false, 5, () => {showError("Folder Creation", "There was an unknown error while trying to compress that folder. It may be a permissions issue, or the host folder doesn't exist anymore.");});
clearModals();
postModal(modalOut.id);
}
};
cont.appendChild(conf);
input.focus();
let msm = new Mousetrap(modal);
msm.bind('esc', () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
});
msm.bind('enter', () => {conf.click();});
let close = document.createElement('a');
close.className = 'close-button';
close.onclick = () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
};
let closeWrap = document.createElement('div');
closeWrap.className = 'close-button-wrapper';
modal.appendChild(closeWrap);
closeWrap.appendChild(close);
};

@ -3,6 +3,29 @@ module.exports = (e, target, window) => {
window.kade.context = true;
let ctx = document.getElementById('ctx');
ctx.style.display = 'block';
const ctxf = document.getElementById('ctx-folder');
const compress = document.getElementById('ctx-compress');
const compsel = document.getElementById('ctx-compress-selected');
if (target.classList.contains('folder') || (target.parentElement && target.parentElement.classList.contains('folder'))) {
ctxf.style.display = 'block';
ctxf.previousElementSibling.style.display = 'block';
if (target.classList.contains('folder')) {window.kade.currentFolder = target.children[1].innerHTML.trim();}
else {window.kade.currentFolder = target.parentElement.children[1].innerHTML.trim();}
compress.style.display = 'none';
compsel.style.display = 'block';
} else {
ctxf.style.display = 'none';
ctxf.previousElementSibling.style.display = 'none';
compress.style.display = 'block';
compsel.style.display = 'none';
}
if (target.classList.contains('zip') || (target.parentElement && target.parentElement.classList.contains('zip'))) {
if (target.classList.contains('zip')) {window.kade.currentFolder = target.children[1].innerHTML.trim();}
else {window.kade.currentFolder = target.parentElement.children[1].innerHTML.trim();}
document.getElementById('ctx-decompress').style.display = 'block';
} else {
document.getElementById('ctx-decompress').style.display = 'none';
}
ctx.style.left = `${Math.min(e.pageX, (window.innerWidth - (ctx.clientWidth + 2)))}px`;
ctx.style.top = `${Math.min(e.pageY, ((window.innerHeight + window.scrollY) - (ctx.clientHeight + 2)))}px`;
};

@ -0,0 +1,105 @@
const fs = require('fs');
const path = require('path');
const az = require('adm-zip');
const Mousetrap = require('../dep/mousetrap');
const lightRefresh = require('../fileview/lightrefresh');
const preModal = require('../modal/pre');
const postModal = require('../modal/post');
const showError = require('../modal/common/error');
const clearModals = require('../modal/clearmodals');
const newToast = require('../toast/createtoast');
const refresh = require('../fileview/refresh');
module.exports = (event, pathToCompress) => {
if (!fs.existsSync(path.join(window.kade.cpath, window.kade.currentFolder))) {
return newToast("Decompression failed", "For some reason, that zip archive could not be found.");
}
let zip = new az(path.join(window.kade.cpath, window.kade.currentFolder));
if (!pathToCompress) {pathToCompress = window.kade.currentFolder;}
if (window.kade.modal) {return;}
preModal('decompress-folder-modal-container');
let modalOut = document.createElement('div');
modalOut.className = 'modal';
modalOut.id = 'decompress-folder-modal-container';
document.body.appendChild(modalOut);
let modal = document.createElement('div');
modal.className = 'modal-wrapper';
modalOut.appendChild(modal);
let title = document.createElement('h2');
title.innerHTML = 'Decompress Archive';
modal.appendChild(title);
let text = document.createElement('p');
text.innerHTML = "Please name the zip you'd like to decompress to.";
modal.appendChild(text);
let cont = document.createElement('div');
cont.className = 'button-container';
modal.appendChild(cont);
let input = document.createElement('input');
input.placeholder = pathToCompress.split(/\\+|\/+/gm).reverse()[0];
input.placeholder = input.placeholder.slice(0, input.placeholder.length - 4);
input.value = input.placeholder;
input.id = 'decompress-folder-input';
let lastIn = '';
input.oninput = () => {
if (!input.value.match(/^[a-zA-Z0-9-_() ]*$/gm)) {input.value = lastIn;}
else {lastIn = input.value;}
};
cont.appendChild(input);
let conf = document.createElement('button');
conf.innerHTML = 'Create';
conf.onclick = () => {
try {
input.value = input.value.trim();
if (!input.value.length) {return;}
if (fs.existsSync(path.join(window.kade.cpath, input.value))) {
if (!input.value.match(/^.+\(\d\)$/gm)) {input.value += ' (1)';}
else {
let tempstr = input.value.split('');
tempstr[input.value.length - 2] = `${Number(input.value.charAt(input.value.length - 2)) + 1}`;
input.value = tempstr.join('');
}
return;
}
input.style.display = 'none';
conf.style.display = 'none';
cont.style.display = 'none';
closeWrap.style.display = 'none';
title.innerHTML += " - In Progress..."
text.innerHTML = "Your arhive is being decompressed. Please wait a moment.<br><br>This may take some time...";
let bar = document.createElement('div');
bar.className = "loading-bar";
modal.appendChild(bar);
zip.extractAllToAsync(path.join(window.kade.cpath, input.value), undefined, undefined, () => {
newToast("Archive decompressed", [`The current folder was decompressed into "${input.value}" successfully`, `<em>${window.kade.cpath}/${input.value}</em>`], undefined, false, 5, () => refresh(`${window.kade.cpath}/${input.value}`));
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
});
} catch {
newToast("Archive not Decompressed", "An error caused that folder to not be decompressed.", "#b24355", false, 5, () => {showError("Folder Creation", "There was an unknown error while trying to decompress that folder. It may be a permissions issue, or the host folder doesn't exist anymore.");});
clearModals();
postModal(modalOut.id);
}
};
cont.appendChild(conf);
input.focus();
let msm = new Mousetrap(modal);
msm.bind('esc', () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
});
msm.bind('enter', () => {conf.click();});
let close = document.createElement('a');
close.className = 'close-button';
close.onclick = () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
};
let closeWrap = document.createElement('div');
closeWrap.className = 'close-button-wrapper';
modal.appendChild(closeWrap);
closeWrap.appendChild(close);
};

@ -0,0 +1,79 @@
const fs = require('fs');
const path = require('path');
const Mousetrap = require('../dep/mousetrap');
const lightRefresh = require('../fileview/lightrefresh');
const preModal = require('../modal/pre');
const postModal = require('../modal/post');
const showError = require('../modal/common/error');
const clearModals = require('../modal/clearmodals');
const newToast = require('../toast/createtoast');
module.exports = () => {
if (window.kade.modal) {return;}
preModal('delete-folder-modal-container');
let modalOut = document.createElement('div');
modalOut.className = 'modal';
modalOut.id = 'delete-folder-modal-container';
document.body.appendChild(modalOut);
let modal = document.createElement('div');
modal.className = 'modal-wrapper';
modalOut.appendChild(modal);
let title = document.createElement('h2');
title.innerHTML = 'Delete Folder';
modal.appendChild(title);
let text = document.createElement('p');
text.innerHTML = "Are you sure you'd like to delete this folder? Remember, this <b>cannot be undone</b>.";
modal.appendChild(text);
let cont = document.createElement('div');
cont.className = 'button-container';
modal.appendChild(cont);
let conf = document.createElement('button');
conf.innerHTML = 'Delete it!';
let cxl = document.createElement('button');
cxl.innerHTML = "Nevermind";
cxl.onclick = () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
};
conf.onclick = () => {
try {
fs.rmdirSync(path.join(window.kade.cpath, window.kade.currentFolder));
postModal(modalOut.id);
modalOut.remove();
lightRefresh(window.kade.cpath);
newToast("Folder Deleted", "Your folder has been deleted successfully.");
} catch {
newToast("Folder not Deleted", "An error caused that folder to not be deleted.", "#b24355", false, 5, () => {showError("Folder Deletion", "There was an unknown error while trying to delete that folder. It may be a permissions issue, or the host folder doesn't exist anymore.");});
clearModals();
try {modalOut.remove();} catch {}
postModal(modalOut.id);
}
};
cont.appendChild(conf);
cont.appendChild(cxl);
let iin = document.createElement('input');
iin.className = 'invis';
iin.classList.add('nosel');
cont.appendChild(iin);
iin.focus();
let msm = new Mousetrap(modal);
msm.bind('esc', () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
});
msm.bind('enter', () => {conf.click();});
let close = document.createElement('a');
close.className = 'close-button';
close.onclick = () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
};
let closeWrap = document.createElement('div');
closeWrap.className = 'close-button-wrapper';
modal.appendChild(closeWrap);
closeWrap.appendChild(close);
};

@ -1,4 +1,5 @@
module.exports = (window) => {
document.getElementById('ctx').style.display = 'none';
if (!window) {return;}
window.kade.context = false;
};

@ -9,6 +9,7 @@ const showError = require('../modal/common/error');
const clearModals = require('../modal/clearmodals');
const newToast = require('../toast/createtoast');
const refresh = require('../fileview/refresh');
const selectFolder = require('../fileview/selectfolder');
module.exports = () => {
if (window.kade.modal) {return;}
@ -64,6 +65,10 @@ module.exports = () => {
newToast("Copied!", "<em>The folder's path has been copied to your clipboard.</em>", "#19df46");
}
);
setTimeout(() => {
selectFolder(input.value);
setTimeout(() => window.kade.cl.click(), 100);
}, 100);
} catch {
newToast("Folder not Created", "An error caused that folder to not be created.", "#b24355", false, 5, () => {showError("Folder Creation", "There was an unknown error while trying to create that folder. It may be a permissions issue, or the host folder doesn't exist anymore.");});
clearModals();

@ -0,0 +1,36 @@
const fs = require('fs');
const path = require('path');
const createToast = require('../toast/createtoast');
const refresh = require('../fileview/refresh');
const newToast = require("../toast/createtoast");
module.exports = () => {
if (!fs.existsSync(path.join(__dirname, '../../', '/json/config'))) {fs.mkdirSync(path.join(__dirname, '../../', '/json/config'));}
let pins;
if (fs.existsSync(path.join(__dirname, '../../', '/json/config/favorites.json'))) {
pins = require('../../json/config/favorites.json');
} else {pins = {};}
let fta = window.kade.currentFolder.trim();
if (Object.keys(pins).includes(`${window.kade.cpath.replace(/\\+/gm, '/')}/${fta}`)) {
return createToast("Already pinned", "That folder is already pinned!");
}
let tr = `${window.kade.cpath.replace(/\\+/gm, '/')}/${fta}`;
pins[tr] = fta;
let cfc = document.getElementById('custom-favorites-container');
let fav = document.createElement('div');
['favorites-button', 'folder-pin', 'nosel'].forEach(x => fav.classList.add(x));
fav.innerHTML = fta;
fav.onclick = () => {refresh(tr);};
cfc.appendChild(fav);
createToast(
"Folder Pinned", [`Folder "${fta}" was successfully pinned! You can now access it permanently in your sidebar!"`, `<em>${window.kade.cpath.replace(/\\+/gm, '/')}/${fta}</em>`], undefined, false, 5,
() => {
refresh(tr);
require('electron').clipboard.writeText(`${window.kade.cpath.replace(/\\+/gm, '/')}`);
newToast("Copied!", "<em>The folder's path has been copied to your clipboard.</em>", "#19df46");
}
);
try {fs.writeFileSync(path.join(__dirname, '../../', '/json/config/favorites.json'), JSON.stringify(pins));}
catch {createToast("Error", "Your pin was not saved for some reason. Please restart or reload (ctrl+shift+r) the app and try again.", "#ff557a");}
};

@ -0,0 +1,94 @@
const fs = require('fs');
const path = require('path');
const Mousetrap = require('../dep/mousetrap');
const lightRefresh = require('../fileview/lightrefresh');
const preModal = require('../modal/pre');
const postModal = require('../modal/post');
const showError = require('../modal/common/error');
const clearModals = require('../modal/clearmodals');
const newToast = require('../toast/createtoast');
const refresh = require('../fileview/refresh');
module.exports = () => {
if (window.kade.modal) {return;}
preModal('rename-folder-modal-container');
let modalOut = document.createElement('div');
modalOut.className = 'modal';
modalOut.id = 'rename-folder-modal-container';
document.body.appendChild(modalOut);
let modal = document.createElement('div');
modal.className = 'modal-wrapper';
modalOut.appendChild(modal);
let title = document.createElement('h2');
title.innerHTML = 'Rename Folder';
modal.appendChild(title);
let text = document.createElement('p');
text.innerHTML = "What would you like to rename this folder to?";
modal.appendChild(text);
let cont = document.createElement('div');
cont.className = 'button-container';
modal.appendChild(cont);
let input = document.createElement('input');
input.placeholder = window.kade.currentFolder;
input.id = 'rename-folder-input';
input.value = window.kade.currentFolder;
let lastIn = '';
input.oninput = () => {
if (!input.value.match(/^[a-zA-Z0-9-_() ]*$/gm)) {input.value = lastIn;}
else {lastIn = input.value;}
};
cont.appendChild(input);
let conf = document.createElement('button');
conf.innerHTML = 'Rename';
conf.onclick = () => {
try {
input.value = input.value.trim();
if (!input.value.length) {return;}
if (fs.existsSync(path.join(window.kade.cpath, input.value))) {
if (!input.value.match(/^.+\(\d\)$/gm)) {input.value += ' (1)';}
else {
let tempstr = input.value.split('');
tempstr[input.value.length - 2] = `${Number(input.value.charAt(input.value.length - 2)) + 1}`;
input.value = tempstr.join('');
}
return;
}
fs.renameSync(path.join(window.kade.cpath, window.kade.currentFolder), path.join(window.kade.cpath, input.value));
lightRefresh();
modalOut.remove();
newToast(
"Folder renamed", [`Folder "${window.kade.currentFolder}" was successfully renamed to "${input.value}"`, `<em>${window.kade.cpath}/${input.value}</em>`], undefined, false, 5,
() => {
refresh(`${window.kade.cpath}/${input.value}`);
require('electron').clipboard.writeText(`${window.kade.cpath}`);
newToast("Copied!", "<em>The folder's path has been copied to your clipboard.</em>", "#19df46");
}
);
} catch {
newToast("Folder not Renamed", "An error caused that folder to not be renamed.", "#b24355", false, 5, () => {showError("Folder Renaming", "There was an unknown error while trying to rename that folder. It may be a permissions issue, or the host folder doesn't exist anymore.");});
clearModals();
}
postModal(modalOut.id);
};
cont.appendChild(conf);
input.focus();
let msm = new Mousetrap(modal);
msm.bind('esc', () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
});
msm.bind('enter', () => {conf.click();});
let close = document.createElement('a');
close.className = 'close-button';
close.onclick = () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
};
let closeWrap = document.createElement('div');
closeWrap.className = 'close-button-wrapper';
modal.appendChild(closeWrap);
closeWrap.appendChild(close);
}

@ -16,6 +16,7 @@ module.exports = (check=false) => {
for (const file of ldir) {
let ofile = {};
ofile.icon = fileIcon(`${dir}/${file}`, file);
ofile.trueName = file;
ofile.name = trimext.includes(path.extname(file)) ? file.slice(0, file.length - path.extname(file).length) : file;
try {ofile.type = fs.lstatSync(`${dir}/${file}`).isDirectory() ? "File Folder" : (extensions[(file.startsWith('.') ? file : path.extname(file)).slice(1)] || "File");}
catch {ofile.type = `${path.extname(file)} File`.trim();}

@ -1,4 +1,8 @@
const cp = require('child_process');
const path = require('path');
const loadHierarchy = require("../hierarchy");
const newToast = require('../../toast/createtoast');
const isOverflowing = require('../../dep/overflowing');
@ -13,17 +17,27 @@ module.exports = (dir, options) => {
let cfc = document.createElement("div");
cfc.className = 'file';
if (options.animate) {cfc.classList.add('rise');}
if (file.dir) {cfc.classList.add('folder');}
if (!file.dir && path.extname(path.join(window.kade.cpath, file.trueName)) === '.zip') {cfc.classList.add('zip');}
cfc.onclick = function () {
window.kade.elc = true;
if (cfc.classList.contains('file-active')) {if (file.dir) {refresh(`${window.kade.cpath}/${file.name}`);}}
if (cfc.classList.contains('file-active')) {
if (file.dir) {refresh(`${window.kade.cpath}/${file.name}`);}
else {
try {cp.exec(`${window.kade.cpath}/${file.trueName}`, {shell: 'powershell.exe'}, (error) => {
if (error) {newToast("Error", "Unable to open file.", "#a4052b");}
});}
catch {newToast("Error", "Unable to open file.", "#a4052b");}
}
}
cfc.classList.add('file-active');
if (window.kade.cl) {window.kade.cl.classList.remove('file-active');}
if (window.kade.cl && !cfc.isSameNode(window.kade.cl)) {window.kade.cl.classList.remove('file-active');}
window.kade.cl = cfc;
};
cfc.oncontextmenu = function () {
window.kade.elc = true;
if (!cfc.classList.contains('file-active')) {cfc.classList.add('file-active');}
if (window.kade.cl) {window.kade.cl.classList.remove('file-active');}
if (window.kade.cl && !cfc.isSameNode(window.kade.cl)) {window.kade.cl.classList.remove('file-active');}
window.kade.cl = cfc;
window.kade.ctxel = cfc;
};

@ -0,0 +1,12 @@
module.exports = (name) => {
let folders = document.getElementById('files').getElementsByClassName('folder');
let folder = 1;
for (let i = 0; i < folders.length; i++) {
if (folders.item(i).children.item(1).innerHTML === name) {
folder = folders.item(i);
folder.click();
break;
}
}
return folder;
};

@ -1,13 +1,21 @@
const preModal = require("../pre");
const mousetrap = require('../../dep/mousetrap');
const lightRefresh = require('../../fileview/lightrefresh');
const preModal = require('../pre');
const postModal = require('../post');
module.exports = (name, text, after = () => {}) => {
preModal('error-modal');
if (window.kade.modal) {return;}
preModal('error-modal-container');
let modalOut = document.createElement('div');
modalOut.className = 'modal';
modalOut.id = 'error-modal-container'
document.body.appendChild(modalOut);
let modal = document.createElement('div');
modal.className = 'modal';
modal.className = 'modal-wrapper';
modalOut.appendChild(modal);
modal.classList.add('error-modal');
modal.id = 'error-modal';
document.body.appendChild(modal);
let title = document.createElement('h2');
title.innerHTML = `Error - ${name}`;
modal.appendChild(title);
@ -16,4 +24,21 @@ module.exports = (name, text, after = () => {}) => {
modal.appendChild(err);
after('error-modal');
postModal();
};
let msm = new mousetrap(modal);
msm.bind('esc', () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
});
let close = document.createElement('a');
close.className = 'close-button';
close.onclick = () => {
lightRefresh();
modalOut.remove();
postModal(modalOut.id);
};
let closeWrap = document.createElement('div');
closeWrap.className = 'close-button-wrapper';
modal.appendChild(closeWrap);
closeWrap.appendChild(close);
}

@ -1,8 +1,10 @@
const transit = require("./transit");
module.exports = (id) => {
document.getElementById('modal-block').remove();
window.kade.modal = false;
document.body.style.overflowY = 'overlay';
transit(id, false);
try {
try {document.getElementById('modal-block').remove();} catch {}
window.kade.modal = false;
document.body.style.overflowY = 'overlay';
transit(id, false);
} catch {}
};

@ -1,10 +1,11 @@
const fs = require('fs');
const Mousetrap = require('../dep/mousetrap');
const path = require('path');
const preModal = require('../modal/pre');
const postModal = require('../modal/post');
const changelogs = fs.readdirSync('./json/changelogs').filter(file => file.endsWith('.json'));
const changelogs = fs.readdirSync(path.join(__dirname, '../../', '/json/changelogs')).filter(file => file.endsWith('.json'));
module.exports = () => {
if (window.kade.modal) {return;}
@ -58,10 +59,7 @@ module.exports = () => {
});
});
clww.style = `height: ${modalOut.clientHeight - 6};`; // TODO cry enough tears that they magically make this line work
console.log(clww.style.height);
console.log(modalOut.clientHeight - 6);
console.log(typeof clww.style);
clww.style = `height: ${modalOut.clientHeight - 6};`;
let msm = new Mousetrap(modal);
msm.bind('esc', () => {

@ -23,5 +23,6 @@ module.exports = () => {
}
if (i + 1 < ctxl.length) {ctx.appendChild(document.createElement('hr'));}
}
document.getElementById('ctx-pin').parentElement.id = 'ctx-folder';
} catch (e) {console.error(e);}
};

@ -0,0 +1,41 @@
const refresh = require('../fileview/refresh');
const qa = require('../../json/qa.json');
const os = require("os");
const fs = require('fs');
const path = require('path');
module.exports = () => {
let root
switch (window.kade.platform) {
case 'win32':
root = `${os.homedir()}`;
break;
case 'linux':
root = `~/home`;
break;
}
let quickAccess = document.getElementById('favorites-container');
qa.default.forEach(i => {
let quick = document.createElement('div');
quick.innerHTML = i.name;
quick.onclick = () => {refresh(i[window.kade.platform].replace('{r}', root));};
quick.className = 'favorites-button';
quick.classList.add('nosel');
quickAccess.appendChild(quick);
});
if (fs.existsSync(path.join(__dirname, '../../', '/json/config/favorites.json'))) {
const pins = require('../../json/config/favorites.json');
let cfc = document.getElementById('custom-favorites-container');
Object.keys(pins).forEach(pin => {
let fav = document.createElement('div');
['favorites-button', 'folder-pin', 'nosel'].forEach(x => fav.classList.add(x));
fav.innerHTML = pins[pin];
fav.onclick = () => {refresh(pin);};
cfc.appendChild(fav);
});
}
};

@ -44,6 +44,7 @@ window.addEventListener('DOMContentLoaded', () => {
}
require('./initcontext')();
require('./initsidebar')();
require('../fileview/refresh')(startDir);
setButtons();

@ -11,6 +11,7 @@ module.exports = () => {
backb.innerHTML = 'Go Back';
backb.setAttribute('id', 'back-button');
backb.className = 'header-button';
backb.classList.add('nosel');
backb.onclick = () => {
if (window.kade.cpath !== 'C:\\' && window.kade.cpath !== '\\') {refresh(path.join(window.kade.cpath, '..'));}
};
@ -19,6 +20,7 @@ module.exports = () => {
let sb = document.createElement('p');
sb.innerHTML = 'Sort by: Name';
sb.className = 'header-button';
sb.classList.add("nosel");
sb.onclick = () => {changesort();};
sb.setAttribute('id', 'sort-button');
hb.appendChild(sb);
@ -26,6 +28,7 @@ module.exports = () => {
let ob = document.createElement('p');
ob.innerHTML = 'Ascending';
ob.className = 'header-button';
ob.classList.add("nosel");
ob.onclick = () => {changeascend();};
ob.setAttribute('id', 'order-button');
hb.appendChild(ob);

@ -7,6 +7,7 @@
position: absolute;
background-color: #101010df;
padding: 7px 5px;
z-index: 2;
}
#ctx hr {
@ -32,4 +33,9 @@
align-items: stretch;
align-content: stretch;
row-gap: 2px;
}
#ctx-folder {
padding: 0 0;
margin: 0 0;
}

@ -10,7 +10,7 @@
}
.files {
margin: 0 15px 12px 15px;
margin: 0 15px 12px 7px;
display: flex;
flex-direction: column;
justify-content: space-between;

@ -9,7 +9,7 @@
border: 1px solid #af2188a4;
background-color: #171717da;
padding: 6px 8px;
z-index: 3;
z-index: 4;
max-width: 50%;
}
@ -65,11 +65,9 @@
top: 0;
left: 0;
background-color: #1717176d;
z-index: 2;
z-index: 3;
}
.error-modal {max-width: 45%;}
.modal-wrapper {
margin: 0 0;
padding: 0 0;
@ -95,6 +93,7 @@
display: block;
z-index: 200;
position: relative;
cursor: pointer;
}
.close-button:before, .close-button:after {
content: '';
@ -135,4 +134,15 @@
overflow: hidden;
}
#changelog-modal {max-height: 70vh;}
#changelog-modal {max-height: 70vh;}
.loading-bar {
width: 90%;
margin: 12px auto 10px auto;
border-radius: 3px;
padding: 0 0;
height: 5px;
animation: 12s linear infinite, moving-stripes 10s linear infinite;
background-image: repeating-linear-gradient(-45deg, #a172a6 10px, #5d60ca98, #a172a6 30px);
background-size: 200%;
}

@ -0,0 +1,42 @@
#sidebar {
width: 180px;
border-right: 1px solid #5d60caaf;
margin: 26px 0 0 0;
padding: 0 14px 12px 14px;
position: fixed;
z-index: 1;
overflow-x: hidden;
top: 0;
left: 0;
background-color: #0000006d;
height: 100%;
}
#container {margin-left: 200px;}
#favorites-container, #favorites-wrapper, #custom-favorites-container {
display: flex;
flex-direction: column;
align-items: stretch;
align-content: flex-start;
justify-content: flex-start;
row-gap: 6px;
}
.favorites-button {
padding: 4px 6px;
color: #afafaf;
border-radius: 3px 3px;
cursor: pointer;
transition: padding-left .05s linear;
}
.favorites-button:hover {
background-color: #a172a65f;
padding-left: 10px;
color: white;
}
.favorites-header {
margin-bottom: 7px;
}

@ -11,7 +11,6 @@ body {
color: #d3d3d3;
font-family: 'Montserrat', sans-serif;
overflow-y: overlay;
width: calc(100vw) - 10px;
}
.rise {
@ -29,10 +28,16 @@ body {
to {transform: translateY(0);}
}
@keyframes fade {
0% {background-color: #5d60ca;}
50% {background-color: #af2188;}
100% {background-color: #5d60ca;}
}
#title {
font-family: 'Nunito', sans-serif;
margin: 0 0;
z-index: 1;
z-index: 2;
animation: shine 5s linear infinite;
background: linear-gradient(to right, #5d60ca 20%, #171717 35%, #171717 35%, #5d60ca 50%, #5d60ca 50%, #af2188 75%, #5d60ca 90%);
background-size: 200% auto;
@ -42,11 +47,13 @@ body {
-webkit-user-select: none;
}
#title-sub-container {
#title-sub-container, #title-controls-container, #title-container-wrapper {
padding: 0 0;
margin: 0 0;
}
#title-container-wrapper {position: relative;}
#title-container {
position: fixed;
top: -5px;
@ -55,10 +62,35 @@ body {
width: 100vw;
overflow: hidden;
background-color: #0000006d;
z-index: 1;
z-index: 2;
-webkit-app-region: drag;
}
#title-controls-container {
font-family: 'Nunito', sans-serif;
right: 10px;
position: absolute;
top: -2px;
font-size: 20px;
}
#title-controls-container > * {
display: inline-block;
padding: 0 0;
margin: 0 5px;
}
#close-window {
top: -1px;
cursor: pointer!important;
z-index: 2;
}
#close-window:before, #close-window:after {
background-color: #5d60ca;
animation: fade 10s linear infinite;
}
.nosel {-webkit-user-select: none;}
@ -77,4 +109,14 @@ body {
background-image: linear-gradient(to bottom, #af2188c5 0%, #af2188c5 10%, #fa59cfc5 75%, #fa59cfc5 100%);
}
::-webkit-scrollbar-thumb:hover {background-image: linear-gradient(to bottom, #af2188ff 0%, #af2188ff 10%, #fa59cfff 75%, #fa59cfff 100%);}
::-webkit-scrollbar-thumb:hover {background-image: linear-gradient(to bottom, #af2188ff 0%, #af2188ff 10%, #fa59cfff 75%, #fa59cfff 100%);}
.invis {
position: relative;
left: -1000px;
width: 0;
height: 0;
padding: 0 0;
margin: 0 0;
opacity: 0;
}
Loading…
Cancel
Save