dotfiles

My PC Dotfiles & Website
commit b1533d2444556e9b136f9f7e4f48b0c9a5ba0690
parent 74391c5e8dd5d2342a973a27c2fa74adcd2ef25c
Author: maydayv7 <maydayv7@gmail.com>
Date:   Fri,  2 Jan 2026 19:43:44 +0530

feat(site): Improve `stagit` Site

Diffstat:

M.github/workflows/website-git.yaml | 5+----
M.github/workflows/website.yml | 1-
Mflake.lock | 6+++---
Msite/git/base.css | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msite/git/default.nix | 19++++++-------------
Msite/git/index.js | 44++++++++++++++++++++++++++++----------------
Msite/git/repos.nix | 1-
Msite/git/theme.nix | 5-----
Msite/static/js/theme.js | 64+++++++++++++++++++++++++++++++++++++++-------------------------
9 files changed, 151 insertions(+), 92 deletions(-)

diff --git a/.github/workflows/website-git.yaml b/.github/workflows/website-git.yaml @@ -28,10 +28,7 @@ jobs: - name: Build Stagit Site run: nix run .#build-stagit - name: Prepare for Deployment - run: | - rm -rf site/git/public - mkdir -p site/git/public - cp -rL public/* site/git/public/ + run: mv public site/git/public - name: Deploy to Cloudflare id: deploy uses: cloudflare/wrangler-action@v3 diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml @@ -28,7 +28,6 @@ jobs: run: nix build .#website - name: Prepare for Deployment run: | - rm -rf site/public mkdir -p site/public cp -rL result/* site/public/ - name: Deploy to Cloudflare diff --git a/flake.lock b/flake.lock @@ -747,11 +747,11 @@ ] }, "locked": { - "lastModified": 1767300315, - "narHash": "sha256-KZHyOaFrwh/IBn8wTc3tImVHwpeRi/RJtaD9kt1iNNg=", + "lastModified": 1767360683, + "narHash": "sha256-flWHlN2Wx9sSDDswFlkuUVxX2Q6PfK6FKsPf0ykbbMw=", "owner": "maydayv7", "repo": "stagit", - "rev": "6aa8a5443cec322bf8e7a09a1ff03c34f71d96af", + "rev": "af747fbf9d6a7833144e70a3089c69f934dfd0c7", "type": "github" }, "original": { diff --git a/site/git/base.css b/site/git/base.css @@ -33,33 +33,90 @@ body { a { text-decoration: none; - color: var(--fg); + color: var(--accent); &:hover { text-decoration: underline; + color: var(--secondary); } } /* Header */ -#header { - margin-bottom: 1.5rem; - text-align: left; +.header { + display: flex; + flex-direction: column; + position: relative; + margin-bottom: 2rem; + width: 100%; } -tbody td:first-child { - width: 1px; - white-space: nowrap; - padding-right: 10px; +.header-inner { + align-items: center; + display: flex; + justify-content: space-between; + width: 100%; +} + +/* Bars */ +.header-logo { + display: flex; + flex: 1; + align-items: center; } -img { - height: 32px; - width: auto; +.header-logo::after { + content: ""; + display: block; + width: 100%; + height: 40px; + margin-left: 15px; + background: linear-gradient( + 90deg, + var(--accent) 0% 12%, + transparent 12% 50%, + var(--secondary) 50% 62%, + transparent 62% + ); + background-position: left center; + background-repeat: repeat-x; + background-size: 40px 100%; +} + +/* Button */ +.header-logo a { + flex: 0 0 auto; + text-decoration: none; + font-weight: bold; + font-size: 1.2em; + color: var(--bg); + background-color: var(--accent); + padding: 5px 10px; border-radius: 3px; - vertical-align: middle; + border: 1px solid var(--border-subtle); + + &:hover { + color: var(--secondary); + text-decoration: none; + } + + &:focus { + outline: dotted 2px var(--fg); + } } -h1 { - margin: 0; +/* Repo Header */ +#repo-header { + margin-bottom: 1rem; + text-align: left; + + h1 { + margin: 0; + font-size: 1.5em; + } +} + +/* Navigation Row */ +#nav { + margin-bottom: 1rem; } /* Tables */ @@ -110,7 +167,6 @@ pre { .h { color: var(--diff-mod); } - pre span.i, pre span.d, pre span.h { @@ -152,7 +208,6 @@ pre span.h { /* Syntax Highlighting */ -/* Container Table */ table#blob.chroma { width: 100%; border-collapse: collapse; @@ -165,7 +220,6 @@ table#blob.chroma { table-layout: fixed; } -/* Cells */ #blob.chroma td { padding: 0 0.5em; vertical-align: top; @@ -173,7 +227,6 @@ table#blob.chroma { border: none; } -/* Line Numbers */ #blob.chroma td.num { width: 1%; min-width: 2.5em; @@ -185,7 +238,6 @@ table#blob.chroma { white-space: nowrap; } -/* Code Content Column */ #blob.chroma td.code { width: 100%; white-space: pre-wrap; @@ -196,14 +248,12 @@ table#blob.chroma { #blob.chroma td.num a { text-decoration: none; color: inherit; - &:hover { - color: var(--fg); - } +} +#blob.chroma td.num a:hover { + color: var(--fg); } /* Syntax Colors */ - -/* Comments */ .chroma .c, .chroma .c1, .chroma .cs, diff --git a/site/git/default.nix b/site/git/default.nix @@ -2,12 +2,13 @@ lib, pkgs, site ? "https://git.maydayv7.cc", + sitename ? "maydayv7", repos ? import ./repos.nix, }: let theme = import ./theme.nix pkgs; buildCommands = lib.concatMapStrings (repo: '' - build_repo "${repo.name}" "${repo.description}" "${repo.owner}" "${repo.url}" "${repo.logo or ""}" + build_repo "${repo.name}" "${repo.description}" "${repo.owner}" "${repo.url}" '') repos; in pkgs.writeShellApplication { @@ -16,7 +17,6 @@ pkgs.writeShellApplication { coreutils git stagit-fork - xhtml1 ]; text = '' @@ -44,11 +44,10 @@ pkgs.writeShellApplication { fi # Theme - ls $OUTPUT_DIR - cp "${theme.red}" "$OUTPUT_DIR/style.css" cp "${theme.red}" "$OUTPUT_DIR/style-red.css" cp "${theme.blue}" "$OUTPUT_DIR/style-blue.css" cp "${theme.black}" "$OUTPUT_DIR/style-black.css" + ln -sf style-red.css "$OUTPUT_DIR/style.css" # Favicon if [ -f "$FAVICON_SRC" ] @@ -66,7 +65,6 @@ pkgs.writeShellApplication { DESC=$2 OWNER=$3 URL=$4 - LOGO=$5 echo "---------------------------------------" echo "Processing $NAME..." @@ -78,14 +76,9 @@ pkgs.writeShellApplication { echo "$OWNER" > "$REPO_DIR/owner" echo "$URL" > "$REPO_DIR/url" - mkdir -p "$OUTPUT_DIR/$NAME" - if [ -n "$LOGO" ] && [ -f "$LOGO" ] - then - cp "$LOGO" "$OUTPUT_DIR/$NAME/logo.png" - fi - # Run Stagit - (cd "$OUTPUT_DIR/$NAME" && stagit -l 50 -u "$BASE_URL/$NAME" "$REPO_DIR") + mkdir -p "$OUTPUT_DIR/$NAME" + (cd "$OUTPUT_DIR/$NAME" && stagit -l 50 -n ${sitename} -u "$BASE_URL/$NAME" "$REPO_DIR") # Link Global Assets ln -sf ../style.css "$OUTPUT_DIR/$NAME/style.css" @@ -98,7 +91,7 @@ pkgs.writeShellApplication { # 4. Generate Index echo "Generating Index..." - stagit-index "$BUILD_ROOT"/*.git > "$OUTPUT_DIR/index.html" + stagit-index -n ${sitename} "$BUILD_ROOT"/*.git > "$OUTPUT_DIR/index.html" echo "Successfully built to $OUTPUT_DIR!" ''; diff --git a/site/git/index.js b/site/git/index.js @@ -1,24 +1,36 @@ export default { async fetch(request, env) { const url = new URL(request.url); - const cookie = request.headers.get("Cookie") || ""; - // Theme + // Theme Switching + const cookieHeader = request.headers.get("Cookie") || ""; + const cookies = Object.fromEntries( + cookieHeader.split(";").map((c) => c.trim().split("=")) + ); + const themeCookie = cookies["theme_color"]; if (url.pathname.endsWith("style.css")) { - let theme = "red"; - if (cookie.includes("theme=blue")) theme = "blue"; - if (cookie.includes("theme=black")) theme = "black"; - - const themeUrl = new URL(url); - themeUrl.pathname = themeUrl.pathname.replace( - "style.css", - `style-${theme}.css`, - ); - - let themeResponse = await env.ASSETS.fetch( - new Request(themeUrl, request), - ); - if (themeResponse.ok) return themeResponse; + let theme = "red"; // Default + if (themeCookie === "blue") theme = "blue"; + if (themeCookie === "black") theme = "black"; + if (theme !== "red") { + const themeUrl = new URL(url); + themeUrl.pathname = themeUrl.pathname.replace( + "style.css", + `style-${theme}.css` + ); + let themeResponse = await env.ASSETS.fetch( + new Request(themeUrl, request) + ); + if (themeResponse.ok) { + const newHeaders = new Headers(themeResponse.headers); + newHeaders.set("Vary", "Cookie"); + newHeaders.set("Cache-Control", "private, max-age=60"); + return new Response(themeResponse.body, { + ...themeResponse, + headers: newHeaders, + }); + } + } } // Serve assets diff --git a/site/git/repos.nix b/site/git/repos.nix @@ -4,6 +4,5 @@ url = "https://github.com/maydayv7/matiru"; description = "Blockchain-Based Supply Chain Transparency for Agricultural Produce"; owner = "V7"; - logo = ""; } ] diff --git a/site/git/theme.nix b/site/git/theme.nix @@ -36,11 +36,6 @@ let --diff-del: ${diffDel}; --diff-mod: ${diffMod}; } - - /* Overrides */ - body { background-color: var(--bg); color: var(--fg); } - a { color: var(--accent); } - a:hover { color: var(--secondary); } ''; in { diff --git a/site/static/js/theme.js b/site/static/js/theme.js @@ -1,6 +1,23 @@ (function (switch_theme) { - const THEME_KEY = "theme_color"; - const THEME = localStorage.getItem(THEME_KEY); + const COOKIE_NAME = "theme_color"; + function getCookie(name) { + const v = document.cookie.match("(^|;) ?" + name + "=([^;]*)(;|$)"); + return v ? v[2] : null; + } + + function setCookie(name, value) { + document.cookie = `${name}=${value}; path=/; max-age=31536000; SameSite=Lax`; + } + + function saveTheme(themeName) { + setCookie(COOKIE_NAME, themeName); + } + + function clearTheme() { + document.cookie = `${COOKIE_NAME}=; path=/; max-age=0; SameSite=Lax`; + } + + const THEME = getCookie(COOKIE_NAME); const STOP_BLINK_CSS_ID = "stop-blink"; const STYLESHEET_CLASSNAME = "stylesheet"; let previousLink = null; @@ -26,10 +43,8 @@ if (previousLink) { document.getElementsByTagName("head")[0].appendChild(previousLink); } - updateThemeSelect( - document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`)[0].id, - true, - ); + let sheets = document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`); + if (sheets.length > 0) updateThemeSelect(sheets[0].id, true); showBody(); }; @@ -47,8 +62,8 @@ link.addEventListener("error", onLinkError); if (firstLoad) { - previousLink = document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`)[0]; - removeStylesheets(); + let sheets = document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`); + if (sheets.length > 0) previousLink = sheets[0]; } saveTheme(themeName); @@ -56,18 +71,10 @@ function removeStylesheets() { document.querySelectorAll(`.${STYLESHEET_CLASSNAME}`).forEach((el) => { - el.remove(); + if (el !== previousLink) el.remove(); }); } - function saveTheme(themeName) { - localStorage.setItem(THEME_KEY, themeName); - } - - function clearTheme() { - localStorage.removeItem(THEME_KEY); - } - function hideBody() { let head = document.getElementsByTagName("head")[0]; let style = document.createElement("style"); @@ -110,15 +117,22 @@ switch_theme.init = function (url) { baseUrl = url; - if (THEME && !document.getElementById(THEME)) { - hideBody(); - changeTheme(THEME, true); - updateThemeSelect(THEME, true); + if (THEME) { + setCookie(COOKIE_NAME, THEME); + if (!document.getElementById(THEME)) { + hideBody(); + changeTheme(THEME, true); + updateThemeSelect(THEME, true); + } } + window.addEventListener("load", () => { - document.getElementById("theme-select").onchange = function () { - changeTheme(this.value); - }; + let selector = document.getElementById("theme-select"); + if (selector) { + selector.onchange = function () { + changeTheme(this.value); + }; + } }); }; -})((switch_theme = window.switch_theme || {})); +})((window.switch_theme = window.switch_theme || {}));