chore: remove junk

This commit is contained in:
enscribe 2024-09-10 10:36:58 -07:00
parent f6dcc302d4
commit 8f6872f739
No known key found for this signature in database
GPG key ID: 9BBD5C4114E25322
96 changed files with 1002 additions and 2485 deletions

View file

@ -1,13 +1,13 @@
---
import type { CollectionEntry } from "astro:content";
import type { CollectionEntry } from 'astro:content'
type Props = {
entry: CollectionEntry<"blog">;
};
entry: CollectionEntry<'blog'>
}
const { entry } = Astro.props as {
entry: CollectionEntry<"blog">;
};
entry: CollectionEntry<'blog'>
}
---
<a

View file

@ -1,9 +1,9 @@
---
type Props = {
href: string;
};
href: string
}
const { href } = Astro.props;
const { href } = Astro.props
---
<a

View file

@ -1,23 +1,23 @@
---
export interface Props {
institution: string;
time: string;
job_title: string;
location: string;
description: string
}
const { institution, time, job_title, location, description } = Astro.props;
institution: string
time: string
job_title: string
location: string
description: string
}
const { institution, time, job_title, location, description } = Astro.props
---
<div class="py-5 px-8">
<div class="flex justify-between text-sm font-bold md:text-lg">
<div>{institution}</div>
<div>{location}</div>
</div>
<div class="flex justify-between text-xs md:text-base">
<div class="italic">{job_title}</div>
<div>{time}</div>
</div>
<p class="text-xs mt-2">{description}</p>
</div>
<div class="px-8 py-5">
<div class="flex justify-between text-sm font-bold md:text-lg">
<div>{institution}</div>
<div>{location}</div>
</div>
<div class="flex justify-between text-xs md:text-base">
<div class="italic">{job_title}</div>
<div>{time}</div>
</div>
<p class="mt-2 text-xs">{description}</p>
</div>

View file

