feat: final refactor for port

This commit is contained in:
Barrett Ruth 2025-05-22 18:51:58 -05:00
parent cd9bd06eef
commit c08e4ce9d5
4 changed files with 131 additions and 140 deletions

128
public/scripts/index.js Normal file
View file

@ -0,0 +1,128 @@
import { getTopicColor } from "../../src/utils/colors.js";
const TERMINAL_PROMPT = "barrett@ruth:~$ ";
let typing = false;
let clearing = false;
function clearPrompt(delay, callback) {
if (clearing) return;
clearing = true;
const terminalPrompt = document.querySelector(".terminal-prompt");
if (!terminalPrompt) {
clearing = false;
return;
}
const topicLength =
terminalPrompt.innerHTML.length - TERMINAL_PROMPT.length;
let i = 0;
function removeChar() {
if (i++ < topicLength) {
terminalPrompt.textContent = terminalPrompt.textContent.slice(0, -1);
setTimeout(removeChar, delay / topicLength);
} else {
i = 0;
clearing = false;
callback && callback();
}
}
removeChar();
}
function typechars(e) {
e.preventDefault();
const topicElement = e.target;
if (topicElement.classList.contains("active")) return;
if (typing) return;
typing = true;
const topic = topicElement.dataset.topic;
const terminalText = ` /${topic.toLowerCase()}`;
const terminalPrompt = document.querySelector(".terminal-prompt");
const delay =
terminalPrompt.innerHTML.length > TERMINAL_PROMPT.length ? 250 : 500;
const topics = document.querySelectorAll(".topic a");
topics.forEach((t) => {
t.classList.remove("active");
t.style.color = "";
});
topicElement.classList.add("active");
topicElement.style.color = getTopicColor(topic);
clearPrompt(delay, () => {
let i = 0;
function typechar() {
if (i < terminalText.length) {
terminalPrompt.innerHTML += terminalText.charAt(i++);
setTimeout(typechar, delay / terminalText.length);
} else {
renderPosts(topic);
typing = false;
}
}
typechar();
});
}
function renderPosts(topic) {
const posts = document.getElementById("posts");
posts.innerHTML = "";
const categoryPosts = postsByCategory[topic];
if (!categoryPosts) {
return;
}
categoryPosts.forEach((post) => {
const postDiv = document.createElement("div");
postDiv.classList.add("post");
const link = document.createElement("a");
const slug = post.id
.split("/")
.pop()
.replace(/\.mdx?$/, "");
link.href = `/posts/${topic}/${slug}.html`;
link.textContent = post.data.title;
link.style.textDecoration = "underline";
postDiv.appendChild(link);
posts.appendChild(postDiv);
});
}
document.addEventListener("DOMContentLoaded", function () {
const topics = document.querySelectorAll(".topic a");
topics.forEach((topic) => {
topic.addEventListener("click", typechars);
const topicName = topic.dataset.topic;
topic.addEventListener("mouseenter", () => {
const color = getTopicColor(topicName);
topic.style.color = color;
});
topic.addEventListener("mouseleave", () => {
if (!topic.classList.contains("active")) {
topic.style.color = "";
}
});
});
window.addEventListener("beforeunload", () => {
const terminalPrompt = document.querySelector(".terminal-prompt");
if (terminalPrompt) {
terminalPrompt.innerHTML = TERMINAL_PROMPT;
}
});
});

View file

@ -55,7 +55,7 @@ const topicColor = getTopicColor(category);
</div>
<slot name="scripts" slot="scripts">
<script src="/scripts/dateHeadings.js" is:inline></script>
<script src="/scripts/centerKatex.js" is:inline></script>
{frontmatter.scripts?.map(script => (
<script src={script} type="module"></script>
))}

View file

@ -48,144 +48,7 @@ Object.keys(postsByCategory).forEach((category) => {
</div>
<script slot="scripts" define:vars={{ postsByCategory }}>
function getTopicColor(topicName) {
switch (topicName) {
case "software":
return "#0073e6";
case "algorithms":
return "#d50032";
case "meditations":
return "#6a0dad";
default:
return "#000000";
}
}
const TERMINAL_PROMPT = "barrett@ruth:~$ ";
let typing = false;
let clearing = false;
function clearPrompt(delay, callback) {
if (clearing) return;
clearing = true;
const terminalPrompt = document.querySelector(".terminal-prompt");
if (!terminalPrompt) {
clearing = false;
return;
}
const topicLength =
terminalPrompt.innerHTML.length - TERMINAL_PROMPT.length;
let i = 0;
function removeChar() {
if (i++ < topicLength) {
terminalPrompt.textContent = terminalPrompt.textContent.slice(0, -1);
setTimeout(removeChar, delay / topicLength);
} else {
i = 0;
clearing = false;
callback && callback();
}
}
removeChar();
}
function typechars(e) {
e.preventDefault();
const topicElement = e.target;
if (topicElement.classList.contains("active")) return;
if (typing) return;
typing = true;
const topic = topicElement.dataset.topic;
const terminalText = ` /${topic.toLowerCase()}`;
const terminalPrompt = document.querySelector(".terminal-prompt");
const delay =
terminalPrompt.innerHTML.length > TERMINAL_PROMPT.length ? 250 : 500;
const topics = document.querySelectorAll(".topic a");
topics.forEach((t) => {
t.classList.remove("active");
t.style.color = "";
});
topicElement.classList.add("active");
topicElement.style.color = getTopicColor(topic);
clearPrompt(delay, () => {
let i = 0;
function typechar() {
if (i < terminalText.length) {
terminalPrompt.innerHTML += terminalText.charAt(i++);
setTimeout(typechar, delay / terminalText.length);
} else {
renderPosts(topic);
typing = false;
}
}
typechar();
});
}
function renderPosts(topic) {
const posts = document.getElementById("posts");
posts.innerHTML = "";
const categoryPosts = postsByCategory[topic];
if (!categoryPosts) {
return;
}
categoryPosts.forEach((post) => {
const postDiv = document.createElement("div");
postDiv.classList.add("post");
const link = document.createElement("a");
const slug = post.id
.split("/")
.pop()
.replace(/\.mdx?$/, "");
link.href = `/posts/${topic}/${slug}.html`;
link.textContent = post.data.title;
link.style.textDecoration = "underline";
postDiv.appendChild(link);
posts.appendChild(postDiv);
});
}
document.addEventListener("DOMContentLoaded", function () {
const topics = document.querySelectorAll(".topic a");
topics.forEach((topic) => {
topic.addEventListener("click", typechars);
const topicName = topic.dataset.topic;
topic.addEventListener("mouseenter", () => {
const color = getTopicColor(topicName);
topic.style.color = color;
});
topic.addEventListener("mouseleave", () => {
if (!topic.classList.contains("active")) {
topic.style.color = "";
}
});
});
window.addEventListener("beforeunload", () => {
const terminalPrompt = document.querySelector(".terminal-prompt");
if (terminalPrompt) {
terminalPrompt.innerHTML = TERMINAL_PROMPT;
}
});
});
window.postsByCategory = postsByCategory;
</script>
<script slot="scripts" type="module" src="/scripts/index.js"></script>
</BaseLayout>