Compare commits

...

43 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 2 years ago
Kit Kasune 1446b04319 fancy compression modal 2 years ago
Kit Kasune 5e04744317 literally zip folders kek 2 years ago
Kit Kasune d8f4ff3267 add a meta tag so my linter stops yelling at me 2 years ago
Kit Kasune c24d40317f unselectable button text 2 years ago
Kit Kasune 17bfc3b1d0 1.7.0 -> File opening! 2 years ago
Kit Kasune 247abefe2b 1.6.4 -> QOL stuff 2 years ago
Kit Kasune 341ce45745 folder now selects after creation 2 years ago
Kit Kasune c5eeedd2a5 finally fix double click bug 2 years ago
Kit Kasune aff2356efc invisible input to prevent repeated deletion 2 years ago
Kit Kasune 1d8e370914 folder selection util 2 years ago
Kit Kasune e480605934 remove log from enter keybind 2 years ago
Kit Kasune ebcd95a76e 1.6.3 -> Deletable folders and stable modals 2 years ago
Kit Kasune 0f5e7eeb73 keybinds for delete modal + bugs 2 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 11c0d28ef3 refresh toast info 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 2524979142 pause toast timers 3 years ago
Kit Kasune e20fd331ef switch to manager for toasts 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
  1. 1
      .gitignore
  2. 28
      index.html
  3. 1
      json/changelogs/1.6.0.json
  4. 1
      json/changelogs/1.6.1.json
  5. 1
      json/changelogs/1.6.2.json
  6. 1
      json/changelogs/1.6.3.json
  7. 1
      json/changelogs/1.6.4.json
  8. 1
      json/changelogs/1.7.0.json
  9. 1
      json/changelogs/1.7.1.json
  10. 10
      json/ctx.json
  11. 18
      package-lock.json
  12. 3
      package.json
  13. 5
      scripts/contextmenu/compress-selected.js
  14. 105
      scripts/contextmenu/compress.js
  15. 23
      scripts/contextmenu/createcontext.js
  16. 105
      scripts/contextmenu/decompress.js
  17. 79
      scripts/contextmenu/delete-folder.js
  18. 1
      scripts/contextmenu/hidecontext.js
  19. 5
      scripts/contextmenu/newfolder.js
  20. 36
      scripts/contextmenu/pin.js
  21. 2
      scripts/contextmenu/refresh.js
  22. 94
      scripts/contextmenu/rename-folder.js
  23. 1
      scripts/fileview/load/load.js
  24. 20
      scripts/fileview/load/render.js
  25. 12
      scripts/fileview/selectfolder.js
  26. 35
      scripts/modal/common/error.js
  27. 10
      scripts/modal/post.js
  28. 5
      scripts/startup/changelog.js
  29. 1
      scripts/startup/initcontext.js
  30. 14
      scripts/startup/initsidebar.js
  31. 6
      scripts/startup/preload.js
  32. 3
      scripts/startup/setbuttons.js
  33. 28
      scripts/toast/createtoast.js
  34. 5
      styles/context.css
  35. 14
      styles/modal.css
  36. 6
      styles/sidebar.css
  37. 45
      styles/styles.css

1
.gitignore vendored

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

@ -3,6 +3,7 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'"> <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/styles.css" rel="stylesheet">
<link href='./styles/files.css' rel='stylesheet'> <link href='./styles/files.css' rel='stylesheet'>
@ -16,18 +17,35 @@
</head> </head>
<body> <body>
<div id="title-container"> <div id="title-container">
<div id="title-sub-container"> <div id="title-container-wrapper">
<p id="title" class="nosel">FileKade</p> <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> </div>
<div id="master"> <div id="master">
<div id="sidebar"> <div id="sidebar">
<div id="favorites"> <div id="favorites">
<div> <div id="favorites-wrapper">
<h2 class="nosel">Quick Access</h2> <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 id="favorites-container"></div>
</div> </div>
</div> </div>
<div id='container'> <div id='container'>

@ -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"}, {"name": "Sort by: Name", "id": "ctx-sort-by", "onclick": "changesort"},
@ -10,5 +13,10 @@
{"name": "Reload", "id": "ctx-reload", "onclick": "reload"}, {"name": "Reload", "id": "ctx-reload", "onclick": "reload"},
{"name": "Refresh", "id": "ctx-refresh", "onclick": "refresh"}, {"name": "Refresh", "id": "ctx-refresh", "onclick": "refresh"},
{"name": "Options", "id": "ctx-options", "onclick": "options"} {"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"}
] ]
] ]

18
package-lock.json generated

@ -1,14 +1,15 @@
{ {
"name": "filekade", "name": "filekade",
"version": "1.5.1", "version": "1.7.1",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "filekade", "name": "filekade",
"version": "1.5.1", "version": "1.7.1",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"adm-zip": "^0.5.9",
"chalk": "^4.1.2", "chalk": "^4.1.2",
"electron-squirrel-startup": "^1.0.0", "electron-squirrel-startup": "^1.0.0",
"generator-code": "^1.6.5" "generator-code": "^1.6.5"
@ -1993,6 +1994,14 @@
"integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true "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": { "node_modules/agent-base": {
"version": "6.0.2", "version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "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==", "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
"dev": true "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": { "agent-base": {
"version": "6.0.2", "version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",

@ -1,6 +1,6 @@
{ {
"name": "filekade", "name": "filekade",
"version": "1.5.1", "version": "1.7.1",
"description": "A file explorer (primarily a learning experience for me)", "description": "A file explorer (primarily a learning experience for me)",
"main": "main.js", "main": "main.js",
"scripts": { "scripts": {
@ -14,6 +14,7 @@
"author": "WubzyGD", "author": "WubzyGD",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"adm-zip": "^0.5.9",
"chalk": "^4.1.2", "chalk": "^4.1.2",
"electron-squirrel-startup": "^1.0.0", "electron-squirrel-startup": "^1.0.0",
"generator-code": "^1.6.5" "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; window.kade.context = true;
let ctx = document.getElementById('ctx'); let ctx = document.getElementById('ctx');
ctx.style.display = 'block'; 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.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`; 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) => { module.exports = (window) => {
document.getElementById('ctx').style.display = 'none'; document.getElementById('ctx').style.display = 'none';
if (!window) {return;}
window.kade.context = false; window.kade.context = false;
}; };

@ -9,6 +9,7 @@ const showError = require('../modal/common/error');
const clearModals = require('../modal/clearmodals'); const clearModals = require('../modal/clearmodals');
const newToast = require('../toast/createtoast'); const newToast = require('../toast/createtoast');
const refresh = require('../fileview/refresh'); const refresh = require('../fileview/refresh');
const selectFolder = require('../fileview/selectfolder');
module.exports = () => { module.exports = () => {
if (window.kade.modal) {return;} 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"); 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 { } 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.");}); 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(); 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");}
};

@ -1,4 +1,4 @@
module.exports = () => { module.exports = () => {
require('../toast/createtoast')("Refresh", "View refreshed!"); require('../toast/createtoast')("Refresh", "View refreshed!", undefined, undefined, undefined, () => require('../toast/createtoast')("Refresh vs. Reload", "Your view was refreshed. This means any changes to files or folders in the directory you're currently viewing will show. This should be all you need, but if the app is behaving weirdly, or you changed some settings that aren't loading properly, you can do a hard reload with <b>Ctrl + Shift + R</b>.", undefined, undefined, 10));
require('../fileview/lightrefresh')(window.kade.cpath); require('../fileview/lightrefresh')(window.kade.cpath);
}; };

@ -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) { for (const file of ldir) {
let ofile = {}; let ofile = {};
ofile.icon = fileIcon(`${dir}/${file}`, file); 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; 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");} 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();} 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 loadHierarchy = require("../hierarchy");
const newToast = require('../../toast/createtoast');
const isOverflowing = require('../../dep/overflowing'); const isOverflowing = require('../../dep/overflowing');
@ -13,17 +17,27 @@ module.exports = (dir, options) => {
let cfc = document.createElement("div"); let cfc = document.createElement("div");
cfc.className = 'file'; cfc.className = 'file';
if (options.animate) {cfc.classList.add('rise');} 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 () { cfc.onclick = function () {
window.kade.elc = true; 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'); 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.cl = cfc;
}; };
cfc.oncontextmenu = function () { cfc.oncontextmenu = function () {
window.kade.elc = true; window.kade.elc = true;
if (!cfc.classList.contains('file-active')) {cfc.classList.add('file-active');} 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.cl = cfc;
window.kade.ctxel = 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'); const postModal = require('../post');
module.exports = (name, text, after = () => {}) => { 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'); let modal = document.createElement('div');
modal.className = 'modal'; modal.className = 'modal-wrapper';
modalOut.appendChild(modal);
modal.classList.add('error-modal'); modal.classList.add('error-modal');
modal.id = 'error-modal'; modal.id = 'error-modal';
document.body.appendChild(modal);
let title = document.createElement('h2'); let title = document.createElement('h2');
title.innerHTML = `Error - ${name}`; title.innerHTML = `Error - ${name}`;
modal.appendChild(title); modal.appendChild(title);
@ -16,4 +24,21 @@ module.exports = (name, text, after = () => {}) => {
modal.appendChild(err); modal.appendChild(err);
after('error-modal'); after('error-modal');
postModal(); 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"); const transit = require("./transit");
module.exports = (id) => { module.exports = (id) => {
document.getElementById('modal-block').remove(); try {
window.kade.modal = false; try {document.getElementById('modal-block').remove();} catch {}
document.body.style.overflowY = 'overlay'; window.kade.modal = false;
transit(id, false); document.body.style.overflowY = 'overlay';
transit(id, false);
} catch {}
}; };

@ -59,10 +59,7 @@ module.exports = () => {
}); });
}); });
clww.style = `height: ${modalOut.clientHeight - 6};`; // TODO cry enough tears that they magically make this line work clww.style = `height: ${modalOut.clientHeight - 6};`;
console.log(clww.style.height);
console.log(modalOut.clientHeight - 6);
console.log(typeof clww.style);
let msm = new Mousetrap(modal); let msm = new Mousetrap(modal);
msm.bind('esc', () => { msm.bind('esc', () => {

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

@ -2,6 +2,8 @@ const refresh = require('../fileview/refresh');
const qa = require('../../json/qa.json'); const qa = require('../../json/qa.json');
const os = require("os"); const os = require("os");
const fs = require('fs');
const path = require('path');
module.exports = () => { module.exports = () => {
let root let root
@ -24,4 +26,16 @@ module.exports = () => {
quick.classList.add('nosel'); quick.classList.add('nosel');
quickAccess.appendChild(quick); 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);
});
}
}; };

@ -23,7 +23,11 @@ window.addEventListener('DOMContentLoaded', () => {
name: "Alpha", name: "Alpha",
semver: require('../../package.json').version semver: require('../../package.json').version
}, },
platform: undefined platform: undefined,
toasts: {
total: 0,
shown: []
}
}; };
const platform = ipcRenderer.sendSync('preload', 'request-platform'); const platform = ipcRenderer.sendSync('preload', 'request-platform');

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

@ -8,8 +8,6 @@ module.exports = (name, text, bg = '#a172a6', persistOnClick = false, time = 5,
toast.style.backgroundColor = `${bg}c2`; toast.style.backgroundColor = `${bg}c2`;
toast.style.borderColor = `${bg}c2`; toast.style.borderColor = `${bg}c2`;
toast.classList.add('toast-entering'); toast.classList.add('toast-entering');
toast.onmouseenter = () => {toast.style.backgroundColor = bg;};
toast.onmouseleave = () => {toast.style.backgroundColor = `${bg}c2`;};
let toastWrap = document.createElement('div'); let toastWrap = document.createElement('div');
toastWrap.className = 'toast-wrapper'; toastWrap.className = 'toast-wrapper';
let continueTimeout = true; let continueTimeout = true;
@ -40,7 +38,27 @@ module.exports = (name, text, bg = '#a172a6', persistOnClick = false, time = 5,
timer.style.backgroundColor = timerColor; timer.style.backgroundColor = timerColor;
timer.style.animation = `toast-timer ${time}s linear`; timer.style.animation = `toast-timer ${time}s linear`;
toastWrap.appendChild(timer); toastWrap.appendChild(timer);
//toast.onmouseenter = () => {timer.style.animationPlayState = 'paused';}; toast.id = `toast-${window.kade.toasts.total}`;
//toast.onmouseleave = () => {timer.style.animationPlayState = 'normal';}; toast.onmouseenter = () => {
setTimeout(() => {if (continueTimeout) {removeToast(toast);}}, time * 1000); let ctoast = window.kade.toasts.shown[toast.id.slice(6)];
ctoast.toast.style.backgroundColor = bg;
ctoast.timer.style.animationPlayState = 'paused';
clearTimeout(ctoast.timeout);
ctoast.tl = ctoast.tt - (Date.now() - ctoast.ts);
};
toast.onmouseleave = () => {
let ctoast = window.kade.toasts.shown[toast.id.slice(6)];
ctoast.toast.style.backgroundColor = `${bg}c2`;
ctoast.timer.style.animationPlayState = 'running';
ctoast.timeout = setTimeout(() => {if (continueTimeout) {removeToast(ctoast.toast);}}, ctoast.tl);
};
window.kade.toasts.shown[window.kade.toasts.total] = {
timeout: setTimeout(() => {if (continueTimeout) {removeToast(toast);}}, time * 1000),
timer,
toast,
tl: time * 1000,
ts: Date.now(),
tt: time * 1000
};
window.kade.toasts.total++;
}; };

@ -34,3 +34,8 @@
align-content: stretch; align-content: stretch;
row-gap: 2px; row-gap: 2px;
} }
#ctx-folder {
padding: 0 0;
margin: 0 0;
}

@ -68,8 +68,6 @@
z-index: 3; z-index: 3;
} }
.error-modal {max-width: 45%;}
.modal-wrapper { .modal-wrapper {
margin: 0 0; margin: 0 0;
padding: 0 0; padding: 0 0;
@ -95,6 +93,7 @@
display: block; display: block;
z-index: 200; z-index: 200;
position: relative; position: relative;
cursor: pointer;
} }
.close-button:before, .close-button:after { .close-button:before, .close-button:after {
content: ''; content: '';
@ -136,3 +135,14 @@
} }
#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%;
}

@ -14,7 +14,7 @@
#container {margin-left: 200px;} #container {margin-left: 200px;}
#favorites-container { #favorites-container, #favorites-wrapper, #custom-favorites-container {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: stretch; align-items: stretch;
@ -36,3 +36,7 @@
padding-left: 10px; padding-left: 10px;
color: white; color: white;
} }
.favorites-header {
margin-bottom: 7px;
}

@ -28,6 +28,12 @@ body {
to {transform: translateY(0);} to {transform: translateY(0);}
} }
@keyframes fade {
0% {background-color: #5d60ca;}
50% {background-color: #af2188;}
100% {background-color: #5d60ca;}
}
#title { #title {
font-family: 'Nunito', sans-serif; font-family: 'Nunito', sans-serif;
margin: 0 0; margin: 0 0;
@ -41,11 +47,13 @@ body {
-webkit-user-select: none; -webkit-user-select: none;
} }
#title-sub-container { #title-sub-container, #title-controls-container, #title-container-wrapper {
padding: 0 0; padding: 0 0;
margin: 0 0; margin: 0 0;
} }
#title-container-wrapper {position: relative;}
#title-container { #title-container {
position: fixed; position: fixed;
top: -5px; top: -5px;
@ -58,6 +66,31 @@ body {
-webkit-app-region: drag; -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;} .nosel {-webkit-user-select: none;}
@ -77,3 +110,13 @@ body {
} }
::-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