@ -1,18 +1,18 @@
---
interface Component {
type: "default" | "info" | "warning" | "error";
type: 'default' | 'info' | 'warning' | 'error'
}
const { type = "default" } = Astro.props;
const { type = 'default' } = Astro.props
let emoji = "💡";
let emoji = '💡'
if (type === "info") {
emoji = "";
} else if (type === "warning") {
emoji = "⚠️";
} else if (type === "error") {
emoji = "🚨";
if (type === 'info') {
emoji = ''
} else if (type === 'warning') {
emoji = '⚠️'
} else if (type === 'error') {
emoji = '🚨'
}
---

View file

@ -1,19 +1,20 @@
---
import Container from "@components/Container.astro";
import { SITE } from "@consts";
import BackToTop from "@components/BackToTop.astro";
import SocialIcons from "./SocialIcons.astro";
import Container from '@components/Container.astro'
import { SITE } from '@consts'
import BackToTop from '@components/BackToTop.astro'
import SocialIcons from './SocialIcons.astro'
---
<footer class="animate">
<Container>
<div class="flex justify-between my-2">
<div class="my-2 flex justify-between">
<SocialIcons icon_size={'text-xl'} />
<BackToTop />
</div>
<div class="flex items-center justify-between">
<div>&copy; {new Date().getFullYear()} • {SITE.TITLE} 👀<br>
Built with Astro
<div>
&copy; {new Date().getFullYear()} • {SITE.TITLE} 👀<br />
Built with Astro
</div>
<div class="flex flex-wrap items-center gap-1.5">
<button

View file

@ -1,17 +1,17 @@
---
interface Props {
date: Date;
date: Date
}
const { date } = Astro.props;
const { date } = Astro.props
---
<time datetime={date.toISOString()}>
{
date.toLocaleDateString("en-US", {
month: "long",
day: "2-digit",
year: "numeric",
date.toLocaleDateString('en-US', {
month: 'long',
day: '2-digit',
year: 'numeric',
})
}
</time>

View file

@ -1,19 +1,19 @@
---
import "../styles/global.css";
import { ViewTransitions } from "astro:transitions";
import '../styles/global.css'
import { ViewTransitions } from 'astro:transitions'
import "@fontsource/geist-sans";
import "@fontsource/geist-mono";
import '@fontsource/geist-sans'
import '@fontsource/geist-mono'
interface Props {
title: string;
description: string;
image?: string;
title: string
description: string
image?: string
}
const canonicalURL = new URL(Astro.url.pathname, Astro.site);
const canonicalURL = new URL(Astro.url.pathname, Astro.site)
const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
const { title, description, image = '/blog-placeholder-1.jpg' } = Astro.props
---
<!-- Global Metadata -->
@ -48,116 +48,112 @@ const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
<meta property="twitter:description" content={description} />
<meta property="twitter:image" content={new URL(image, Astro.url)} />
<!-- PageFind -->
<link href="/pagefind/pagefind-ui.css" rel="stylesheet" />
<script is:inline src="/pagefind/pagefind-ui.js"></script>
<ViewTransitions />
<script is:inline>
function init() {
preloadTheme();
onScroll();
animate();
updateThemeButtons();
addCopyCodeButtons();
setGiscusTheme();
preloadTheme()
onScroll()
animate()
updateThemeButtons()
addCopyCodeButtons()
setGiscusTheme()
const backToTop = document.getElementById("back-to-top");
backToTop?.addEventListener("click", (event) => scrollToTop(event));
const backToTop = document.getElementById('back-to-top')
backToTop?.addEventListener('click', (event) => scrollToTop(event))
const backToPrev = document.getElementById("back-to-prev");
backToPrev?.addEventListener("click", () => window.history.back());
const backToPrev = document.getElementById('back-to-prev')
backToPrev?.addEventListener('click', () => window.history.back())
const lightThemeButton = document.getElementById("light-theme-button");
lightThemeButton?.addEventListener("click", () => {
localStorage.setItem("theme", "light");
toggleTheme(false);
updateThemeButtons();
});
const lightThemeButton = document.getElementById('light-theme-button')
lightThemeButton?.addEventListener('click', () => {
localStorage.setItem('theme', 'light')
toggleTheme(false)
updateThemeButtons()
})
const darkThemeButton = document.getElementById("dark-theme-button");
darkThemeButton?.addEventListener("click", () => {
localStorage.setItem("theme", "dark");
toggleTheme(true);
updateThemeButtons();
});
const darkThemeButton = document.getElementById('dark-theme-button')
darkThemeButton?.addEventListener('click', () => {
localStorage.setItem('theme', 'dark')
toggleTheme(true)
updateThemeButtons()
})
const systemThemeButton = document.getElementById("system-theme-button");
systemThemeButton?.addEventListener("click", () => {
localStorage.setItem("theme", "system");
toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
updateThemeButtons();
});
const systemThemeButton = document.getElementById('system-theme-button')
systemThemeButton?.addEventListener('click', () => {
localStorage.setItem('theme', 'system')
toggleTheme(window.matchMedia('(prefers-color-scheme: dark)').matches)
updateThemeButtons()
})
window
.matchMedia("(prefers-color-scheme: dark)")
.addEventListener("change", (event) => {
if (localStorage.theme === "system") {
toggleTheme(event.matches);
.matchMedia('(prefers-color-scheme: dark)')
.addEventListener('change', (event) => {
if (localStorage.theme === 'system') {
toggleTheme(event.matches)
}
});
})
document.addEventListener("scroll", onScroll);
document.addEventListener('scroll', onScroll)
}
function updateThemeButtons() {
const theme = localStorage.getItem("theme");
const lightThemeButton = document.getElementById("light-theme-button");
const darkThemeButton = document.getElementById("dark-theme-button");
const systemThemeButton = document.getElementById("system-theme-button");
const theme = localStorage.getItem('theme')
const lightThemeButton = document.getElementById('light-theme-button')
const darkThemeButton = document.getElementById('dark-theme-button')
const systemThemeButton = document.getElementById('system-theme-button')
function removeActiveButtonTheme(button) {
button?.classList.remove("bg-black/5");
button?.classList.remove("dark:bg-white/5");
button?.classList.remove('bg-black/5')
button?.classList.remove('dark:bg-white/5')
}
function addActiveButtonTheme(button) {
button?.classList.add("bg-black/5");
button?.classList.add("dark:bg-white/5");
button?.classList.add('bg-black/5')
button?.classList.add('dark:bg-white/5')
}
removeActiveButtonTheme(lightThemeButton);
removeActiveButtonTheme(darkThemeButton);
removeActiveButtonTheme(systemThemeButton);
removeActiveButtonTheme(lightThemeButton)
removeActiveButtonTheme(darkThemeButton)
removeActiveButtonTheme(systemThemeButton)
if (theme === "light") {
addActiveButtonTheme(lightThemeButton);
} else if (theme === "dark") {
addActiveButtonTheme(darkThemeButton);
if (theme === 'light') {
addActiveButtonTheme(lightThemeButton)
} else if (theme === 'dark') {
addActiveButtonTheme(darkThemeButton)
} else {
addActiveButtonTheme(systemThemeButton);
addActiveButtonTheme(systemThemeButton)
}
}
function animate() {
const animateElements = document.querySelectorAll(".animate");
const animateElements = document.querySelectorAll('.animate')
animateElements.forEach((element, index) => {
setTimeout(() => {
element.classList.add("show");
}, index * 100);
});
element.classList.add('show')
}, index * 100)
})
}
function onScroll() {
if (window.scrollY > 0) {
document.documentElement.classList.add("scrolled");
document.documentElement.classList.add('scrolled')
} else {
document.documentElement.classList.remove("scrolled");
document.documentElement.classList.remove('scrolled')
}
}
function scrollToTop(event) {
event.preventDefault();
event.preventDefault()
window.scrollTo({
top: 0,
behavior: "smooth",
});
behavior: 'smooth',
})
}
function toggleTheme(dark) {
const css = document.createElement("style");
const css = document.createElement('style')
css.appendChild(
document.createTextNode(
@ -168,84 +164,84 @@ const { title, description, image = "/blog-placeholder-1.jpg" } = Astro.props;
-ms-transition: none !important;
transition: none !important;
}
`
)
);
`,
),
)
document.head.appendChild(css);
document.head.appendChild(css)
if (dark) {
document.documentElement.classList.add("dark");
document.documentElement.classList.add('dark')
} else {
document.documentElement.classList.remove("dark");
document.documentElement.classList.remove('dark')
}
window.getComputedStyle(css).opacity;
document.head.removeChild(css);
window.getComputedStyle(css).opacity
document.head.removeChild(css)
setGiscusTheme();
setGiscusTheme()
}
function preloadTheme() {
const userTheme = localStorage.theme;
const userTheme = localStorage.theme
if (userTheme === "light" || userTheme === "dark") {
toggleTheme(true); // set default to dark theme
if (userTheme === 'light' || userTheme === 'dark') {
toggleTheme(true) // set default to dark theme
} else {
toggleTheme(window.matchMedia("(prefers-color-scheme: dark)").matches);
toggleTheme(window.matchMedia('(prefers-color-scheme: dark)').matches)
}
}
function addCopyCodeButtons() {
let copyButtonLabel = "📋";
let codeBlocks = Array.from(document.querySelectorAll("pre"));
let copyButtonLabel = '📋'
let codeBlocks = Array.from(document.querySelectorAll('pre'))
async function copyCode(codeBlock, copyButton) {
const codeText = codeBlock.innerText;
const buttonText = copyButton.innerText;
const textToCopy = codeText.replace(buttonText, "");
const codeText = codeBlock.innerText
const buttonText = copyButton.innerText
const textToCopy = codeText.replace(buttonText, '')
await navigator.clipboard.writeText(textToCopy);
copyButton.innerText = "✅";
await navigator.clipboard.writeText(textToCopy)
copyButton.innerText = '✅'
setTimeout(() => {
copyButton.innerText = copyButtonLabel;
}, 2000);
copyButton.innerText = copyButtonLabel
}, 2000)
}
for (let codeBlock of codeBlocks) {
const wrapper = document.createElement("div");
wrapper.style.position = "relative";
const wrapper = document.createElement('div')
wrapper.style.position = 'relative'
const copyButton = document.createElement("button");
copyButton.innerText = copyButtonLabel;
copyButton.classList = "copy-code";
const copyButton = document.createElement('button')
copyButton.innerText = copyButtonLabel
copyButton.classList = 'copy-code'
codeBlock.setAttribute("tabindex", "0");
codeBlock.appendChild(copyButton);
codeBlock.setAttribute('tabindex', '0')
codeBlock.appendChild(copyButton)
codeBlock.parentNode.insertBefore(wrapper, codeBlock);
wrapper.appendChild(codeBlock);
codeBlock.parentNode.insertBefore(wrapper, codeBlock)
wrapper.appendChild(codeBlock)
copyButton?.addEventListener("click", async () => {
await copyCode(codeBlock, copyButton);
});
copyButton?.addEventListener('click', async () => {
await copyCode(codeBlock, copyButton)
})
}
}
const setGiscusTheme = () => {
const giscus = document.querySelector(".giscus-frame");
const giscus = document.querySelector('.giscus-frame')
const isDark = document.documentElement.classList.contains("dark");
const isDark = document.documentElement.classList.contains('dark')
if (giscus) {
const url = new URL(giscus.src);
url.searchParams.set("theme", isDark ? "dark" : "light");
giscus.src = url.toString();
const url = new URL(giscus.src)
url.searchParams.set('theme', isDark ? 'dark' : 'light')
giscus.src = url.toString()
}
};
}
document.addEventListener("DOMContentLoaded", () => init());
document.addEventListener("astro:after-swap", () => init());
preloadTheme();
document.addEventListener('DOMContentLoaded', () => init())
document.addEventListener('astro:after-swap', () => init())
preloadTheme()
</script>

