diff options
Diffstat (limited to 'src/pages')
| -rw-r--r-- | src/pages/index.astro | 40 | ||||
| -rw-r--r-- | src/pages/posts/[slug].astro | 19 | ||||
| -rw-r--r-- | src/pages/posts/feed.xml.ts | 21 | ||||
| -rw-r--r-- | src/pages/posts/index.astro | 90 | ||||
| -rw-r--r-- | src/pages/reading.astro | 60 | ||||
| -rw-r--r-- | src/pages/resume.astro | 272 | ||||
| -rw-r--r-- | src/pages/tech.astro | 51 |
7 files changed, 553 insertions, 0 deletions
diff --git a/src/pages/index.astro b/src/pages/index.astro new file mode 100644 index 0000000..d6e47c5 --- /dev/null +++ b/src/pages/index.astro @@ -0,0 +1,40 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import OpenMoji from '../components/OpenMoji.astro'; +--- + +<BaseLayout title="Matthew Kosarek" description="The personal website of Matthew Kosarek"> + <div class="index-layout"> + <div class="index-main"> + <section> + <p> + Hi there <OpenMoji code="1F30A" alt="wave" /> + </p> + <p> + My name is Matthew Kosarek. + I am a computer programmer from northern New Jersey and I currently live in Philadelphia, PA. I work at Canonical on + <a href="https://github.com/canonical/mir">Mir</a> and <a href="https://github.com/flutter/flutter">Flutter</a>. I + have a strong interest in C++, Computer Graphics, Rust, and Linux. + <p/> + <p> + In my spare time, I work on <a href="https://github.com/miracle-wm-org/miracle-wm">miracle-wm</a>, a Mir-based + window manager that features manual tiling and a WebAssembly-powered plugin system for window management and beyond. + </p> + <p> + Off the computer, you can find me surfing, walking my dog, or hanging out with my fiancee and friends in Philly. I + also have 3 cats! + </p> + </section> + </div> + + <aside class="sidebar"> + <ul> + <li><a href="https://github.com/mattkae">Github</a><span>my personal github with most of my projects</span></li> + <li><a href="https://git.matthewkosarek.xyz">CGit</a><span>my self-hosted git instance with a few of my projects</span></li> + <li style="display: none;"><a href="https://physicsforgames.com">physicsforgames.com</a><span>a project that I'm currently working on in my spare time where I explore the world of realtime physics</span></li> + <li><a href="https://www.linkedin.com/in/matthew-kosarek/">LinkedIn</a><span>corporate goings-ons</span></li> + <li><a href="mailto:matthew@matthewkosarek.xyz">Email</a><span>matthew@matthewkosarek.xyz</span></li> + </ul> + </aside> + </div> +</BaseLayout> diff --git a/src/pages/posts/[slug].astro b/src/pages/posts/[slug].astro new file mode 100644 index 0000000..0f29ec5 --- /dev/null +++ b/src/pages/posts/[slug].astro @@ -0,0 +1,19 @@ +--- +import { getCollection, type CollectionEntry } from 'astro:content'; +import PostLayout from '../../layouts/PostLayout.astro'; + +export async function getStaticPaths() { + const posts = await getCollection('posts'); + return posts.map((post: CollectionEntry<'posts'>) => ({ + params: { slug: post.slug }, + props: { post }, + })); +} + +const { post } = Astro.props as { post: CollectionEntry<'posts'> }; +const { Content } = await post.render(); +--- + +<PostLayout title={post.data.title}> + <Content /> +</PostLayout> diff --git a/src/pages/posts/feed.xml.ts b/src/pages/posts/feed.xml.ts new file mode 100644 index 0000000..43b9b84 --- /dev/null +++ b/src/pages/posts/feed.xml.ts @@ -0,0 +1,21 @@ +import rss from '@astrojs/rss'; +import { getCollection } from 'astro:content'; +import { marked } from 'marked'; +import type { APIContext } from 'astro'; + +export async function GET(context: APIContext) { + const posts = await getCollection('posts'); + posts.sort((a, b) => b.data.date.localeCompare(a.data.date)); + + return rss({ + title: "Matthew Kosarek's Blog", + description: 'Updates and thoughts from Matthew Kosarek', + site: context.site ?? 'https://matthewkosarek.xyz', + items: posts.map(post => ({ + title: post.data.title, + pubDate: new Date(post.data.date), + link: `/posts/${post.slug}/`, + content: marked(post.body) as string, + })), + }); +} diff --git a/src/pages/posts/index.astro b/src/pages/posts/index.astro new file mode 100644 index 0000000..447384c --- /dev/null +++ b/src/pages/posts/index.astro @@ -0,0 +1,90 @@ +--- +import { getCollection, type CollectionEntry } from 'astro:content'; +import BaseLayout from '../../layouts/BaseLayout.astro'; +import '../../styles/post.css'; +import '../../styles/sitemap.css'; + +const allPosts = await getCollection('posts'); +allPosts.sort((a: CollectionEntry<'posts'>, b: CollectionEntry<'posts'>) => b.data.date.localeCompare(a.data.date)); + +function formatDate(dateStr: string): string { + const [year, month, day] = dateStr.split('-').map(Number); + const d = new Date(year, month - 1, day); + return d.toLocaleDateString('en-US', { month: 'long', day: '2-digit', year: 'numeric' }); +} +--- + +<BaseLayout title="Posts"> + <div class="org-article-title"> + <h1></h1> + <a href="/posts/feed.xml">RSS Feed</a> + </div> + + <div id="tag-filter-container"></div> + + <div id="content" class="content"> + <ul class="org-ul" id="posts-list"> + {allPosts.map((post: CollectionEntry<'posts'>) => ( + <li data-tags={post.data.tags.join(',')}> + <p><a href={`/posts/${post.slug}`}>{post.data.title}</a></p> + <div class="sitemap_date"><p>{formatDate(post.data.date)}</p></div> + {post.data.tags.map((tag: string) => ( + <div class="sitemap_tag"><p>{tag}</p></div> + ))} + </li> + ))} + </ul> + </div> + + <script is:inline> + (function () { + const list = document.getElementById('posts-list'); + const filterContainer = document.getElementById('tag-filter-container'); + if (!list || !filterContainer) return; + + const items = Array.from(list.querySelectorAll('li[data-tags]')); + + // Collect unique tags + const tagSet = new Set(); + items.forEach(item => { + const tags = item.getAttribute('data-tags') || ''; + tags.split(',').filter(Boolean).forEach(t => tagSet.add(t.trim())); + }); + + if (tagSet.size === 0) return; + + // Track which tags are enabled + const enabledTags = new Set(tagSet); + + function applyFilter() { + items.forEach(item => { + const itemTags = (item.getAttribute('data-tags') || '') + .split(',') + .filter(Boolean) + .map(t => t.trim()); + const visible = itemTags.some(t => enabledTags.has(t)) || itemTags.length === 0; + item.style.display = visible ? '' : 'none'; + }); + } + + // Create filter buttons + tagSet.forEach(tag => { + const btn = document.createElement('span'); + btn.textContent = tag; + btn.className = 'tag-filter-item'; + btn.dataset.tag = tag; + btn.addEventListener('click', () => { + if (enabledTags.has(tag)) { + enabledTags.delete(tag); + btn.classList.add('disabled'); + } else { + enabledTags.add(tag); + btn.classList.remove('disabled'); + } + applyFilter(); + }); + filterContainer.appendChild(btn); + }); + })(); + </script> +</BaseLayout> diff --git a/src/pages/reading.astro b/src/pages/reading.astro new file mode 100644 index 0000000..0e1d1cb --- /dev/null +++ b/src/pages/reading.astro @@ -0,0 +1,60 @@ +--- +import { getCollection, type CollectionEntry } from "astro:content"; +import BaseLayout from "../layouts/BaseLayout.astro"; +import ReadingEntry from "../components/ReadingEntry.astro"; +import "../styles/post.css"; +import "../styles/sitemap.css"; + +type ReadingYear = CollectionEntry<"reading">; +type Entry = ReadingYear["data"]["entries"][number]; + +const years = await getCollection("reading"); +years.sort((a: ReadingYear, b: ReadingYear) => b.data.year - a.data.year); + +// Entries are authored oldest-first within a year; show the most recent first. +function newestFirst(entries: Entry[]): Entry[] { + return [...entries].reverse(); +} +--- + +<BaseLayout + title="Reading" + description="Books and articles I've read/am reading" +> + <div id="content" class="content"> + { + years.map((year: ReadingYear) => { + const entries = newestFirst(year.data.entries); + const books = entries.filter((e: Entry) => e.type === "book"); + const articles = entries.filter( + (e: Entry) => e.type === "article", + ); + + return ( + <section class="reading-year"> + <h2>{year.data.year}</h2> + + <div class="reading-year-body"> + <ul class="org-ul"> + {books.map((entry: Entry) => ( + <ReadingEntry entry={entry} /> + ))} + </ul> + + {articles.length > 0 && ( + <Fragment> + <h3 class="reading-subhead">Articles</h3> + <ul class="org-ul"> + {articles.map((entry: Entry) => ( + <ReadingEntry entry={entry} /> + ))} + </ul> + </Fragment> + )} + </div> + </section> + ); + }) + } + </div> +</BaseLayout> diff --git a/src/pages/resume.astro b/src/pages/resume.astro new file mode 100644 index 0000000..b326657 --- /dev/null +++ b/src/pages/resume.astro @@ -0,0 +1,272 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +import CppIcon from '../components/CppIcon.astro'; +import RustIcon from '../components/RustIcon.astro'; +import JavaScriptIcon from '../components/JavaScriptIcon.astro'; +import TypeScriptIcon from '../components/TypeScriptIcon.astro'; +import ReactIcon from '../components/ReactIcon.astro'; +import CIcon from '../components/CIcon.astro'; +import PythonIcon from '../components/PythonIcon.astro'; +import GitIcon from '../components/GitIcon.astro'; +import CSharpIcon from '../components/CSharpIcon.astro'; +import CSharpModernIcon from '../components/CSharpModernIcon.astro'; +import JavaIcon from '../components/JavaIcon.astro'; +import LuaIcon from '../components/LuaIcon.astro'; +import '../styles/resume.css'; +import '../styles/resume.mobile.css'; +--- + +<BaseLayout + title="Matthew Kosarek - Resume" + description="The hosted resume of Matthew Kosarek" +> + <main id="resume"> + <section class="resume_section"> + <h2>Experience</h2> + <div class="resume_section_content"> + <div class="experience-item"> + <div class="experience-header"> + <div> + <span><b>Software Engineer II</b></span> + <span><i>Canonical</i></span> + </div> + <div> + <span>July 2023 to Present</span> + <span>Philadelphia, PA</span> + </div> + </div> + <div class="experience-tech"> + <CppIcon /> + <RustIcon /> + </div> + <ul> + <li> + Contributed extensively to <a + href="https://github.com/MirServer/Mir" + target="_blank">Mir</a + >, a C++ library for Wayland compositors + </li> + <li> + Implemented multi-window support in <a + href="https://github.com/flutter/flutter" + target="_blank">Flutter</a + > for Win32, Linux, and MacOS + </li> + </ul> + </div> + <div class="experience-item"> + <div class="experience-header"> + <div> + <span><b>Software Team Lead for MachineApps</b></span> + <span><i>Vention</i></span> + </div> + <div> + <span>July 2020 to July 2023</span> + <span>Montreal, QC</span> + </div> + </div> + <div class="experience-tech"> + <JavaScriptIcon /> + <TypeScriptIcon /> + <ReactIcon /> + <CIcon /> + <PythonIcon /> + <GitIcon /> + </div> + <ul> + <li> + Developed industrial software applications including cobot + palletizers, cartesian palletizers, and path following machines + </li> + <li> + Programmed, deployed, and supported several client projects valued + over $100k+ USD each + </li> + <li> + Developed the core user-facing API for programming industrial + machines in Python + </li> + <li> + Interfaced with both technical and non-technical teams on a daily + basis + </li> + <li> + Planned and organized long-term projects and daily tasks via Asana + and Github Projects + </li> + <li> + Programmed thousands of lines across the codebase, from the + firmware running on a BeagleBone AI to the application layer + running in the cloud + </li> + <li>Onboarded and mentored new members of the team</li> + </ul> + </div> + <div class="experience-item"> + <div class="experience-header"> + <div> + <span><b>Software Engineer I</b></span> + <span><i>Big Huge Games</i></span> + </div> + <div> + <span>January 2018 to June 2020</span> + <span>Timonium, MD</span> + </div> + </div> + <div class="experience-tech"> + <CSharpIcon /> + <JavaIcon /> + <TypeScriptIcon /> + <ReactIcon /> + <LuaIcon /> + <CSharpModernIcon /> + <GitIcon /> + </div> + <ul> + <li> + Developed and maintained the data pipeline - from data entry, to + data validation, to data publication - for <i>Arcane Showdown</i> + </li> + <li> + Designed, built, and maintained a live operations scheduling and + publishing web application for <i>DomiNations</i> + </li> + <li> + Implemented a localization system for <i>Arcane Showdown</i> which allowed + the game to be released in different languages + </li> + <li> + Implemented game features on all parts of the stack, including + tools, Unity client, and game servers + </li> + </ul> + </div> + <div class="experience-item"> + <div class="experience-header"> + <div> + <span + ><b>Teaching Assistant for Intro to Video Game Design</b></span + > + <span><i>Johns Hopkins University</i></span> + </div> + <div> + <span>September 2017 to December 2017</span> + <span>Baltimore, MD</span> + </div> + </div> + <div class="experience-tech"> + <CppIcon /> + </div> + <ul> + <li> + Assisted beginner programmers in the development of 2D game + engines using SDL2 + </li> + </ul> + </div> + <div class="experience-item"> + <div class="experience-header"> + <div> + <span><b>Software Engineering Intern</b></span> + <span><i>Big Huge Games</i></span> + </div> + <div> + <span>May 2017 to August 2017</span> + <span>Timonium, MD</span> + </div> + </div> + <div class="experience-tech"> + <CSharpIcon /> + <LuaIcon /> + <CSharpModernIcon /> + <GitIcon /> + </div> + <ul> + <li> + Developed a tool using C# and GTK to improve the workflow of the + quality assurance team for <i>DomiNations</i> + </li> + <li> + Wrote a comprehensive user manual that explains how the tool + functions for both technical and non-technical users + </li> + </ul> + </div> + <div class="experience-item"> + <div class="experience-header"> + <div> + <span><b>Software Engineering Intern</b></span> + <span><i>Sparkypants Studios</i></span> + </div> + <div> + <span>May 2016 to August 2016</span> + <span>Baltimore, MD</span> + </div> + </div> + <div class="experience-tech"> + <CppIcon /> + </div> + <ul> + <li> + Developed a profiling framework for the game systems of <i + >Dropzone</i + > + </li> + </ul> + </div> + </div> + </section> + + <section class="resume_section"> + <h2>Education</h2> + <div class="resume_section_content"> + <div class="experience-item"> + <div class="experience-header"> + <div> + <span + ><b>BSc Computer Engineering at Johns Hopkins University</b + ></span + > + <span>Baltimore, MD</span> + </div> + <div> + <span>September 2014 to December 2017</span> + </div> + </div> + <ul> + <li>3.53 GPA (Magna Cum Laude)</li> + <li> + <i>Relevant Coursework</i>: Computer Graphics, Object Oriented + Software Engineering, Linear Algebra, Video Game Engines and + Design, Operating Systems, Data Structures + </li> + </ul> + </div> + </div> + </section> + + <section class="resume_section"> + <h2>Projects</h2> + <ul> + <li> + Author of <b + ><a href="https://github.com/miracle-wm-org/miracle-wm" + >miracle-wm</a + ></b + >, a hackable Wayland window manager + </li> + <li> + My <b>self-hosted personal website</b> where I do small projects in WebAssembly + and OpenGL: <a href="https://matthewkosarek.xyz">matthewkosarek.xyz</a + > + </li> + <li> + A <b>game engine</b> that I built in C++ and OpenGL: <a + href="https://github.com/mattkae/MatteEngine" + >github.com/mattkae/MatteEngine</a + > + </li> + </ul> + </section> + </main> +</BaseLayout> diff --git a/src/pages/tech.astro b/src/pages/tech.astro new file mode 100644 index 0000000..b533515 --- /dev/null +++ b/src/pages/tech.astro @@ -0,0 +1,51 @@ +--- +import BaseLayout from '../layouts/BaseLayout.astro'; +--- + +<BaseLayout + title="Tech I Like - Matthew Kosarek" + description="Tech that Matthew Kosarek likes and uses" +> + <div class="index-layout"> + <div class="index-main"> + <section> + <h2>Things I Use</h2> + <h3>For Development</h3> + <ul> + <li> + <b>My dotfiles</b>: I use everything in my dotfiles every day, which + you can find <a href="https://github.com/mattkae/dotfiles">here</a> + </li> + <li> + <a href="https://www.gnu.org/software/emacs/">Emacs</a>: I am a + long-time Emacs user. You can find my config <a + href="https://git.matthewkosarek.xyz/emacs_config/">here</a + > + </li> + <li style="text-decoration: line-through;"> + <a href="https://www.jetbrains.com/clion/">Clion</a>: I use this for + my corporate life, although it is quite heavy + </li> + <li> + <a href="https://zed.dev/">Zed</a>: I am currently experimenting + using Zed for all of my development + </li> + <li> + <a href="https://astro.build/">astro</a>: super simple SSG that I + use constantly + </li> + </ul> + <h3>For Lifestyle</h3> + <ul> + <li> + <a href="https://orgmode.org/">Org Mode</a>: for calendar, todo + lists, notes, and more! + </li> + <li> + <a href="https://newsboat.org/">Newsboat</a>: RSS reader + </li> + </ul> + </section> + </div> + </div> +</BaseLayout> |
