Skip to content

Hydepwns/droodotfoo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

338 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DROO.FOO

Personal website built with LiveView, generative art patterns and monospace web aesthetics.

Test Coverage Tests Elixir Phoenix

Live: DROO.FOO

Features

Core Portfolio & Blog

  • Monospace Web Design: Character-perfect grid using 1ch units and rem-based line-height
  • Blog System: File-based markdown posts with YAML frontmatter and series support
  • Generative Patterns: Unique SVG patterns per post with 8 animation styles
  • Real-time Updates: Phoenix LiveView for instant page updates
  • Projects Showcase: GitHub integration with stats and contribution visualization
  • Resume System: Structured JSON-based resume with filtering and search
  • SEO Optimized: JSON-LD structured data for enhanced search engine visibility

Integrations

  • Web3 Wallet: Connect MetaMask for wallet authentication, ENS resolution, NFT/token viewing
  • Spotify Player: OAuth integration with playback controls, playlist browsing, and real-time progress
  • GitHub Stats: Repository visualization and contribution graphs
  • STL Viewer: 3D model viewer with Three.js integration

Quick Start

Local Development with 1Password CLI

# Install dependencies
mix setup

# Install 1Password CLI
# Install the desktop app
# https://1password.com/downloads
# https://developer.1password.com/docs/cli/app-integration/
brew install --cask 1password-cli

# Sign in to 1Password
op signin

# Create secrets in 1Password.
op item create --category=login --title="droodotfoo-dev" \
  SPOTIFY_CLIENT_ID="your_client_id" \
  SPOTIFY_CLIENT_SECRET="your_client_secret"

# Start server with secrets loaded from 1Password
./bin/dev

# After changes re-deploy with:
# 1. Deploy updated assets to CDN
./scripts/deploy-cdn.sh
# 2. Deploy Phoenix app to Fly.io
fly deploy

Alternative: Manual Environment Variables

# Set Spotify credentials (optional)
export SPOTIFY_CLIENT_ID="your_client_id"
export SPOTIFY_CLIENT_SECRET="your_client_secret"

# Start server
mix phx.server

Visit localhost:4000

Monospace Web Design

The site implements Wickström's monospace web technique for character-perfect grid alignment:

Horizontal Grid (1ch units):

  • Each character occupies exactly 1ch width
  • Container widths snap to character boundaries: calc(round(down, 80ch, 1ch))
  • Table columns use character-based widths (8ch, 12ch, 20ch, etc.)

Vertical Grid (rem-based line-height):

  • Fixed --line-height: 1.5rem for predictable calculations
  • Prevents line-height compounding in nested elements
  • Scales proportionally: 24px at 16px base, 21px at 14px mobile

Visual Refinements:

  • Double-line horizontal rules with layered pseudo-elements
  • Precision table padding compensates for border thickness
  • Media element grid alignment (images/videos snap to line-height)
  • All spacing uses multiples of 1ch or line-height

Benefits:

  • Zero layout shift (every character positioned exactly)
  • Maintainable vertical rhythm throughout content
  • Professional terminal-inspired aesthetic
  • Consistent across all themes and screen sizes

See wickstrom.tech for the original technique.

Architecture

Built with modular Phoenix LiveView architecture:

Monospace Web Design: Character-perfect grid using Wickstrom's monospace web technique with 1ch horizontal units and rem-based line-height for predictable vertical rhythm. Double-line dividers, precision table padding, and media element grid alignment maintain visual consistency.

Rendering: Phoenix LiveView handles real-time updates over WebSockets.

State Management: GenServers orchestrate content loading and GitHub API integration. Functional patterns with immutable state throughout.

Performance: ETS caching for GitHub API data, blog post metadata, and SVG patterns. Pattern cache provides 568x speedup (26ms -> 47us). Brotli compression for static assets. Page loads under 200ms.

Content System: File-based blog posts with markdown + YAML frontmatter. Deterministic SVG pattern generation per post with 8 animation styles. No database required.

Test Coverage: 1084 tests passing (41.2% code coverage)