View file

@ -1,8 +1,8 @@
---
import Container from "@components/Container.astro";
import Link from "@components/Link.astro";
import { SITE } from "@consts";
import ProgressBar from "./ProgressBar.astro";
import Container from '@components/Container.astro'
import Link from '@components/Link.astro'
import { SITE } from '@consts'
import ProgressBar from './ProgressBar.astro'
---
<header transition:persist>

View file

@ -1,29 +1,23 @@
---
import { cn } from "@lib/utils";
import { cn } from '@lib/utils'
type Props = {
href: string;
external?: boolean;
underline?: boolean;
group?: boolean;
};
href: string
external?: boolean
underline?: boolean
group?: boolean
}
const {
href,
external,
underline = true,
group = false,
...rest
} = Astro.props;
const { href, external, underline = true, group = false, ...rest } = Astro.props
---
<a
href={href}
target={external ? "_blank" : "_self"}
target={external ? '_blank' : '_self'}
class={cn(
"inline-block decoration-black/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:decoration-white/30 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out",
underline && "underline underline-offset-[3px]",
group && "group"
'inline-block decoration-black/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:decoration-white/30 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out',
underline && 'underline underline-offset-[3px]',
group && 'group',
)}
{...rest}
>

View file

@ -1,132 +0,0 @@
---
import Search from "astro-pagefind/components/Search";
---
<aside data-pagefind-ignore>
<div
transition:persist
id="backdrop"
class="bg-[rgba(0, 0, 0, 0.5] invisible fixed left-0 top-0 z-50 flex h-screen w-full justify-center p-6 backdrop-blur-sm"
>
<div
id="pagefind-container"
class="m-0 flex h-fit max-h-[80%] w-full max-w-screen-sm flex-col overflow-auto rounded border border-black/15 bg-neutral-100 p-2 px-4 py-3 shadow-lg dark:border-white/20 dark:bg-neutral-900"
>
<Search
id="search"
className="pagefind-ui"
uiOptions={{
showImages: false,
excerptLength: 15,
resetStyles: false,
}}
/>
<div class="mr-2 pb-1 pt-4 text-right text-xs dark:prose-invert">
Press <span class="prose text-xs dark:prose-invert"
><kbd class="">Esc</kbd></span
> or click anywhere to close
</div>
</div>
</div>
</aside>
<script is:inline>
const magnifyingGlass = document.getElementById("magnifying-glass");
const backdrop = document.getElementById("backdrop");
function openPagefind() {
const searchDiv = document.getElementById("search");
const search = searchDiv.querySelector("input");
setTimeout(() => {
search.focus();
}, 0);
backdrop?.classList.remove("invisible");
backdrop?.classList.add("visible");
}
function closePagefind() {
const search = document.getElementById("search");
search.value = "";
backdrop?.classList.remove("visible");
backdrop?.classList.add("invisible");
}
// open pagefind
magnifyingGlass?.addEventListener("click", () => {
openPagefind();
});
document.addEventListener("keydown", (e) => {
if (e.key === "/") {
e.preventDefault();
openPagefind();
} else if ((e.metaKey || e.ctrlKey) && e.key === "k") {
e.preventDefault();
openPagefind();
}
});
// close pagefind
document.addEventListener("keydown", (e) => {
if (e.key === "Escape" || e.keyCode === 27) {
closePagefind();
}
});
// close pagefind when searched result(link) clicked
document.addEventListener("click", (event) => {
if (event.target.classList.contains("pagefind-ui__result-link")) {
closePagefind();
}
});
backdrop?.addEventListener("click", (event) => {
if (!event.target.closest("#pagefind-container")) {
closePagefind();
}
});
// prevent form submission
const form = document.getElementById("form");
form?.addEventListener("submit", (event) => {
event.preventDefault();
});
</script>
<style is:global>
:root {
--pagefind-ui-scale: 0.75;
--pagefind-ui-border-width: 1px;
--pagefind-ui-border-radius: 3px;
--pagefind-ui-font: "Geist", sans-serif;
--pagefind-ui-primary: #3d3d3d;
--pagefind-ui-text: #3d3d3d;
--pagefind-ui-background: #ffffff;
--pagefind-ui-border: #d0d0d0;
--pagefind-ui-tag: #f5f5f5;
}
.dark {
--pagefind-ui-primary: #d4d4d4;
--pagefind-ui-text: #d4d4d4;
--pagefind-ui-background: #171717;
--pagefind-ui-border: #404040;
}
#search input {
font-weight: normal;
}
#search p {
font-weight: normal;
}
#search .pagefind-ui__result-title {
font-weight: 600;
}
#search .pagefind-ui__message {
padding: 0;
padding-bottom: 0.75rem;
}
</style>

