| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- ---
- import Layout from "../layouts/Layout.astro";
- import Taskbar from "../components/taskbar.astro";
- import App from "../components/app.astro";
- import Aboutme from "../components/aboutme.astro";
- import Redirect from "../components/redirect.astro";
- import Contact from "../components/contact.astro";
- import Pgp from "../components/pgp.astro";
- import Projects from "../components/projects.astro";
- import PastWork from "../components/pastwork.astro";
- import Duolingo from "../components/duolingo.astro";
- import GitHubGraph from "../components/githubgraph.astro";
- import NowPlaying from "../components/nowplaying.astro";
- import Ram from "../components/ram.astro";
- // Projects
- import Summize from "../components/projects/summize.astro";
- import Notion from "../components/projects/notion.astro";
- // import Imdb from "../components/projects/imdb.astro";
- import "../styles/global.css";
- import me from "../assets/apps/me.png";
- import github from "../assets/apps/github.png";
- import pastwork from "../assets/apps/pastWork.png";
- import projects from "../assets/apps/projects.png";
- import blog from "../assets/apps/blog.png";
- import contact from "../assets/apps/contact.png";
- import pgp from "../assets/apps/pgp.png";
- import Glance from "../components/projects/glance.astro";
- import ramIcon from "../assets/apps/blog.png";
- let apps = [
- {
- name: "About Me",
- logo: me.src,
- windowId: "About Me",
- row: 1,
- },
- {
- name: "Projects",
- logo: projects.src,
- windowId: "Projects ",
- row: 1,
- },
- {
- name: "Past Work",
- logo: pastwork.src,
- windowId: "Past Work",
- row: 1,
- },
- {
- name: "Git",
- logo: github.src,
- redirectUrl: "https://git.simo.ng/simo",
- row: 2,
- },
- {
- name: "RAM",
- logo: ramIcon.src,
- windowId: "ram",
- row: 2,
- },
- {
- name: "Contact",
- logo: contact.src,
- windowId: "contact",
- row: 2,
- },
- {
- name: "PGP Key",
- logo: pgp.src,
- windowId: "pgp",
- fullscreen: true,
- row: 1,
- },
- ];
- let projectsArr: project[] = [
- {
- title: "Mikro",
- id: "mikro",
- },
- {
- title: "Glance",
- id: "glance",
- },
- {
- title: "Mneme",
- id: "mneme",
- },
- ];
- const row1Items = apps.filter((item) => item.row === 1);
- const row2Items = apps.filter((item) => item.row === 2);
- ---
- <Layout title="Simo">
- <div style="width: 100%; height: calc(100vh - 3.5rem); ">
- <Pgp />
- <div style="display: flex;">
- <div
- style="height: 20rem; display: flex; flex-direction: column; align-items: flex-start;"
- >
- {row1Items.map((item) => <App {item} />)}
- </div>
- <div
- style="height: 20rem; display: flex; flex-direction: column; align-items: flex-start;"
- >
- {row2Items.map((item) => <App {item} />)}
- </div>
- </div>
- <Aboutme />
- <Redirect />
- <Contact />
- <iframe
- id="SimoSearch"
- title="SimoSearch"
- data-src="https://search.simo.ng/#embed"
- loading="lazy"
- referrerpolicy="no-referrer"
- allowfullscreen
- style="
- display: none;
- position: absolute;
- left: 62%;
- top: 10%;
- border: 0;
- outline: 0;
- background: transparent;
- "
- ></iframe>
- <Ram />
- <NowPlaying />
- <PastWork />
- <Projects projects={projectsArr} />
- <Summize />
- <Notion />
- <Glance />
- <Duolingo />
- <GitHubGraph />
- </div>
- <Taskbar />
- </Layout>
- <script define:vars={{ apps, projectsArr }}>
- let dino = `
- ██████████████
- ████░░████████████
- ██████████████████
- ██████████████████
- ██████████████████
- ████████
- ██████████████░░
- ██████
- ██ ██████████
- ██▒▒ ▒▒▒▒██████████▒▒▒▒
- ████▓▓ ██████████████ ▒▒
- ██████▒▒▒▒████████████████
- ██████████████████████████
- ██████████████████████
- ██████████████████
- ▒▒██████████████
- ▒▒██████▒▒██▓▓
- ████ ▓▓
- ██▒▒ ▓▓
- ██ ██
- `;
- console.log(dino);
- const prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
- function getWindow(id) {
- return document.getElementById(id);
- }
- function raiseUpSpec(id) {
- const target = getWindow(id);
- if (!target) return;
- const windows = Array.from(document.getElementsByClassName('window'));
- const highestIndex = windows.reduce((highest, element) => {
- const zindex = parseInt(element.style.zIndex || '0', 10);
- return Number.isFinite(zindex) && zindex > highest ? zindex : highest;
- }, 0);
- target.style.zIndex = String(highestIndex + 1);
- }
- function loadDeferredIframes(root = document) {
- const load = (iframe) => {
- if (!(iframe instanceof HTMLIFrameElement)) return;
- const src = iframe.dataset.src;
- if (src && !iframe.src) iframe.src = src;
- };
- load(root);
- if ('querySelectorAll' in root) {
- root.querySelectorAll('iframe[data-src]:not([src])').forEach(load);
- }
- }
- function showWindow(id, options = {}) {
- const windowEl = getWindow(id);
- if (!windowEl) return;
- if (options.fullscreen) windowEl.classList.add('fullscreen');
- windowEl.style.display = 'block';
- loadDeferredIframes(windowEl);
- raiseUpSpec(id);
- const focusTarget = windowEl.querySelector('button, a, input, textarea, select, [tabindex]:not([tabindex="-1"])');
- if (focusTarget instanceof HTMLElement) focusTarget.focus({ preventScroll: true });
- }
- function openRedirect(redirectUrl) {
- const redirectElement = getWindow('Redirect') || getWindow('redirect');
- if (!redirectElement || !redirectUrl) return;
- redirectElement.dataset.redirecturl = redirectUrl;
- updateRedirectMessage();
- showWindow(redirectElement.id);
- }
- function updateRedirectMessage() {
- const redirectElement = getWindow('Redirect') || getWindow('redirect');
- if (!redirectElement) return;
- const redirectUrl = redirectElement.dataset.redirecturl;
- if (!redirectUrl) return;
- const messageElement = redirectElement.querySelector('h2');
- if (messageElement) {
- messageElement.textContent = 'You are about to be redirected to ';
- const link = document.createElement('a');
- link.className = 'redirUrl';
- link.href = redirectUrl;
- link.textContent = redirectUrl.replace(/^https?:\/\//, '');
- link.style.cssText = 'cursor: pointer; color: blue; text-decoration: underline;';
- messageElement.appendChild(link);
- }
- const buttonElement = redirectElement.querySelector('#okButton');
- if (buttonElement && !buttonElement.dataset.redirectBound) {
- buttonElement.dataset.redirectBound = 'true';
- buttonElement.addEventListener('click', () => {
- const currentUrl = redirectElement.dataset.redirecturl;
- if (currentUrl) window.location.href = currentUrl;
- });
- }
- }
- function dragElement(elmnt) {
- let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
- const header = document.getElementById(elmnt.id + 'header') || elmnt;
- header.addEventListener('mousedown', dragMouseDown);
- header.addEventListener('touchstart', dragMouseDown, { passive: true });
- function dragMouseDown(e) {
- raiseUpSpec(elmnt.id);
- if (e.type === 'touchstart') {
- pos3 = e.touches[0].clientX;
- pos4 = e.touches[0].clientY;
- } else {
- pos3 = e.clientX;
- pos4 = e.clientY;
- }
- document.addEventListener('mouseup', closeDragElement);
- document.addEventListener('touchend', closeDragElement);
- document.addEventListener('mousemove', elementDrag);
- document.addEventListener('touchmove', elementDrag, { passive: false });
- }
- function elementDrag(e) {
- if (e.cancelable) e.preventDefault();
- if (e.type === 'touchmove') {
- pos1 = pos3 - e.touches[0].clientX;
- pos2 = pos4 - e.touches[0].clientY;
- pos3 = e.touches[0].clientX;
- pos4 = e.touches[0].clientY;
- } else {
- pos1 = pos3 - e.clientX;
- pos2 = pos4 - e.clientY;
- pos3 = e.clientX;
- pos4 = e.clientY;
- }
- elmnt.style.top = elmnt.offsetTop - pos2 + 'px';
- elmnt.style.left = elmnt.offsetLeft - pos1 + 'px';
- }
- function closeDragElement() {
- document.removeEventListener('mouseup', closeDragElement);
- document.removeEventListener('touchend', closeDragElement);
- document.removeEventListener('mousemove', elementDrag);
- document.removeEventListener('touchmove', elementDrag);
- }
- }
- Array.from(document.getElementsByClassName("project")).forEach((project) => {
- // Projects window uses buttons with data-project for the preview pane.
- // Skip wiring those into the legacy "open a new window" behavior.
- if (project instanceof HTMLElement && project.dataset && project.dataset.project) {
- return;
- }
- let found = projectsArr.find((i) => i.id + "item" == project.id);
- if (!found) return;
- let id = found.id;
- if (id == "pgpcord") {
- project.addEventListener("click", () => {
- setTimeout(() => {
- openRedirect("https://blog.simo.ng/articles/WIP/pgpcord");
- }, 1);
- });
- return;
- }
- project.addEventListener("click", () => {
- setTimeout(() => {
- console.log(id);
- const el = document.getElementsByClassName(id)[0];
- if (!el) return;
- showWindow(el.id);
- }, 1);
- });
- });
- Array.from(document.getElementsByClassName("window")).forEach((window) => {
- dragElement(window);
- window.querySelectorAll('.title-bar-controls button').forEach((btn) => {
- btn.addEventListener('mousedown', (e) => e.stopPropagation());
- btn.addEventListener('touchstart', (e) => e.stopPropagation());
- });
- window.addEventListener("click", () => {
- raiseUpSpec(window.id);
- });
- Array.from(document.querySelectorAll(".projectwindow a")).forEach((link) => {
- link.addEventListener("click", (e) => {
- e.preventDefault();
- openRedirect(link.href);
- });
- });
- const titleButtons = Array.from(
- window.querySelectorAll('.title-bar-controls button')
- );
- const minimizeBtn = titleButtons.find(
- (btn) => (btn.getAttribute('aria-label') || '').toLowerCase() === 'minimize'
- );
- const closeBtn = titleButtons.find(
- (btn) => (btn.getAttribute('aria-label') || '').toLowerCase() === 'close'
- );
- if (minimizeBtn) {
- minimizeBtn.addEventListener('click', () => {
- minimizeWindow(window.id);
- });
- }
- if (closeBtn) {
- closeBtn.addEventListener('click', () => {
- window.classList.add('closed');
- removeFromTaskbar(window.id);
- const onEnd = () => {
- window.classList.remove('closed');
- window.style.display = 'none';
- };
- window.addEventListener('animationend', onEnd, { once: true });
- setTimeout(() => {
- if (window.style.display !== 'none') {
- window.classList.remove('closed');
- window.style.display = 'none';
- }
- }, 250);
- });
- }
- });
- apps.forEach((app) => {
- const itemName = app.name.replace(' ', '');
- const launcher = document.getElementById(itemName);
- if (!launcher) return;
- const activate = (event) => {
- event.preventDefault();
- if (app.redirectUrl) {
- openRedirect(app.redirectUrl);
- return;
- }
- if (app.windowId) showWindow(app.windowId, { fullscreen: Boolean(app.fullscreen) });
- };
- launcher.addEventListener('click', activate);
- launcher.addEventListener('keydown', (event) => {
- if (event.key === 'Enter' || event.key === ' ') activate(event);
- });
- });
- function minimizeWindow(windowId) {
- const window = document.getElementById(windowId);
- addToTaskbar(windowId);
- const windowRect = window.getBoundingClientRect();
- const taskbarButton = document.getElementById(`taskbar-${windowId}`);
- const buttonRect = taskbarButton.getBoundingClientRect();
- const translateX = buttonRect.left - windowRect.left;
- const translateY = buttonRect.top - windowRect.top;
- if (!prefersReducedMotion) {
- window.style.transition = "all 0.3s ease-out";
- window.style.transform = `translate(${translateX}px, ${translateY}px) scale(0.1)`;
- window.style.opacity = "0";
- }
- setTimeout(() => {
- window.style.display = "none";
- window.style.transition = "";
- window.style.transform = "";
- window.style.opacity = "";
- }, prefersReducedMotion ? 0 : 300);
- }
- // Expose a tiny API for legacy components that wire their own controls.
- window.minimizeWindow = minimizeWindow;
- window.removeFromTaskbar = removeFromTaskbar;
- window.raiseUpSpec = raiseUpSpec;
- function restoreWindow(windowId) {
- const window = document.getElementById(windowId);
- const taskbarButton = document.getElementById(`taskbar-${windowId}`);
- const buttonRect = taskbarButton.getBoundingClientRect();
- const windowRect = window.getBoundingClientRect();
- const translateX = buttonRect.left - windowRect.left;
- const translateY = buttonRect.top - windowRect.top;
- if (!prefersReducedMotion) {
- window.style.transform = `translate(${translateX}px, ${translateY}px) scale(0.1)`;
- window.style.opacity = "0";
- }
- window.style.display = "block";
- removeFromTaskbar(windowId);
- raiseUpSpec(windowId);
- requestAnimationFrame(() => {
- if (prefersReducedMotion) return;
- window.style.transition = "all 0.3s ease-out";
- window.style.transform = "translate(0, 0) scale(1)";
- window.style.opacity = "1";
- setTimeout(() => {
- window.style.transition = "";
- window.style.transform = "";
- window.style.opacity = "";
- }, 300);
- });
- }
- function addToTaskbar(windowId) {
- const taskbarWindows = document.getElementById("taskbar-windows");
- if (document.getElementById(`taskbar-${windowId}`)) {
- return;
- }
- const window = document.getElementById(windowId);
- const titleBar = window.querySelector(".title-bar-text");
- const title = titleBar ? titleBar.textContent : windowId;
- const icon = "";
-
- const button = document.createElement("button");
- button.id = `taskbar-${windowId}`;
- button.style.cssText = `
- min-width: 140px;
- max-width: 180px;
- height: 2.25rem;
- padding: 0 0.5rem;
- overflow: hidden;
- cursor: pointer;
- background-color: #c0c0c0;
- box-shadow: -2px -2px #e0dede, -2px 0 #e0dede, 0 -2px #e0dede, -4px -4px white, -4px 0 white, 0 -4px white, 2px 2px #818181, 0 2px #818181, 2px 0 #818181, 2px -2px #e0dede, -2px 2px #818181, -4px 2px white, -4px 4px black, 4px 4px black, 4px 0 black, 0 4px black, 2px -4px white, 4px -4px black;
- display: flex;
- align-items: center;
- gap: 0.35rem;
- border: none;
- `;
- const iconSpan = document.createElement("span");
- iconSpan.textContent = icon;
- iconSpan.style.cssText = `
- font-size: 18px;
- flex-shrink: 0;
- line-height: 1;
- `;
- const textSpan = document.createElement("span");
- textSpan.textContent = title;
- textSpan.style.cssText = `
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- font-weight: bold;
- font-size: 11px;
- letter-spacing: 0.3px;
- `;
- button.appendChild(iconSpan);
- button.appendChild(textSpan);
- button.addEventListener("mousedown", () => {
- button.style.boxShadow = "-2px -2px #818181, -2px 0 #818181, 0 -2px #818181, -4px -4px black, -4px 0 black, 0 -4px black, 2px 2px #e0dede, 0 2px #e0dede, 2px 0 #e0dede, 2px -2px #818181, -2px 2px #e0dede, -4px 2px black, -4px 4px white, 4px 4px white, 4px 0 white, 0 4px white, 2px -4px black, 4px -4px white";
- });
- button.addEventListener("mouseup", () => {
- button.style.boxShadow = "-2px -2px #e0dede, -2px 0 #e0dede, 0 -2px #e0dede, -4px -4px white, -4px 0 white, 0 -4px white, 2px 2px #818181, 0 2px #818181, 2px 0 #818181, 2px -2px #e0dede, -2px 2px #818181, -4px 2px white, -4px 4px black, 4px 4px black, 4px 0 black, 0 4px black, 2px -4px white, 4px -4px black";
- });
- button.addEventListener("click", () => {
- restoreWindow(windowId);
- });
- taskbarWindows.appendChild(button);
- }
- function removeFromTaskbar(windowId) {
- const button = document.getElementById(`taskbar-${windowId}`);
- if (button) {
- button.remove();
- }
- }
- const startButton = document.querySelector('button[aria-label="startButton"]');
- if (startButton) {
- startButton.addEventListener('click', () => {
- const w = document.getElementById('SimoSearch');
- if (!w) return;
- loadDeferredIframes(w);
- w.style.display = 'block';
- w.style.zIndex = '9999';
- });
- }
- </script>
|