Tech Stack

  • Backend: Elixir 1.17+, Phoenix 1.8.1, LiveView 1.1.12, Bandit web server
  • Styling: Tailwind CSS v4, Monaspace fonts (woff2 format with preload optimization)
  • Monospace Grid: 1ch units + rem-based line-height for character-perfect alignment
  • Frontend: TypeScript, esbuild for bundling, lazy-loaded hooks
  • Content: MDEx for markdown parsing with syntax highlighting
  • Caching: ETS for GitHub API, posts, patterns (568x speedup for patterns)
  • Compression: Brotli for static assets (JS, CSS, SVG, fonts)
  • SEO: JSON-LD structured data for enhanced search visibility
  • Rust NIFs: ex_keccak, ex_secp256k1 (Web3 crypto), autumn, mdex (compiled from source)
  • Optional: ethers.js (Web3), Three.js (STL viewer)
  • Testing: ExUnit with 1084 tests passing

Development

# Run tests
mix test

# Run specific test file
mix test test/droodotfoo/raxol_app_test.exs

# Format code
mix format

# Compile with warnings
mix compile --warning-as-errors

# Full precommit check (compile, deps, format, test)
mix precommit

# Generate ExDoc documentation
mix docs

Deployment

Fly.io Production Deployment

# Install Fly CLI
brew install flyctl

# Login to Fly.io
fly auth login

# Create fly.toml and guides through setup
# Fly.io will handle the routing from external ports (80/443) to your app's internal port 8080 (default)
# Even though our config/runtime.exs specifies port 4000
fly launch
# Or if you want to create the app manually:
fly apps create droodotfoo

# Set production secrets (required)
# once successfully set with fly secrets set, they're stored encrypted in Fly.io's infra
# and injected into your app as environment variables at runtime
fly secrets set \
  SECRET_KEY_BASE=$(mix phx.gen.secret) \
  PHX_HOST="droodotfoo.fly.dev"

# Set blog API token (required for Obsidian publishing)
fly secrets set BLOG_API_TOKEN=$(mix phx.gen.secret)

# Optional: Spotify integration
# obtain secrets from https://developer.spotify.com/dashboard
fly secrets set \
  SPOTIFY_CLIENT_ID="prod_client_id" \
  SPOTIFY_CLIENT_SECRET="prod_client_secret"

# Then register https://droo.foo/auth/spotify/callback in Spotify Dashboard
# https://developer.spotify.com/dashboard
# add redirect URI and the website link (i.e. `PHX_HOST`)
SPOTIFY_REDIRECT_URI="https://your-app.fly.dev/auth/spotify/callback"

# Optional: GitHub API token for higher rate limits (5000/hr vs 60/hr)
fly secrets set GITHUB_TOKEN="ghp_xxxxx"

# Optional: Configure Cloudflare Pages CDN for static assets
fly secrets set CDN_HOST="your-project.pages.dev"

# Deploy
fly deploy

Rust NIF Compilation

The Dockerfile compiles Rust NIFs from source because GitHub release assets are often blocked from CI builders. If deployment fails with NIF download errors, ensure these env vars are set in the Dockerfile:

ENV EX_KECCAK_BUILD="1"
ENV RUSTLER_BUILD="1"
ENV AUTUMN_BUILD="1"
ENV MDEX_BUILD="1"

Environment Variables

See docs/guides/deployment.md for complete environment variable reference.

Required: SECRET_KEY_BASE, PHX_HOST, BLOG_API_TOKEN

Optional: SPOTIFY_CLIENT_ID, SPOTIFY_CLIENT_SECRET, GITHUB_TOKEN, CDN_HOST

Security

See docs/guides/security.md for comprehensive security documentation.

Key Features:

  • OAuth 2.0 for Spotify, Bearer token for Blog API
  • Rate limiting on all public endpoints
  • Input validation with path traversal prevention
  • HTTPS enforcement, CSP headers, secure cookies

Documentation

Project Documentation

  • CLAUDE.md - Project overview, patterns, and AI assistant context
  • AGENTS.md - Phoenix/Elixir development guidelines

Guides (docs/)

API Documentation (ExDoc)

Generate comprehensive documentation with typespecs:

# Generate HTML documentation
mix docs

# View in browser
open doc/index.html

Includes:

  • Module documentation with examples
  • Function signatures with @spec annotations
  • Type definitions and behaviors
  • Searchable interface

About

DROO.FOO

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors