tab completions + more testimonials + velzie button
This commit is contained in:
parent
c13dfabd47
commit
dc4309ae38
8 changed files with 417 additions and 222 deletions
|
@ -86,6 +86,15 @@ nav {
|
|||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.emoji {
|
||||
--emoji-size: 1.1em;
|
||||
height: var(--emoji-size);
|
||||
width: var(--emoji-size);
|
||||
object-fit: contain;
|
||||
position: relative;
|
||||
top: 0.2em;
|
||||
}
|
||||
|
||||
.cursor {
|
||||
color: var(--crust);
|
||||
background-color: var(--text);
|
||||
|
|
BIN
img/emoji/neodog_bite_neocat.png
Normal file
BIN
img/emoji/neodog_bite_neocat.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
20
index.html
20
index.html
|
@ -47,10 +47,6 @@
|
|||
<nav>
|
||||
<div class="header-title">trinkey's website!</div>
|
||||
<div><a href="javascript:emptyWindow()">open terminal</a></div>
|
||||
<div class="hyphen">-</div>
|
||||
<div><a href="javascript:windowPreset('specs', true)">specs</a></div>
|
||||
<div class="hyphen">-</div>
|
||||
<div><a href="javascript:createBlob()">spin</a></div>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
|
@ -59,7 +55,7 @@
|
|||
<a href="no-js.html">this page</a> instead
|
||||
</noscript>
|
||||
|
||||
<img class="cat" src="img/cat.jpg" alt="My cat">
|
||||
<img class="cat" src="img/cat.jpg" alt="my cat">
|
||||
|
||||
<footer>
|
||||
<nav>
|
||||
|
@ -69,20 +65,6 @@
|
|||
</nav>
|
||||
</footer>
|
||||
|
||||
<div hidden id="window-templates">
|
||||
<ol data-template-id="specs">
|
||||
<li>_internal_set_ps1 trinkey@desktop|ssh trinkey@desktop<br>Last login: Tue Sep 10 12:00:24 2024 from 192.168.1.254</li>
|
||||
<li>_internal_neofetch desktop</li>
|
||||
<li>_internal_set_ps1 trinkey@website|exit</li>
|
||||
<li>_internal_set_ps1 trinkey@server|ssh trinkey@server<br>Last login: Tue Sep 11 9:03:02 2001 from 192.168.1.254</li>
|
||||
<li>_internal_neofetch server</li>
|
||||
<li>_internal_set_ps1 trinkey@website|exit</li>
|
||||
<li>(i never made a way to realistically access this via just the builtin commands yet so this is what you get)</li>
|
||||
<div data-template-field="width" data-is-number>1000</div>
|
||||
<div data-template-field="height" data-is-number>800</div>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<script src="js/index.js"></script>
|
||||
<script src="js/blobcat.js"></script>
|
||||
</body>
|
||||
|
|
223
js/index.js
223
js/index.js
|
@ -53,6 +53,74 @@ function edgeMoveEvent(x, y, pos, windowID) {
|
|||
w.element.querySelector(".window").style.width = `${w.width}px`;
|
||||
w.element.querySelector(".window").style.height = `${w.height}px`;
|
||||
}
|
||||
function mouseMoveEvent(windowID, x, y) {
|
||||
let w = WINDOWS[windowID];
|
||||
w.posX = Math.max(0, Math.min(innerWidth - w.width - _windowPaddingX, x - w.vars.mouseOffsetX));
|
||||
w.posY = Math.max(0, Math.min(innerHeight - w.height - _windowPaddingY, y - w.vars.mouseOffsetY));
|
||||
w.element.style.left = `${w.posX}px`;
|
||||
w.element.style.top = `${w.posY}px`;
|
||||
}
|
||||
function syncInputs(windowID) {
|
||||
let windowInput = WINDOWS[windowID].element.querySelector("input.window-input");
|
||||
let windowVisualText = WINDOWS[windowID].element.querySelector("[data-type-area]");
|
||||
let w = WINDOWS[windowID].element.querySelector(".window");
|
||||
if (!windowVisualText) {
|
||||
return;
|
||||
}
|
||||
setTimeout(function () {
|
||||
let text = windowInput.value;
|
||||
let cursor = windowInput.selectionStart;
|
||||
if (cursor == text.length) {
|
||||
windowVisualText.innerHTML = `${escapeHTML(text)}<i class="cursor"> </i>`;
|
||||
}
|
||||
else {
|
||||
windowVisualText.innerHTML = `${escapeHTML(text.slice(0, cursor))}<span class="cursor">${escapeHTML(text[cursor])}</span>${escapeHTML(text.slice(cursor + 1))}`;
|
||||
}
|
||||
}, 1);
|
||||
w.scrollTop = w.scrollHeight;
|
||||
}
|
||||
function setCursor(windowID) {
|
||||
let windowInput = WINDOWS[windowID].element.querySelector("input.window-input");
|
||||
setTimeout(() => {
|
||||
windowInput.setSelectionRange(windowInput.value.length, windowInput.value.length);
|
||||
syncInputs(windowID);
|
||||
}, 1);
|
||||
}
|
||||
function toggleFullscreen(windowID) {
|
||||
let w = WINDOWS[windowID];
|
||||
if (w.fullscreen) {
|
||||
w.posX = Math.max(0, Math.min(innerWidth - w.vars.oldWidth - _windowPaddingX, w.vars.oldPosX));
|
||||
w.posY = Math.max(0, Math.min(innerHeight - w.vars.oldHeight - _windowPaddingY, w.vars.oldPosY));
|
||||
w.width = Math.max(w.minWidth, Math.min(w.vars.oldWidth, innerWidth - _windowPaddingX));
|
||||
w.height = Math.max(w.minHeight, Math.min(w.vars.oldHeight, innerHeight - _windowPaddingY));
|
||||
w.fullscreen = false;
|
||||
delete w.vars.oldPosX;
|
||||
delete w.vars.oldPosY;
|
||||
delete w.vars.oldWidth;
|
||||
delete w.vars.oldHeight;
|
||||
w.element.style.left = `${w.posX}px`;
|
||||
w.element.style.top = `${w.posY}px`;
|
||||
w.element.style.width = `${w.width + _windowPaddingX - 2}px`;
|
||||
w.element.querySelector(".window").style.width = `${w.width}px`;
|
||||
w.element.querySelector(".window").style.height = `${w.height}px`;
|
||||
}
|
||||
else {
|
||||
w.vars.oldPosX = w.posX;
|
||||
w.vars.oldPosY = w.posY;
|
||||
w.vars.oldWidth = w.width;
|
||||
w.vars.oldHeight = w.height;
|
||||
w.fullscreen = true;
|
||||
w.posX = 0;
|
||||
w.posY = 0;
|
||||
w.width = innerWidth;
|
||||
w.height = innerHeight;
|
||||
w.element.style.left = "0px";
|
||||
w.element.style.top = "0px";
|
||||
w.element.style.width = `${w.width}px`;
|
||||
w.element.querySelector(".window").style.width = `${w.width - _windowPaddingX}px`;
|
||||
w.element.querySelector(".window").style.height = `${w.height - _windowPaddingY}px`;
|
||||
}
|
||||
}
|
||||
function createWindow(config) {
|
||||
if (document.getElementById(config.id)) {
|
||||
incrementZIndex(config.id);
|
||||
|
@ -90,30 +158,8 @@ function createWindow(config) {
|
|||
wI = document.createElement("input");
|
||||
wI.classList.add("window-input");
|
||||
wI.id = `${config.id}__input`;
|
||||
function syncInputs() {
|
||||
setTimeout(function () {
|
||||
let text = wI.value;
|
||||
let cursor = wI.selectionStart;
|
||||
let el = wC.querySelector("[data-type-area]");
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
if (cursor == text.length) {
|
||||
el.innerHTML = `${escapeHTML(text)}<i class="cursor"> </i>`;
|
||||
}
|
||||
else {
|
||||
el.innerHTML = `${escapeHTML(text.slice(0, cursor))}<span class="cursor">${escapeHTML(text[cursor])}</span>${escapeHTML(text.slice(cursor + 1))}`;
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
function setCursor() {
|
||||
setTimeout(() => {
|
||||
wI.setSelectionRange(wI.value.length, wI.value.length);
|
||||
syncInputs();
|
||||
}, 0);
|
||||
}
|
||||
wI.oninput = (event) => {
|
||||
syncInputs();
|
||||
syncInputs(config.id);
|
||||
w.scrollTop = w.scrollHeight;
|
||||
};
|
||||
wI.onkeydown = (event) => {
|
||||
|
@ -122,12 +168,88 @@ function createWindow(config) {
|
|||
w.scrollTop = w.scrollHeight;
|
||||
wI.value = "";
|
||||
}
|
||||
else if (event.key == "Tab") {
|
||||
event.preventDefault();
|
||||
let val = wI.value.trim();
|
||||
let possibilities = [];
|
||||
let parent;
|
||||
if (!val) {
|
||||
return;
|
||||
}
|
||||
if (val.split(" ").length == 1 && wI.value[wI.value.length - 1] != " ") {
|
||||
possibilities = Object.keys(_internal_commands).filter((cmd) => (cmd.startsWith(val) && !cmd.startsWith("_")));
|
||||
}
|
||||
else if (_internal_commands[val.split(" ")[0]] && _internal_commands[val.split(" ")[0]].autocomplete) {
|
||||
let ac = _internal_commands[val.split(" ")[0]].autocomplete;
|
||||
let path = val.split(" ").slice(1).join(" ").trim();
|
||||
let sw = path.split("/")[path.split("/").length - 1];
|
||||
if (typeof ac == "object") {
|
||||
possibilities = ac;
|
||||
}
|
||||
else {
|
||||
syncInputs();
|
||||
if (path) {
|
||||
if (path[path.length - 1] == "/") {
|
||||
parent = _internal_getFile(_internal_sanitizePath(_internal_joinPaths(windowInformation[config.id].PWD, path)));
|
||||
}
|
||||
else {
|
||||
parent = _internal_getFile(_internal_sanitizePath(_internal_joinPaths(windowInformation[config.id].PWD, path + "/..")));
|
||||
}
|
||||
}
|
||||
else {
|
||||
parent = _internal_getFile(windowInformation[config.id].PWD);
|
||||
}
|
||||
if (parent && parent.type == "directory") {
|
||||
let f = parent.files;
|
||||
possibilities = Object.keys(f);
|
||||
if (ac == "dir") {
|
||||
possibilities = possibilities.filter((file) => (f[file] && f[file].type == "directory"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
parent = null;
|
||||
}
|
||||
}
|
||||
possibilities = possibilities.filter((v) => v.startsWith(sw));
|
||||
}
|
||||
if (possibilities.length == 1) {
|
||||
if (val.split(" ").length == 1 && wI.value[wI.value.length - 1] != " ") {
|
||||
wI.value = possibilities[0] + " ";
|
||||
}
|
||||
else if (_internal_commands[val.split(" ")[0]] && _internal_commands[val.split(" ")[0]].autocomplete) {
|
||||
let path = val;
|
||||
if (val[val.length - 1] == "/") {
|
||||
path += possibilities[0];
|
||||
}
|
||||
else {
|
||||
let p = path.split("/");
|
||||
if (p.length == 1) {
|
||||
p = p[0].split(" ", 2);
|
||||
if (p.length == 1) {
|
||||
p.push("");
|
||||
}
|
||||
p.pop();
|
||||
path = p.join(" ") + " " + possibilities[0];
|
||||
}
|
||||
else {
|
||||
p.pop();
|
||||
path = p.join("/") + "/" + possibilities[0];
|
||||
}
|
||||
}
|
||||
wI.value = path + (parent && parent.type == "directory" && parent.files[possibilities[0]].type == "directory" ? "/" : " ");
|
||||
}
|
||||
syncInputs(config.id);
|
||||
}
|
||||
else if (possibilities) {
|
||||
addWindowCommand(config.id, possibilities.join(" "));
|
||||
syncInputs(config.id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
syncInputs(config.id);
|
||||
}
|
||||
};
|
||||
wI.onfocus = setCursor;
|
||||
wI.onclick = setCursor;
|
||||
wI.onfocus = () => { setCursor(config.id); };
|
||||
wI.onclick = () => { setCursor(config.id); };
|
||||
wC = document.createElement("label");
|
||||
wC.htmlFor = `${config.id}__input`;
|
||||
}
|
||||
|
@ -146,6 +268,7 @@ function createWindow(config) {
|
|||
let el = document.createElement("div");
|
||||
el.classList.add("edge", pos);
|
||||
el.addEventListener("mousedown", function (e) {
|
||||
incrementZIndex(config.id);
|
||||
e.preventDefault();
|
||||
WINDOWS[config.id].vars.mouseOffsetX = e.clientX - WINDOWS[config.id].posX;
|
||||
WINDOWS[config.id].vars.mouseOffsetY = e.clientY - WINDOWS[config.id].posY;
|
||||
|
@ -182,12 +305,9 @@ function createWindow(config) {
|
|||
zIndex: globalIncrement,
|
||||
vars: {}
|
||||
};
|
||||
function mouseMoveEvent(x, y) {
|
||||
WINDOWS[config.id].posX = Math.max(0, Math.min(innerWidth - WINDOWS[config.id].width - _windowPaddingX, x - WINDOWS[config.id].vars.mouseOffsetX));
|
||||
WINDOWS[config.id].posY = Math.max(0, Math.min(innerHeight - WINDOWS[config.id].height - _windowPaddingY, y - WINDOWS[config.id].vars.mouseOffsetY));
|
||||
wC.style.left = `${WINDOWS[config.id].posX}px`;
|
||||
wC.style.top = `${WINDOWS[config.id].posY}px`;
|
||||
}
|
||||
windowInformation[config.id] = {
|
||||
PWD: HOME_DIR
|
||||
};
|
||||
wC.addEventListener("focus", function () { incrementZIndex(config.id); });
|
||||
for (const link of wC.querySelectorAll("a")) {
|
||||
link.addEventListener("focus", function () { incrementZIndex(config.id); });
|
||||
|
@ -199,7 +319,7 @@ function createWindow(config) {
|
|||
WINDOWS[config.id].vars.mouseOffsetX = e.clientX - WINDOWS[config.id].posX;
|
||||
WINDOWS[config.id].vars.mouseOffsetY = e.clientY - WINDOWS[config.id].posY;
|
||||
MOUSE_MOVE_PROCESSING[config.id] = {
|
||||
callback: mouseMoveEvent,
|
||||
callback: (x, y) => { mouseMoveEvent(config.id, x, y); },
|
||||
mouseUp: true
|
||||
};
|
||||
});
|
||||
|
@ -212,41 +332,8 @@ function createWindow(config) {
|
|||
config.onDestroy();
|
||||
}
|
||||
});
|
||||
wH.querySelector(".fullscreen").addEventListener("click", function () {
|
||||
let window = WINDOWS[config.id];
|
||||
if (window.fullscreen) {
|
||||
window.posX = Math.max(0, Math.min(innerWidth - window.vars.oldWidth - _windowPaddingX, window.vars.oldPosX));
|
||||
window.posY = Math.max(0, Math.min(innerHeight - window.vars.oldHeight - _windowPaddingY, window.vars.oldPosY));
|
||||
window.width = Math.max(window.minWidth, Math.min(window.vars.oldWidth, innerWidth - _windowPaddingX));
|
||||
window.height = Math.max(window.minHeight, Math.min(window.vars.oldHeight, innerHeight - _windowPaddingY));
|
||||
window.fullscreen = false;
|
||||
delete window.vars.oldPosX;
|
||||
delete window.vars.oldPosY;
|
||||
delete window.vars.oldWidth;
|
||||
delete window.vars.oldHeight;
|
||||
wC.style.left = `${window.posX}px`;
|
||||
wC.style.top = `${window.posY}px`;
|
||||
wC.style.width = `${window.width + _windowPaddingX - 2}px`;
|
||||
w.style.width = `${window.width}px`;
|
||||
w.style.height = `${window.height}px`;
|
||||
}
|
||||
else {
|
||||
window.vars.oldPosX = window.posX;
|
||||
window.vars.oldPosY = window.posY;
|
||||
window.vars.oldWidth = window.width;
|
||||
window.vars.oldHeight = window.height;
|
||||
window.fullscreen = true;
|
||||
window.posX = 0;
|
||||
window.posY = 0;
|
||||
window.width = innerWidth;
|
||||
window.height = innerHeight;
|
||||
wC.style.left = "0px";
|
||||
wC.style.top = "0px";
|
||||
wC.style.width = `${window.width}px`;
|
||||
w.style.width = `${window.width - _windowPaddingX}px`;
|
||||
w.style.height = `${window.height - _windowPaddingY}px`;
|
||||
}
|
||||
});
|
||||
wH.querySelector(".fullscreen").addEventListener("click", () => (toggleFullscreen(config.id)));
|
||||
wH.addEventListener("dblclick", () => (toggleFullscreen(config.id)));
|
||||
globalIncrement++;
|
||||
}
|
||||
function windowPreset(template, dontDisableTyping = false) {
|
||||
|
|
67
js/shell.js
67
js/shell.js
|
@ -209,19 +209,21 @@ function _internal_neofetch(args, windowID) {
|
|||
return _internal_neofetchOutputs[args];
|
||||
}
|
||||
const _internal_commands = {
|
||||
cat: cat,
|
||||
cd: cd,
|
||||
clear: clear,
|
||||
help: help,
|
||||
ls: ls,
|
||||
exit: exit,
|
||||
_internal_set_ps1: _internal_set_ps1,
|
||||
_internal_neofetch: _internal_neofetch
|
||||
cat: { callback: cat, autocomplete: "file" },
|
||||
cd: { callback: cd, autocomplete: "dir" },
|
||||
clear: { callback: clear, autocomplete: null },
|
||||
help: { callback: help, autocomplete: null },
|
||||
ls: { callback: ls, autocomplete: "file" },
|
||||
exit: { callback: exit, autocomplete: null },
|
||||
_internal_set_ps1: { callback: _internal_set_ps1, autocomplete: null },
|
||||
_internal_neofetch: { callback: _internal_neofetch, autocomplete: null },
|
||||
spin: { callback: (args, windowID) => { createBlob(); return ""; }, autocomplete: null },
|
||||
};
|
||||
const _internal_defaultFiles = {
|
||||
about: `<div><b>hi there! i'm trinkey!</b></div>
|
||||
about: `<div><b>hi there!</b></div>
|
||||
<div>i'm trinkey, but you can call me <b>katie</b> too! <small>(trinkey is more of a username)</small></div>
|
||||
<div>--------------------</div>
|
||||
<div>i'm a silly little kitty cat who lives in the usa (sadly).</div>
|
||||
<div>i'm a silly little cat who lives in the usa (new york time zone).</div>
|
||||
<div>i'm <span class="blue">t</span><span class="pink">r</span>a<span class="pink">n</span><span class="blue">s</span> (she/it, they/them is also fine).</div>
|
||||
<div>i'm not actively in a relationship, however i'm also not looking to get into one either.</div>
|
||||
<div>--------------------</div>
|
||||
|
@ -236,6 +238,7 @@ const _internal_defaultFiles = {
|
|||
<div>- signal - <b>@trinkey.01</b></div>
|
||||
<div>- email - <b>trinkey [at] proton [dot] me</b></div>
|
||||
<div>- youtube - <a href="https://youtube.com/@trinkey" target="_blank"><b>@trinkey</b></a> (inactive)</div>
|
||||
<div>- discord - <b>@trinkey_</b> (mostly inactive)</div>
|
||||
<div>- <a href="trinkey_gpg.asc" target="_blank">gpg key</a> (1D6E 5D28 BDD4 D7FA 96B8 8799 2B33 C6C6 14F2 591A)</div>`,
|
||||
projects: `<div><b>projects</b> - the things i made</div>
|
||||
<div>- <a href="https://github.com/jerimiah-smiggins/smiggins/" target="_blank"><b>smiggins</b></a> (<a href="https://smiggins.trinkey.com/" target="_blank">website</a>) - a social media platform i made</div>
|
||||
|
@ -247,23 +250,28 @@ const _internal_defaultFiles = {
|
|||
buttons: `<div><b>my button:</b> (click to copy html)</div>
|
||||
<div><img style="cursor: pointer;" src="img/88x31.png" alt="trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button." title="trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button." onclick="copyButton()"></div>
|
||||
<div>--------------------</div>
|
||||
<div><b>cool people:</b></div>
|
||||
<div class="buttons-88x31">
|
||||
<a href="https://notfire.cc" target="_blank"><img src="https://notfire.cc/design/images/buttons/notfire-cc-88x31-af.gif" alt="notfire.cc" title="notfire.cc"></a>
|
||||
<a href="https://micro.niko.lgbt" target="_blank"><img src="https://micro.niko.lgbt/static/button_2.png" alt="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro"" title="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro""></a>
|
||||
<a href="https://microspinny.zip" target="_blank"><img src="https://microspinny.zip/static/button_2.png" alt="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro"" title="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro""></a>
|
||||
<a href="https://w.on-t.work" target="_blank"><img src="https://w.on-t.work/assets/88x31.png" alt="kopper's button" title="kopper's button"></a>
|
||||
<a href="https://synth.download" target="_blank"><img src="https://synth.download/assets/buttons/sneexy.svg" alt="Sneexy" title="Sneexy"></a>
|
||||
<a href="https://beepi.ng" target="_blank"><img src="https://beepi.ng/88x31.png" alt="unnick" title="unnick"></a>
|
||||
<a href="http://autumn.town" target="_blank"><img src="https://autumn.town/assets/buttons/mybutton.webp" alt="Autumn Town Café" title="Autumn Town Café"></a>
|
||||
<a href="https://redcatho.de" target="_blank"><img src="https://redcatho.de/buttons/red.png" alt="the text 'red is purple' on a purple background" title="the text 'red is purple' on a purple background"></a>
|
||||
<a href="https://doskel.net" target="_blank"><img src="https://doskel.net/button.png" alt="doskel" title="doskel"></a>
|
||||
<a href="https://velzie.rip" target="_blank"><img src="https://velzie.rip/88x31.png" alt="velzie" title="velzie"></a>
|
||||
</div>`,
|
||||
testimonials: `<div>"warning: this user is trinkey"</div>
|
||||
<div>- <a href="https://booping.synth.download/@breaadyboy" target="_blank">bread</a></div><br>
|
||||
<div>"This user is only slightly crazy once was I. 10/10 would recommend"</div>
|
||||
<div>- <a href="https://lea.pet/@subroutine" target="_blank">subroutine</a></div><br>
|
||||
<div>"the f slur but repeated 36 times"</div>
|
||||
<div>- <a href="https://oomfie.city/@cornfields74">corn fields seventy four</a></div>`,
|
||||
<div>- <a href="https://oomfie.city/@cornfields74" target="_blank">corn fields seventy four</a></div><br>
|
||||
<div>"silly cute kitn"</div>
|
||||
<div>- <a href="https://microspinny.zip" target="_blank">niko</a></div><br>
|
||||
<div>"very bitable <img class="emoji" alt="neodog_bite_neocat" src="img/emoji/neodog_bite_neocat.png"></div>
|
||||
<div>- <a href="https://booping.synth.download/@strongsand" target="_blank">strongsand</a></div>
|
||||
`,
|
||||
webrings: `<div>
|
||||
<a href="https://ctp-webr.ing/trinkey/previous">←</a>
|
||||
<a href="https://ctp-webr.ing/">catppuccin webring</a>
|
||||
|
@ -301,6 +309,7 @@ const _internal_defaultFiles = {
|
|||
<div>the <a href="https://codeberg.org/KittyShopper/mastoapi-fe">outpost</a> frontend for fedi made by kopper</div><br>
|
||||
<div><b><a href="https://smiggins.trinkey.com/">smiggins.trinkey.com</a>:</b></div>
|
||||
<div>official jerimiah smiggins instance, that being my own social media platform</div><br>
|
||||
<div>there's also a qna for me at *<a href="https://trinkey.com/qna/index.php">trinkey.com/qna</a></div><br>
|
||||
<div>(asterisk (*) means i haven't written the code for it)</div><br>`
|
||||
};
|
||||
const _internal_neofetchOutputs = {
|
||||
|
@ -343,25 +352,28 @@ const _internal_neofetchOutputs = {
|
|||
<b>'-MMMMMMMMMMMMM-'</b>
|
||||
<b>\`\`-:::::-\`\`</b></pre>`
|
||||
};
|
||||
const helpText = `<div> -=== <b class="pink">tSh help</b> ===-</div>
|
||||
const helpText = `
|
||||
<div> -=== <b class="pink">tSh help</b> ===-</div>
|
||||
<div>--------------------</div>
|
||||
<div>-= <b class="green">cat</b> =-</div>
|
||||
<div>Displays the contents of a file.</div>
|
||||
<div>displays the contents of a file</div>
|
||||
<div>-= <b class="green">cd</b> =-</div>
|
||||
<div>Changes the working directory.</div>
|
||||
<div>changes the working directory</div>
|
||||
<div>-= <b class="green">clear</b> =-</div>
|
||||
<div>Clears the terminal output.</div>
|
||||
<div>clears the terminal output</div>
|
||||
<div>-= <b class="green">help</b> =-</div>
|
||||
<div>Shows this help menu.</div>
|
||||
<div>shows this help menu</div>
|
||||
<div>-= <b class="green">ls</b> =-</div>
|
||||
<div>Lists all files in a directory.</div>
|
||||
<div>lists all files in a directory</div>
|
||||
<div> -l - displays more information about each file</div>
|
||||
<div> -a - displays all files</div>
|
||||
<div> -A - displays all files except implied . and ..</div>
|
||||
<div> -r - reverses the order of the files</div>
|
||||
<div> -R - recurse through all subdirectories</div>
|
||||
<div>-= <b class="green">spin</b> =-</div>
|
||||
<div>creates a new window with a spinning blobcat wireframe</div>
|
||||
<div>-= <b class="green">exit</b> =-</div>
|
||||
<div>Closes the terminal.</div>`;
|
||||
<div>closes the terminal window</div>`;
|
||||
const HOME_DIR = "/home/trinkey";
|
||||
let FILESYSTEM = {
|
||||
home: {
|
||||
|
@ -393,22 +405,16 @@ let FILESYSTEM = {
|
|||
cd: { type: "file", name: "cd", content: "<div>function cd(directory: string): void { ... }</div>" },
|
||||
clear: { type: "file", name: "clear", content: "<div>function clear(): void { ... }</div>" },
|
||||
help: { type: "file", name: "help", content: "<div>function help(): string { ... }</div>" },
|
||||
ls: { type: "file", name: "ls", content: "<div>function ls(directory: string): string { ... }</div>" },
|
||||
neofetch: { type: "file", name: "neofetch", content: "<div>function neofetch(): string { ... }</div>" }
|
||||
ls: { type: "file", name: "ls", content: "<div>function ls(directory?: string): string { ... }</div>" }
|
||||
}
|
||||
},
|
||||
".secret-file": { type: "file", name: ".secret-file", content: "<div>meow :3</div>" }
|
||||
};
|
||||
let windowInformation = {};
|
||||
function commandManager(windowID, command) {
|
||||
if (!windowInformation[windowID]) {
|
||||
windowInformation[windowID] = {
|
||||
PWD: HOME_DIR
|
||||
};
|
||||
}
|
||||
let out;
|
||||
if (_internal_commands[command.split(" ")[0]]) {
|
||||
out = _internal_commands[command.split(" ")[0]](command.split(" ").slice(1).join(" ").trim(), windowID);
|
||||
out = _internal_commands[command.split(" ")[0]].callback(command.split(" ").slice(1).join(" ").trim(), windowID);
|
||||
}
|
||||
else if (command == "") {
|
||||
out = "";
|
||||
|
@ -416,8 +422,11 @@ function commandManager(windowID, command) {
|
|||
else {
|
||||
out = `<div class="red">Unknown command '${escapeHTML(command.split(" ")[0])}'.</div><div>Type 'help' for a list of commands</div>`;
|
||||
}
|
||||
addWindowCommand(windowID, out);
|
||||
}
|
||||
function addWindowCommand(windowID, value) {
|
||||
let el = document.createElement("div");
|
||||
el.innerHTML = out;
|
||||
el.innerHTML = value;
|
||||
WINDOWS[windowID].element.querySelector(".window").append(el);
|
||||
let dTE = WINDOWS[windowID].element.querySelector("[data-type-area]");
|
||||
if (dTE) {
|
||||
|
|
|
@ -61,10 +61,9 @@
|
|||
<div>html:</div>
|
||||
<code style="overflow-x: scroll; display: inline-block; background-color: var(--mantle); padding: 5px 8px; border-radius: 5px;"><a href="https://trinkey.com/" target="_blank"><img src="https://trinkey.com/img/88x31.png" alt="trinkey's 88x31. image of her cat on the right with the word trinkey name taking up the rest of the button." title="trinkey's 88x31. image of her cat on the right with the word trinkey name taking up the rest of the button."></a></code>
|
||||
<div>--------------------</div>
|
||||
<h3>cool people:</h3>
|
||||
<div class="buttons-88x31">
|
||||
<a href="https://notfire.cc" target="_blank"><img src="https://notfire.cc/design/images/buttons/notfire-cc-88x31-af.gif" alt="notfire.cc"></a>
|
||||
<a href="https://micro.niko.lgbt" target="_blank"><img src="https://micro.niko.lgbt/static/button_2.png" alt="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro"" title="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro""></a>
|
||||
<a href="https://microspinny.zip" target="_blank"><img src="https://microspinny.zip/static/button_2.png" alt="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro"" title="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro""></a>
|
||||
<a href="https://w.on-t.work" target="_blank"><img src="https://w.on-t.work/assets/88x31.png" alt="kopper's button" title="kopper's button"></a>
|
||||
<a href="https://synth.download" target="_blank"><img src="https://synth.download/assets/buttons/sneexy.svg" alt="Sneexy" title="Sneexy"></a>
|
||||
<a href="https://beepi.ng" target="_blank"><img src="https://beepi.ng/88x31.png" alt="unnick" title="unnick"></a>
|
||||
|
@ -119,6 +118,7 @@
|
|||
<div>the <a href="https://codeberg.org/KittyShopper/mastoapi-fe">outpost</a> frontend for fedi made by kopper</div><br>
|
||||
<div><b><a href="https://smiggins.trinkey.com/">smiggins.trinkey.com</a>:</b></div>
|
||||
<div>official jerimiah smiggins instance, that being my own social media platform</div><br>
|
||||
<div>there's also a qna for me at *<a href="https://trinkey.com/qna/index.php">trinkey.com/qna</a></div><br>
|
||||
<div>(asterisk (*) means i haven't written the code for it)</div>
|
||||
</div>
|
||||
</body>
|
||||
|
|
230
ts/index.ts
230
ts/index.ts
|
@ -68,6 +68,79 @@ function edgeMoveEvent(x: number, y: number, pos: "top" | "bottom" | "left" | "r
|
|||
(w.element.querySelector(".window") as HTMLElement).style.height = `${w.height}px`;
|
||||
}
|
||||
|
||||
function mouseMoveEvent(windowID: string, x: number, y: number): void {
|
||||
let w: _winConf = WINDOWS[windowID];
|
||||
w.posX = Math.max(0, Math.min(innerWidth - w.width - _windowPaddingX, x - w.vars.mouseOffsetX));
|
||||
w.posY = Math.max(0, Math.min(innerHeight - w.height - _windowPaddingY, y - w.vars.mouseOffsetY));
|
||||
w.element.style.left = `${w.posX}px`;
|
||||
w.element.style.top = `${w.posY}px`;
|
||||
}
|
||||
|
||||
function syncInputs(windowID: string): void {
|
||||
let windowInput: HTMLInputElement = WINDOWS[windowID].element.querySelector("input.window-input");
|
||||
let windowVisualText: HTMLDivElement = WINDOWS[windowID].element.querySelector("[data-type-area]");
|
||||
let w: HTMLDivElement = WINDOWS[windowID].element.querySelector(".window");
|
||||
|
||||
if (!windowVisualText) { return; }
|
||||
|
||||
setTimeout(function(): void {
|
||||
let text: string = windowInput.value;
|
||||
let cursor: number = windowInput.selectionStart;
|
||||
|
||||
if (cursor == text.length) {
|
||||
windowVisualText.innerHTML = `${escapeHTML(text)}<i class="cursor"> </i>`;
|
||||
} else {
|
||||
windowVisualText.innerHTML = `${escapeHTML(text.slice(0, cursor))}<span class="cursor">${escapeHTML(text[cursor])}</span>${escapeHTML(text.slice(cursor + 1))}`;
|
||||
}
|
||||
}, 1);
|
||||
|
||||
w.scrollTop = w.scrollHeight;
|
||||
}
|
||||
|
||||
function setCursor(windowID: string): void {
|
||||
let windowInput: HTMLInputElement = WINDOWS[windowID].element.querySelector("input.window-input");
|
||||
|
||||
setTimeout((): void => {
|
||||
windowInput.setSelectionRange(windowInput.value.length, windowInput.value.length);
|
||||
syncInputs(windowID);
|
||||
}, 1);
|
||||
}
|
||||
|
||||
function toggleFullscreen(windowID: string): void {
|
||||
let w: _winConf = WINDOWS[windowID];
|
||||
if (w.fullscreen) {
|
||||
w.posX = Math.max(0, Math.min(innerWidth - w.vars.oldWidth - _windowPaddingX, w.vars.oldPosX)); // window.vars.oldPosX;
|
||||
w.posY = Math.max(0, Math.min(innerHeight - w.vars.oldHeight - _windowPaddingY, w.vars.oldPosY)); // window.vars.oldPosY;
|
||||
w.width = Math.max(w.minWidth, Math.min(w.vars.oldWidth, innerWidth - _windowPaddingX)); // window.vars.oldWidth;
|
||||
w.height = Math.max(w.minHeight, Math.min(w.vars.oldHeight, innerHeight - _windowPaddingY)); // window.vars.oldHeight;
|
||||
w.fullscreen = false;
|
||||
delete w.vars.oldPosX;
|
||||
delete w.vars.oldPosY;
|
||||
delete w.vars.oldWidth;
|
||||
delete w.vars.oldHeight;
|
||||
w.element.style.left = `${w.posX}px`;
|
||||
w.element.style.top = `${w.posY}px`;
|
||||
w.element.style.width = `${w.width + _windowPaddingX - 2}px`;
|
||||
(w.element.querySelector(".window") as HTMLElement).style.width = `${w.width}px`;
|
||||
(w.element.querySelector(".window") as HTMLElement).style.height = `${w.height}px`;
|
||||
} else {
|
||||
w.vars.oldPosX = w.posX;
|
||||
w.vars.oldPosY = w.posY;
|
||||
w.vars.oldWidth = w.width;
|
||||
w.vars.oldHeight = w.height;
|
||||
w.fullscreen = true;
|
||||
w.posX = 0;
|
||||
w.posY = 0;
|
||||
w.width = innerWidth;
|
||||
w.height = innerHeight;
|
||||
w.element.style.left = "0px";
|
||||
w.element.style.top = "0px";
|
||||
w.element.style.width = `${w.width}px`;
|
||||
(w.element.querySelector(".window") as HTMLElement).style.width = `${w.width - _windowPaddingX}px`;
|
||||
(w.element.querySelector(".window") as HTMLElement).style.height = `${w.height - _windowPaddingY}px`;
|
||||
}
|
||||
}
|
||||
|
||||
function createWindow(config: _winInitConf): void {
|
||||
if (document.getElementById(config.id)) {
|
||||
incrementZIndex(config.id);
|
||||
|
@ -114,31 +187,8 @@ function createWindow(config: _winInitConf): void {
|
|||
wI.classList.add("window-input");
|
||||
wI.id = `${config.id}__input`;
|
||||
|
||||
function syncInputs(): void {
|
||||
setTimeout(function(): void {
|
||||
let text: string = wI.value;
|
||||
let cursor: number = wI.selectionStart;
|
||||
let el: HTMLElement = wC.querySelector("[data-type-area]");
|
||||
|
||||
if (!el) { return; }
|
||||
|
||||
if (cursor == text.length) {
|
||||
el.innerHTML = `${escapeHTML(text)}<i class="cursor"> </i>`;
|
||||
} else {
|
||||
el.innerHTML = `${escapeHTML(text.slice(0, cursor))}<span class="cursor">${escapeHTML(text[cursor])}</span>${escapeHTML(text.slice(cursor + 1))}`;
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
function setCursor(): void {
|
||||
setTimeout((): void => {
|
||||
wI.setSelectionRange(wI.value.length, wI.value.length);
|
||||
syncInputs();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
wI.oninput = (event: KeyboardEvent): void => {
|
||||
syncInputs();
|
||||
syncInputs(config.id);
|
||||
w.scrollTop = w.scrollHeight;
|
||||
};
|
||||
|
||||
|
@ -147,13 +197,91 @@ function createWindow(config: _winInitConf): void {
|
|||
commandManager(config.id, wI.value.trim());
|
||||
w.scrollTop = w.scrollHeight;
|
||||
wI.value = "";
|
||||
} else if (event.key == "Tab") {
|
||||
event.preventDefault();
|
||||
|
||||
let val: string = wI.value.trim();
|
||||
let possibilities: string[] = [];
|
||||
let parent: _file | null;
|
||||
|
||||
if (!val) { return; }
|
||||
|
||||
if (val.split(" ").length == 1 && wI.value[wI.value.length - 1] != " ") {
|
||||
possibilities = Object.keys(_internal_commands).filter((cmd: string): boolean => (cmd.startsWith(val) && !cmd.startsWith("_")));
|
||||
} else if (_internal_commands[val.split(" ")[0]] && _internal_commands[val.split(" ")[0]].autocomplete) {
|
||||
let ac: "dir" | "file" | string[] = _internal_commands[val.split(" ")[0]].autocomplete;
|
||||
let path: string = val.split(" ").slice(1).join(" ").trim();
|
||||
let sw: string = path.split("/")[path.split("/").length - 1];
|
||||
|
||||
if (typeof ac == "object") {
|
||||
possibilities = ac;
|
||||
} else {
|
||||
syncInputs();
|
||||
if (path) {
|
||||
if (path[path.length - 1] == "/") {
|
||||
parent = _internal_getFile(_internal_sanitizePath(_internal_joinPaths(windowInformation[config.id].PWD, path)));
|
||||
} else {
|
||||
parent = _internal_getFile(_internal_sanitizePath(_internal_joinPaths(windowInformation[config.id].PWD, path + "/..")));
|
||||
}
|
||||
} else {
|
||||
parent = _internal_getFile(windowInformation[config.id].PWD);
|
||||
}
|
||||
|
||||
if (parent && parent.type == "directory") {
|
||||
let f: _files = parent.files;
|
||||
possibilities = Object.keys(f);
|
||||
|
||||
if (ac == "dir") {
|
||||
possibilities = possibilities.filter((file: string): boolean => (f[file] && f[file].type == "directory"));
|
||||
}
|
||||
} else {
|
||||
parent = null;
|
||||
}
|
||||
}
|
||||
|
||||
possibilities = possibilities.filter((v: string): boolean => v.startsWith(sw));
|
||||
}
|
||||
|
||||
if (possibilities.length == 1) {
|
||||
if (val.split(" ").length == 1 && wI.value[wI.value.length - 1] != " ") {
|
||||
wI.value = possibilities[0] + " ";
|
||||
} else if (_internal_commands[val.split(" ")[0]] && _internal_commands[val.split(" ")[0]].autocomplete) {
|
||||
let path: string = val;
|
||||
|
||||
if (val[val.length - 1] == "/") {
|
||||
path += possibilities[0];
|
||||
} else {
|
||||
let p: string[] = path.split("/");
|
||||
|
||||
if (p.length == 1) {
|
||||
p = p[0].split(" ", 2);
|
||||
|
||||
if (p.length == 1) {
|
||||
p.push("");
|
||||
}
|
||||
|
||||
p.pop();
|
||||
path = p.join(" ") + " " + possibilities[0];
|
||||
} else {
|
||||
p.pop();
|
||||
path = p.join("/") + "/" + possibilities[0];
|
||||
}
|
||||
}
|
||||
|
||||
wI.value = path + (parent && parent.type == "directory" && parent.files[possibilities[0]].type == "directory" ? "/" : " ");
|
||||
}
|
||||
|
||||
syncInputs(config.id);
|
||||
} else if (possibilities) {
|
||||
addWindowCommand(config.id, possibilities.join(" "));
|
||||
syncInputs(config.id);
|
||||
}
|
||||
} else {
|
||||
syncInputs(config.id);
|
||||
}
|
||||
};
|
||||
|
||||
wI.onfocus = setCursor;
|
||||
wI.onclick = setCursor;
|
||||
wI.onfocus = (): void => { setCursor(config.id); };
|
||||
wI.onclick = (): void => { setCursor(config.id); };
|
||||
|
||||
wC = document.createElement("label");
|
||||
wC.htmlFor = `${config.id}__input`;
|
||||
|
@ -174,6 +302,7 @@ function createWindow(config: _winInitConf): void {
|
|||
let el: HTMLDivElement = document.createElement("div");
|
||||
el.classList.add("edge", pos);
|
||||
el.addEventListener("mousedown", function(e: MouseEvent): void {
|
||||
incrementZIndex(config.id);
|
||||
e.preventDefault();
|
||||
|
||||
WINDOWS[config.id].vars.mouseOffsetX = e.clientX - WINDOWS[config.id].posX;
|
||||
|
@ -215,12 +344,9 @@ function createWindow(config: _winInitConf): void {
|
|||
vars: {}
|
||||
};
|
||||
|
||||
function mouseMoveEvent(x: number, y: number): void {
|
||||
WINDOWS[config.id].posX = Math.max(0, Math.min(innerWidth - WINDOWS[config.id].width - _windowPaddingX, x - WINDOWS[config.id].vars.mouseOffsetX));
|
||||
WINDOWS[config.id].posY = Math.max(0, Math.min(innerHeight - WINDOWS[config.id].height - _windowPaddingY, y - WINDOWS[config.id].vars.mouseOffsetY));
|
||||
wC.style.left = `${WINDOWS[config.id].posX}px`;
|
||||
wC.style.top = `${WINDOWS[config.id].posY}px`;
|
||||
}
|
||||
windowInformation[config.id] = {
|
||||
PWD: HOME_DIR
|
||||
};
|
||||
|
||||
// wC.addEventListener("mousedown", function(): void { incrementZIndex(config.id); });
|
||||
wC.addEventListener("focus", function(): void { incrementZIndex(config.id); });
|
||||
|
@ -237,7 +363,7 @@ function createWindow(config: _winInitConf): void {
|
|||
WINDOWS[config.id].vars.mouseOffsetX = e.clientX - WINDOWS[config.id].posX;
|
||||
WINDOWS[config.id].vars.mouseOffsetY = e.clientY - WINDOWS[config.id].posY;
|
||||
MOUSE_MOVE_PROCESSING[config.id] = {
|
||||
callback: mouseMoveEvent,
|
||||
callback: (x: number, y: number): void => { mouseMoveEvent(config.id, x, y); },
|
||||
mouseUp: true
|
||||
};
|
||||
});
|
||||
|
@ -253,40 +379,8 @@ function createWindow(config: _winInitConf): void {
|
|||
}
|
||||
});
|
||||
|
||||
wH.querySelector(".fullscreen").addEventListener("click", function(): void {
|
||||
let window: _winConf = WINDOWS[config.id];
|
||||
if (window.fullscreen) {
|
||||
window.posX = Math.max(0, Math.min(innerWidth - window.vars.oldWidth - _windowPaddingX, window.vars.oldPosX)); // window.vars.oldPosX;
|
||||
window.posY = Math.max(0, Math.min(innerHeight - window.vars.oldHeight - _windowPaddingY, window.vars.oldPosY)); // window.vars.oldPosY;
|
||||
window.width = Math.max(window.minWidth, Math.min(window.vars.oldWidth, innerWidth - _windowPaddingX)); // window.vars.oldWidth;
|
||||
window.height = Math.max(window.minHeight, Math.min(window.vars.oldHeight, innerHeight - _windowPaddingY)); // window.vars.oldHeight;
|
||||
window.fullscreen = false;
|
||||
delete window.vars.oldPosX;
|
||||
delete window.vars.oldPosY;
|
||||
delete window.vars.oldWidth;
|
||||
delete window.vars.oldHeight;
|
||||
wC.style.left = `${window.posX}px`;
|
||||
wC.style.top = `${window.posY}px`;
|
||||
wC.style.width = `${window.width + _windowPaddingX - 2}px`;
|
||||
w.style.width = `${window.width}px`;
|
||||
w.style.height = `${window.height}px`;
|
||||
} else {
|
||||
window.vars.oldPosX = window.posX;
|
||||
window.vars.oldPosY = window.posY;
|
||||
window.vars.oldWidth = window.width;
|
||||
window.vars.oldHeight = window.height;
|
||||
window.fullscreen = true;
|
||||
window.posX = 0;
|
||||
window.posY = 0;
|
||||
window.width = innerWidth;
|
||||
window.height = innerHeight;
|
||||
wC.style.left = "0px";
|
||||
wC.style.top = "0px";
|
||||
wC.style.width = `${window.width}px`;
|
||||
w.style.width = `${window.width - _windowPaddingX}px`;
|
||||
w.style.height = `${window.height - _windowPaddingY}px`;
|
||||
}
|
||||
});
|
||||
wH.querySelector(".fullscreen").addEventListener("click", (): void => (toggleFullscreen(config.id)));
|
||||
wH.addEventListener("dblclick", (): void => (toggleFullscreen(config.id)));
|
||||
|
||||
globalIncrement++;
|
||||
}
|
||||
|
|
78
ts/shell.ts
78
ts/shell.ts
|
@ -251,23 +251,30 @@ function _internal_neofetch(args: string, windowID: string): string {
|
|||
return _internal_neofetchOutputs[args];
|
||||
}
|
||||
|
||||
const _internal_commands: { [key: string]: (args: string, windowID: string) => string } = {
|
||||
cat: cat,
|
||||
cd: cd,
|
||||
clear: clear,
|
||||
help: help, // NEEDS UPDATING
|
||||
ls: ls,
|
||||
exit: exit,
|
||||
_internal_set_ps1: _internal_set_ps1,
|
||||
_internal_neofetch: _internal_neofetch
|
||||
const _internal_commands: {
|
||||
[key: string]: {
|
||||
callback: (args: string, windowID: string) => string,
|
||||
autocomplete: "dir" | "file" | null | string[]
|
||||
}
|
||||
} = {
|
||||
cat: { callback: cat, autocomplete: "file" },
|
||||
cd: { callback: cd, autocomplete: "dir" },
|
||||
clear: { callback: clear, autocomplete: null },
|
||||
help: { callback: help, autocomplete: null },
|
||||
ls: { callback: ls, autocomplete: "file" },
|
||||
exit: { callback: exit, autocomplete: null },
|
||||
_internal_set_ps1: { callback: _internal_set_ps1, autocomplete: null },
|
||||
_internal_neofetch: { callback: _internal_neofetch, autocomplete: null },
|
||||
spin: { callback: (args: string, windowID: string): string => { createBlob(); return ""; }, autocomplete: null },
|
||||
};
|
||||
|
||||
// -= Variables + Other =- //
|
||||
const _internal_defaultFiles: StringDict = {
|
||||
about: `<div><b>hi there! i'm trinkey!</b></div>
|
||||
about: `<div><b>hi there!</b></div>
|
||||
<div>i'm trinkey, but you can call me <b>katie</b> too! <small>(trinkey is more of a username)</small></div>
|
||||
<div>--------------------</div>
|
||||
<div>i'm a silly little kitty cat who lives in the usa (sadly).</div>
|
||||
<div>i'm <span class="blue">t</span><span class="pink">r</span>a<span class="pink">n</span><span class="blue">s</span> (she/is, they/them is also fine).</div>
|
||||
<div>i'm a silly little cat who lives in the usa (new york time zone).</div>
|
||||
<div>i'm <span class="blue">t</span><span class="pink">r</span>a<span class="pink">n</span><span class="blue">s</span> (she/it, they/them is also fine).</div>
|
||||
<div>i'm not actively in a relationship, however i'm also not looking to get into one either.</div>
|
||||
<div>--------------------</div>
|
||||
<div>i like to code stuff (mostly websites)! some of my programs can be found in projects section. i know a few languages, those being python, javascript/typescript, html/css (if you count those), and a little bit of java.</div>
|
||||
|
@ -281,6 +288,7 @@ const _internal_defaultFiles: StringDict = {
|
|||
<div>- signal - <b>@trinkey.01</b></div>
|
||||
<div>- email - <b>trinkey [at] proton [dot] me</b></div>
|
||||
<div>- youtube - <a href="https://youtube.com/@trinkey" target="_blank"><b>@trinkey</b></a> (inactive)</div>
|
||||
<div>- discord - <b>@trinkey_</b> (mostly inactive)</div>
|
||||
<div>- <a href="trinkey_gpg.asc" target="_blank">gpg key</a> (1D6E 5D28 BDD4 D7FA 96B8 8799 2B33 C6C6 14F2 591A)</div>`,
|
||||
projects: `<div><b>projects</b> - the things i made</div>
|
||||
<div>- <a href="https://github.com/jerimiah-smiggins/smiggins/" target="_blank"><b>smiggins</b></a> (<a href="https://smiggins.trinkey.com/" target="_blank">website</a>) - a social media platform i made</div>
|
||||
|
@ -292,23 +300,28 @@ const _internal_defaultFiles: StringDict = {
|
|||
buttons: `<div><b>my button:</b> (click to copy html)</div>
|
||||
<div><img style="cursor: pointer;" src="img/88x31.png" alt="trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button." title="trinkey's 88x31. image of her cat on the right with the word 'trinkey' taking up the rest of the button." onclick="copyButton()"></div>
|
||||
<div>--------------------</div>
|
||||
<div><b>cool people:</b></div>
|
||||
<div class="buttons-88x31">
|
||||
<a href="https://notfire.cc" target="_blank"><img src="https://notfire.cc/design/images/buttons/notfire-cc-88x31-af.gif" alt="notfire.cc" title="notfire.cc"></a>
|
||||
<a href="https://micro.niko.lgbt" target="_blank"><img src="https://micro.niko.lgbt/static/button_2.png" alt="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro"" title="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro""></a>
|
||||
<a href="https://microspinny.zip" target="_blank"><img src="https://microspinny.zip/static/button_2.png" alt="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro"" title="a non-spinning demigirl blobcat angled slightly with a black border to the left of "Micro""></a>
|
||||
<a href="https://w.on-t.work" target="_blank"><img src="https://w.on-t.work/assets/88x31.png" alt="kopper's button" title="kopper's button"></a>
|
||||
<a href="https://synth.download" target="_blank"><img src="https://synth.download/assets/buttons/sneexy.svg" alt="Sneexy" title="Sneexy"></a>
|
||||
<a href="https://beepi.ng" target="_blank"><img src="https://beepi.ng/88x31.png" alt="unnick" title="unnick"></a>
|
||||
<a href="http://autumn.town" target="_blank"><img src="https://autumn.town/assets/buttons/mybutton.webp" alt="Autumn Town Café" title="Autumn Town Café"></a>
|
||||
<a href="https://redcatho.de" target="_blank"><img src="https://redcatho.de/buttons/red.png" alt="the text 'red is purple' on a purple background" title="the text 'red is purple' on a purple background"></a>
|
||||
<a href="https://doskel.net" target="_blank"><img src="https://doskel.net/button.png" alt="doskel" title="doskel"></a>
|
||||
<a href="https://velzie.rip" target="_blank"><img src="https://velzie.rip/88x31.png" alt="velzie" title="velzie"></a>
|
||||
</div>`,
|
||||
testimonials: `<div>"warning: this user is trinkey"</div>
|
||||
<div>- <a href="https://booping.synth.download/@breaadyboy" target="_blank">bread</a></div><br>
|
||||
<div>"This user is only slightly crazy once was I. 10/10 would recommend"</div>
|
||||
<div>- <a href="https://lea.pet/@subroutine" target="_blank">subroutine</a></div><br>
|
||||
<div>"the f slur but repeated 36 times"</div>
|
||||
<div>- <a href="https://oomfie.city/@cornfields74">corn fields seventy four</a></div>`,
|
||||
<div>- <a href="https://oomfie.city/@cornfields74" target="_blank">corn fields seventy four</a></div><br>
|
||||
<div>"silly cute kitn"</div>
|
||||
<div>- <a href="https://microspinny.zip" target="_blank">niko</a></div><br>
|
||||
<div>"very bitable <img class="emoji" alt="neodog_bite_neocat" src="img/emoji/neodog_bite_neocat.png"></div>
|
||||
<div>- <a href="https://booping.synth.download/@strongsand" target="_blank">strongsand</a></div>
|
||||
`,
|
||||
webrings: `<div>
|
||||
<a href="https://ctp-webr.ing/trinkey/previous">←</a>
|
||||
<a href="https://ctp-webr.ing/">catppuccin webring</a>
|
||||
|
@ -346,6 +359,7 @@ const _internal_defaultFiles: StringDict = {
|
|||
<div>the <a href="https://codeberg.org/KittyShopper/mastoapi-fe">outpost</a> frontend for fedi made by kopper</div><br>
|
||||
<div><b><a href="https://smiggins.trinkey.com/">smiggins.trinkey.com</a>:</b></div>
|
||||
<div>official jerimiah smiggins instance, that being my own social media platform</div><br>
|
||||
<div>there's also a qna for me at *<a href="https://trinkey.com/qna/index.php">trinkey.com/qna</a></div><br>
|
||||
<div>(asterisk (*) means i haven't written the code for it)</div><br>`
|
||||
};
|
||||
|
||||
|
@ -390,25 +404,28 @@ const _internal_neofetchOutputs: StringDict = {
|
|||
<b>\`\`-:::::-\`\`</b></pre>`
|
||||
};
|
||||
|
||||
const helpText: string = `<div> -=== <b class="pink">tSh help</b> ===-</div>
|
||||
const helpText: string = `
|
||||
<div> -=== <b class="pink">tSh help</b> ===-</div>
|
||||
<div>--------------------</div>
|
||||
<div>-= <b class="green">cat</b> =-</div>
|
||||
<div>Displays the contents of a file.</div>
|
||||
<div>displays the contents of a file</div>
|
||||
<div>-= <b class="green">cd</b> =-</div>
|
||||
<div>Changes the working directory.</div>
|
||||
<div>changes the working directory</div>
|
||||
<div>-= <b class="green">clear</b> =-</div>
|
||||
<div>Clears the terminal output.</div>
|
||||
<div>clears the terminal output</div>
|
||||
<div>-= <b class="green">help</b> =-</div>
|
||||
<div>Shows this help menu.</div>
|
||||
<div>shows this help menu</div>
|
||||
<div>-= <b class="green">ls</b> =-</div>
|
||||
<div>Lists all files in a directory.</div>
|
||||
<div>lists all files in a directory</div>
|
||||
<div> -l - displays more information about each file</div>
|
||||
<div> -a - displays all files</div>
|
||||
<div> -A - displays all files except implied . and ..</div>
|
||||
<div> -r - reverses the order of the files</div>
|
||||
<div> -R - recurse through all subdirectories</div>
|
||||
<div>-= <b class="green">spin</b> =-</div>
|
||||
<div>creates a new window with a spinning blobcat wireframe</div>
|
||||
<div>-= <b class="green">exit</b> =-</div>
|
||||
<div>Closes the terminal.</div>`;
|
||||
<div>closes the terminal window</div>`;
|
||||
|
||||
const HOME_DIR: string = "/home/trinkey";
|
||||
|
||||
|
@ -442,8 +459,7 @@ let FILESYSTEM: _files = {
|
|||
cd: { type: "file", name: "cd", content: "<div>function cd(directory: string): void { ... }</div>" },
|
||||
clear: { type: "file", name: "clear", content: "<div>function clear(): void { ... }</div>" },
|
||||
help: { type: "file", name: "help", content: "<div>function help(): string { ... }</div>" },
|
||||
ls: { type: "file", name: "ls", content: "<div>function ls(directory: string): string { ... }</div>" },
|
||||
neofetch: { type: "file", name: "neofetch", content: "<div>function neofetch(): string { ... }</div>" }
|
||||
ls: { type: "file", name: "ls", content: "<div>function ls(directory?: string): string { ... }</div>" }
|
||||
}
|
||||
},
|
||||
".secret-file": { type: "file", name: ".secret-file", content: "<div>meow :3</div>" }
|
||||
|
@ -452,23 +468,21 @@ let FILESYSTEM: _files = {
|
|||
let windowInformation: { [key: string]: _tShWinInfo } = {};
|
||||
|
||||
function commandManager(windowID: string, command: string): void {
|
||||
if (!windowInformation[windowID]) {
|
||||
windowInformation[windowID] = {
|
||||
PWD: HOME_DIR
|
||||
};
|
||||
}
|
||||
|
||||
let out: string;
|
||||
if (_internal_commands[command.split(" ")[0]]) {
|
||||
out = _internal_commands[command.split(" ")[0]](command.split(" ").slice(1).join(" ").trim(), windowID);
|
||||
out = _internal_commands[command.split(" ")[0]].callback(command.split(" ").slice(1).join(" ").trim(), windowID);
|
||||
} else if (command == "") {
|
||||
out = ""
|
||||
} else {
|
||||
out = `<div class="red">Unknown command '${escapeHTML(command.split(" ")[0])}'.</div><div>Type 'help' for a list of commands</div>`;
|
||||
}
|
||||
|
||||
addWindowCommand(windowID, out);
|
||||
}
|
||||
|
||||
function addWindowCommand(windowID: string, value: string): void {
|
||||
let el: HTMLDivElement = document.createElement("div");
|
||||
el.innerHTML = out;
|
||||
el.innerHTML = value;
|
||||
WINDOWS[windowID].element.querySelector(".window").append(el);
|
||||
|
||||
let dTE: HTMLElement = WINDOWS[windowID].element.querySelector("[data-type-area]");
|
||||
|
|
Loading…
Reference in a new issue