View file

@ -1,5 +1,5 @@
---
const { prevPost, nextPost } = Astro.props;
const { prevPost, nextPost } = Astro.props
---
<div class="grid grid-cols-2 gap-1.5 sm:gap-3">

View file

@ -1,9 +1,8 @@
<div class="fixed w-full h-[2px] bg-neutral-300 dark:bg-slate-900 z-50">
<div class="bg-cyan-500 dark:bg-orange-500 h-full"></div>
<div class="fixed z-50 h-[2px] w-full bg-neutral-300 dark:bg-slate-900">
<div class="h-full bg-cyan-500 dark:bg-orange-500"></div>
</div>
<script>
import { initializeProgressBar } from '../scripts/progress-bar.js';
initializeProgressBar();
import { initializeProgressBar } from '../scripts/progress-bar.js'
initializeProgressBar()
</script>

View file

@ -1,74 +1,118 @@
---
import type { CollectionEntry } from "astro:content";
import { Image } from "astro:assets";
import { HIGHLIGHTAUTHOR } from "@consts";
import type { CollectionEntry } from 'astro:content'
import { Image } from 'astro:assets'
import { HIGHLIGHTAUTHOR } from '@consts'
type Props = {
entry: CollectionEntry<"publications">;
};
entry: CollectionEntry<'publications'>
}
const { entry } = Astro.props as {
entry: CollectionEntry<"publications">;
};
entry: CollectionEntry<'publications'>
}
const splitStr = (authors: string | undefined, targetAuthor: string) => {
if (!authors) return [];
const parts = authors.split(new RegExp(`(${targetAuthor})`, 'g'));
return parts;
};
if (!authors) return []
const parts = authors.split(new RegExp(`(${targetAuthor})`, 'g'))
return parts
}
const decomposeURL = (URL: string | undefined) => {
if (!URL) return { text: '', url: '' };
const parts = URL.split(": ");
return { text: parts[0], url: parts[1] };
};
const dataLink = decomposeURL(entry.data.dataURL);
const paperLink = decomposeURL(entry.data.paperURL);
const codeLink = decomposeURL(entry.data.codeURL);
const webLink = decomposeURL(entry.data.webURL);
const authorsParts = splitStr(entry.data.authors, HIGHLIGHTAUTHOR);
if (!URL) return { text: '', url: '' }
const parts = URL.split(': ')
return { text: parts[0], url: parts[1] }
}
const dataLink = decomposeURL(entry.data.dataURL)
const paperLink = decomposeURL(entry.data.paperURL)
const codeLink = decomposeURL(entry.data.codeURL)
const webLink = decomposeURL(entry.data.webURL)
const authorsParts = splitStr(entry.data.authors, HIGHLIGHTAUTHOR)
---
<div
class="w-full not-prose group relative grid grid-cols-auto md:grid-cols-[204px_auto] gap-4 rounded-lg items-center border border-black/15 px-4 py-3 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white"
class="not-prose grid-cols-auto group relative grid w-full items-center gap-4 rounded-lg border border-black/15 px-4 py-3 transition-colors duration-300 ease-in-out hover:bg-black/5 hover:text-black focus-visible:bg-black/5 focus-visible:text-black dark:border-white/20 dark:hover:bg-white/5 dark:hover:text-white dark:focus-visible:bg-white/5 dark:focus-visible:text-white md:grid-cols-[204px_auto]"
>
<Image
src={entry.data.img ?? ''}
alt={entry.data.imgAlt ?? ''}
width={640}
height={480}
class="sm:w-[240px] sm:h-[135px] shadow-sm rounded-md sm:mr-6 hover:opacity-80 transition hidden md:flex"
loading="eager"
src={entry.data.img ?? ''}
alt={entry.data.imgAlt ?? ''}
width={640}
height={480}
class="hidden rounded-md shadow-sm transition hover:opacity-80 sm:mr-6 sm:h-[135px] sm:w-[240px] md:flex"
loading="eager"
/>
<div class="flex items-center h-full">
<div class="flex h-full items-center">
<div class="flex flex-col">
<div class="w-full">
<div class="text-md font-semibold w-full">
<div class="text-md w-full font-semibold">
{entry.data.title}
</div>
<div class="text-sm w-full">
{authorsParts.map((part:any) =>
part === HIGHLIGHTAUTHOR ? <u><strong>{part}</strong></u> : part
)}
<div class="w-full text-sm">
{
authorsParts.map((part: any) =>
part === HIGHLIGHTAUTHOR ? (
<u>
<strong>{part}</strong>
</u>
) : (
part
),
)
}
</div>
<div class="text-sm w-full">
{paperLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={paperLink.url}>{paperLink.text}</a>}
{codeLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={codeLink.url}>{codeLink.text}</a>}
{webLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={webLink.url}>{webLink.text}</a>}
{dataLink.url!="" && <a class="underline hover:text-cyan-500 text-orange-500 dark:hover:text-cyan-500 transition-colors duration-300 ease-in-out visited:text-indigo-400" target="_blank" href={dataLink.url}>{dataLink.text}</a>}
<div class="w-full text-sm">
{
paperLink.url != '' && (
<a
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
target="_blank"
href={paperLink.url}
>
{paperLink.text}
</a>
)
}
{
codeLink.url != '' && (
<a
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
target="_blank"
href={codeLink.url}
>
{codeLink.text}
</a>
)
}
{
webLink.url != '' && (
<a
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
target="_blank"
href={webLink.url}
>
{webLink.text}
</a>
)
}
{
dataLink.url != '' && (
<a
class="text-orange-500 underline transition-colors duration-300 ease-in-out visited:text-indigo-400 hover:text-cyan-500 dark:hover:text-cyan-500"
target="_blank"
href={dataLink.url}
>
{dataLink.text}
</a>
)
}
</div>
<div class="text-sm">
In <div class="inline italic">{entry.data.pub}</div>
</div>
</div>
<p class="text-sm mt-2 break-words">
<p class="mt-2 break-words text-sm">
{entry.data.description}
</p>
</div>
</div>
</div>

