Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 2 additions & 12 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,6 @@
.eslintcache
.next
out

# Yarn
.yarn/*
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions

# bun
*.bun

# Cloud9 IDE files
.bake-debug
.c9
dist
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM oven/bun:1.2.22 as builder
WORKDIR /app

RUN apt update && apt install -y unzip
RUN bunx bun-pr 4f0d2a5624e4c54eb89faf7d5e23470efc8de667
COPY bunfig.toml bunfig.toml
COPY bun.lock bun.lock
COPY package.json package.json
RUN bun-4f0d2a5624e4c54eb89faf7d5e23470efc8de667 install

COPY . .
RUN bun-4f0d2a5624e4c54eb89faf7d5e23470efc8de667 build --app

FROM oven/bun:1.2.22 as runner
WORKDIR /app
COPY --from=builder /app/dist .

EXPOSE 3000
CMD ["bunx", "serve", "-p", "3000"]
3 changes: 0 additions & 3 deletions SECURITY.md

This file was deleted.

5 changes: 5 additions & 0 deletions bun.app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import react from 'bun-framework-react';

export default {
app: {framework: react},
};
1,212 changes: 135 additions & 1,077 deletions bun.lock

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions bunfig.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[install.security]
scanner = "bun-demo-security-scanner"
303 changes: 303 additions & 0 deletions home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
'use client';

import clsx from 'clsx';
import {motion} from 'framer-motion';
import {CiTwitter} from 'react-icons/ci';
import {SiBun, SiGithub, SiSpotify} from 'react-icons/si';
import {useLanyardWS} from 'use-lanyard';
import {BlogPostList} from './src/components/blog-post-list';
import {MessageGroup, message} from './src/components/message';
import {useShouldDoInitialPageAnimations} from './src/hooks/use-did-initial-page-animations';
import {discordId} from './src/utils/constants';

const album = '/album.png';

export default function Home() {
const lanyard = useLanyardWS(discordId);

const shouldAnimate = useShouldDoInitialPageAnimations();

return (
<main className="mx-auto max-w-xl px-3 pt-24 pb-16">
<motion.ul
transition={{
staggerChildren: 0.1,
delayChildren: 0.1,
}}
initial={shouldAnimate ? 'hidden' : 'show'}
animate="show"
className="space-y-8"
>
<MessageGroup
messages={[
{
key: 'intro',
content: (
<div className="px-4 py-2.5">
I'm <span className="font-serif italic">Alistair</span>. I work on
<SiBun className="mb-[3px] ml-1 inline" />{' '}
<a
href="https://bun.com"
className="underline decoration-zinc-400 dark:decoration-zinc-500/80"
target="_blank"
>
Bun, the fast JavaScript runtime
</a>
. I'm interested in things like language specifications and type systems. I've
been called a TypeScript wizard at least a few times. It's nice to meet you.
</div>
),
},
]}
/>

{lanyard?.spotify && (
<MessageGroup
messages={[
{
key: 'music',
content: (
<div className="max-w-[380px] space-y-3 px-4 py-2.5">
<p>
I listen to a lot of music, and{' '}
<span className="font-serif italic">right now</span> I'm listening to this
song on Spotify:
</p>
</div>
),
},

{
key: 'the-current-song',
content: (
<a
href={`https://open.spotify.com/track/${lanyard.spotify.track_id}`}
className="group relative block w-full min-w-[300px] cursor-default overflow-hidden rounded-[20px] p-4"
target="_blank"
>
<div className="absolute inset-0">
<div className="absolute inset-0 z-10 bg-white/70 transition-colors group-hover:bg-white/80 dark:bg-zinc-800/80 dark:group-hover:bg-zinc-800/85"></div>
<img
src={lanyard.spotify.album_art_url ?? album}
alt="Album art"
aria-hidden
className="absolute top-1/2 -translate-y-1/2 blur-3xl saturate-[50] dark:saturate-[10]"
/>
</div>

<div className="relative z-10 flex items-center space-x-4 pr-8">
<img
src={lanyard.spotify.album_art_url ?? album}
alt="Album art"
className="size-12 rounded-md border-2"
/>

<div className="space-y-1">
<p className="line-clamp-1">
<strong>{lanyard.spotify.song}</strong>
</p>
{lanyard.spotify.artist && (
<p className="line-clamp-1 text-zinc-800 dark:text-white/60">
{lanyard.spotify.artist.split('; ').join(', ')}
</p>
)}
</div>
</div>

<div className="absolute top-4 right-4 z-10">
<SiSpotify className="size-4 text-zinc-900/80 dark:text-white/50" />
</div>
</a>
),
},
]}
/>
)}

{/* <MessageGroup
messages={[
...(lanyard.spotify
? []
: []),
// {
// key: 'not-music',
// content: (
// <div className="px-4 py-2.5">
// In the rare case I'm not listening to anything, you can usually find me out and
// about riding my{' '}
// <a
// href="https://www.youtube.com/watch?v=LBx-JCj-7Y8"
// className="underline decoration-zinc-400 dark:decoration-zinc-500/80"
// target="_blank"
// >
// Evolve skateboard
// </a>
// ,{' '}
// <a
// href="https://www.youtube.com/watch?v=x6vlL9Sscmw"
// className="underline decoration-zinc-400 dark:decoration-zinc-500/80"
// target="_blank"
// >
// DJing (on YouTube)
// </a>{' '}
// or{' '}
// <a
// href="https://soundcloud.com/alistairsmusic/"
// className="underline decoration-zinc-400 dark:decoration-zinc-500/80"
// target="_blank"
// >
// trying my hardest to figure out Ableton Live
// </a>
// </div>
// ),
// },
]}
/> */}