View file

@ -1,18 +1,19 @@
---
import 'bootstrap-icons/font/bootstrap-icons.css';
import 'bootstrap-icons/font/bootstrap-icons.css'
export interface Props {
URL: string;
icon: string;
icon_size: string
URL: string
icon: string
icon_size: string
}
const { URL, icon, icon_size } = Astro.props;
const { URL, icon, icon_size } = Astro.props
---
<a
href={URL}
target={"_blank"}
class={
`inline-block ${icon_size} decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out`}>
<i class={`bi bi-${icon}`}></i>
</a>
href={URL}
target={'_blank'}
class={`inline-block ${icon_size} decoration-black/30 dark:decoration-white/30 hover:decoration-black/50 focus-visible:decoration-black/50 dark:hover:decoration-white/50 dark:focus-visible:decoration-white/50 text-current hover:text-cyan-500 focus-visible:text-black dark:hover:text-orange-500 dark:focus-visible:text-white transition-colors duration-300 ease-in-out`}
>
<i class={`bi bi-${icon}`}></i>
</a>

View file

@ -1,18 +1,23 @@
---
import SocialIcon from "@components/SocialIcon.astro";
import { SITE } from "@consts";
import SocialIcon from '@components/SocialIcon.astro'
import { SITE } from '@consts'
export interface Props {
icon_size: string
icon_size: string
}
const { icon_size } = Astro.props;
const { icon_size } = Astro.props
---
<ul class="not-prose flex flex-wrap gap-2">
<SocialIcon icon_size={icon_size} URL="#" icon="twitter-x"/>
<SocialIcon icon_size={icon_size} URL="#" icon="github"/>
<SocialIcon icon_size={icon_size} URL="#" icon="linkedin"/>
<SocialIcon icon_size={icon_size} URL="#" icon="envelope-fill"/>
<SocialIcon icon_size={icon_size} URL="#" icon="mortarboard-fill"/>
<SocialIcon icon_size={icon_size} URL={`${SITE.SITEURL}/rss.xml`} icon="rss-fill"/>
</ul>
<SocialIcon icon_size={icon_size} URL="#" icon="twitter-x" />
<SocialIcon icon_size={icon_size} URL="#" icon="github" />
<SocialIcon icon_size={icon_size} URL="#" icon="linkedin" />
<SocialIcon icon_size={icon_size} URL="#" icon="envelope-fill" />
<SocialIcon icon_size={icon_size} URL="#" icon="mortarboard-fill" />
<SocialIcon
icon_size={icon_size}
URL={`${SITE.SITEURL}/rss.xml`}
icon="rss-fill"
/>
</ul>

View file

@ -1,29 +1,29 @@
---
import TableOfContentsHeading from "./TableOfContentsHeading.astro";
import TableOfContentsHeading from './TableOfContentsHeading.astro'
// https://kld.dev/building-table-of-contents/
const { headings } = Astro.props;
const toc = buildToc(headings);
const { headings } = Astro.props
const toc = buildToc(headings)
export interface Heading {
depth: number;
slug: string;
text: string;
depth: number
slug: string
text: string
}
function buildToc(headings: Heading[]) {
const toc: Heading[] = [];
const parentHeadings = new Map();
const toc: Heading[] = []
const parentHeadings = new Map()
headings.forEach((h) => {
const heading = { ...h, subheadings: [] };
parentHeadings.set(heading.depth, heading);
const heading = { ...h, subheadings: [] }
parentHeadings.set(heading.depth, heading)
if (heading.depth === 2) {
toc.push(heading);
toc.push(heading)
} else {
parentHeadings.get(heading.depth - 1).subheadings.push(heading);
parentHeadings.get(heading.depth - 1).subheadings.push(heading)
}
});
return toc;
})
return toc
}
---

View file

@ -1,14 +1,14 @@
---
import type { Heading } from "./TableOfContents.astro";
import Link from "./Link.astro";
import type { Heading } from './TableOfContents.astro'
import Link from './Link.astro'
// https://kld.dev/building-table-of-contents/
const { heading } = Astro.props;
const { heading } = Astro.props
---
<li class="list-inside list-disc px-6 py-1.5 text-sm">
<Link href={"#" + heading.slug} underline>
<Link href={'#' + heading.slug} underline>
{heading.text}
</Link>
{