<MessageGroup messages={[message('remaining-blog-posts', <BlogPostList />)]} />

{lanyard && (
<MessageGroup
messages={[
{
key: 'location',
content: (
<div className="relative h-[150px] w-[300px]">
<div className="absolute inset-0 overflow-hidden rounded-[20px]">
<img
src={`/api/map?location=${lanyard.kv.location}&theme=light`}
alt="Map"
className="absolute inset-0 h-full w-full scale-125 object-cover dark:hidden"
/>
<img
src={`/api/map?location=${lanyard.kv.location}&theme=dark`}
alt="Map"
className="absolute inset-0 hidden h-full w-full scale-125 object-cover dark:block"
/>
</div>

<span className="absolute top-1/2 left-1/2 z-10 -mt-7 -ml-7 block size-14 animate-[ping_2s_cubic-bezier(0,_0,_0.2,_1)_infinite] rounded-full bg-lime-500" />

<img
src={`https://cdn.discordapp.com/avatars/${lanyard.discord_user.id}/${lanyard.discord_user.avatar}.webp?size=160`}
alt="Avatar"
className="absolute top-1/2 left-1/2 z-10 size-16 -translate-x-1/2 -translate-y-1/2 rounded-full border-2"
/>
</div>
),
},
{
key: 'location-caption',
content: (
<p className="px-4 py-2.5">
I'm currently in{' '}
<a
href={`https://maps.apple.com/?q=${lanyard.kv.location}`}
className="underline decoration-zinc-400 dark:decoration-zinc-500/80"
target="_blank"
>
{lanyard.kv.location}
</a>{' '}
📍
</p>
),
},
]}
/>
)}

{lanyard && (
<MessageGroup
messages={[
{
key: 'chat-1',
content: (
<div className="max-w-[384px] px-4 py-2.5">I'm on a few social platforms</div>
),
},
{
key: 'discord',
content: (
<div className="px-4 py-2.5">
My Discord is{' '}
<a
href="discord://-/users/268798547439255572"
className="font-serif text-indigo-600 italic underline dark:text-indigo-300"
>
@alistaiir
</a>{' '}
<span
aria-hidden
className={clsx(
'ml-0.5 inline-block size-1.5 rounded-full',
{
dnd: 'bg-red-600 dark:bg-red-400',
idle: 'bg-amber-500',
online: 'bg-green-500',
offline: 'bg-gray-500',
}[lanyard.discord_status],
)}
/>
</div>
),
},
{
key: 'github',
content: (
<div className="px-4 py-2.5">
I'm{' '}
<a
href="https://github.com/alii"
className="underline decoration-zinc-400 dark:decoration-zinc-500/80"
target="_blank"
>
@alii on GitHub
</a>{' '}
<SiGithub className="mb-[3px] inline" />{' '}
</div>
),
},
{
key: 'chat-2',
content: (
<div className="px-4 py-2.5">
Lastly I'm{' '}
<a
href="https://x.com/alistaiir"
className="underline decoration-zinc-400 dark:decoration-zinc-500/80"
target="_blank"
>
@alistaiir on Twitter/X
</a>{' '}
<CiTwitter className="mb-[3px] inline" />
</div>
),
},
]}
/>
)}

<MessageGroup
messages={[
{
key: 'experiments',
content: (
<div className="px-4 py-2.5">
I have some fun experiments on this site, some are functional things I use, others
are just me messing around.{' '}
<a
href="/experiments"
className="underline decoration-zinc-400 dark:decoration-zinc-500/80"
>
Click here to see them
</a>
.
</div>
),
},
]}
/>
</motion.ul>
</main>
);
}
6 changes: 0 additions & 6 deletions next-env.d.ts

This file was deleted.

Loading
Loading