feat: Retro pixel-art desktop environment with NES.css theming#18
feat: Retro pixel-art desktop environment with NES.css theming#18
Conversation
Major transformation of the Corvid Labs site into an interactive desktop-like environment with windowed applications and games. New Features: - NES.css pixel-art styling with 8 customizable themes - Floating window system with drag/resize support - 18+ window components (games, utilities, wallet, NFT showcase) - Pera Wallet integration for Algorand blockchain - SoundCloud player integration - Leaderboard system - Swift backend infrastructure Games Added: - Tetris, Snake, Pong, Breakout - 2048, Minesweeper, Memory Match - Flappy Raven, Slot Machine Components: - Launch pad dashboard - NFT showcase & rarity checker - Calculator, Notepad, Settings - Theme switcher with live preview 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This pull request transforms the Corvid Labs site into an immersive retro pixel-art desktop environment featuring NES.css theming, window management, games, utilities, NFT/wallet integration, and a Swift backend for leaderboards.
Changes:
- Adds 8 customizable themes (Dark, Light, Corvid, Green, Black-Orange, Arcade, Sunset, Cyberpunk) with a centralized theme service
- Implements a floating window system with 18+ window components including games (Tetris, Snake, Pong, etc.), utilities (Calculator, Notepad), and NFT features
- Integrates Pera Wallet for Algorand blockchain connectivity with wallet and NFT showcase windows
- Adds Swift/Vapor backend infrastructure for leaderboards, user profiles, and authentication
Reviewed changes
Copilot reviewed 130 out of 138 changed files in this pull request and generated 25 comments.
Show a summary per file
| File | Description |
|---|---|
| src/themes/*.scss | Theme definitions for 8 pixel-art themes with CSS variables |
| src/app/services/general/theme.service.ts | Centralized theme management with signals and localStorage persistence |
| src/app/services/nodely.service.ts | Algorand indexer integration for NFT data and wallet operations |
| src/app/directives/draggable.directive.ts | Window drag functionality with viewport constraints |
| src/app/components/windows/* | 18+ window components for games, utilities, and NFT features |
| src/app/components/shared/pixel-icon | Pixel-art icon component mapping Material icons to pixelarticons font |
| backend/Sources/App/* | Swift/Vapor backend with JWT auth, leaderboards, and user profiles |
| package.json | Adds nes.css and pixelarticons dependencies |
| export class SoundcloudService { | ||
| private url = 'https://api.soundcloud.com'; | ||
|
|
||
| constructor(private httpClient: HttpClient) {} |
There was a problem hiding this comment.
Use the inject() function instead of constructor injection for consistency with Angular modern practices.
| return `${address.slice(0, 6)}...${address.slice(-4)}`; | ||
| }); | ||
|
|
||
| constructor(private nodelyService: NodelyService) { |
There was a problem hiding this comment.
Use the inject() function instead of constructor injection for consistency with Angular modern practices.
| return this.MIN_TXN_FEE * price; | ||
| }); | ||
|
|
||
| constructor(private http: HttpClient) { |
There was a problem hiding this comment.
Use the inject() function instead of constructor injection for consistency with Angular modern practices.
| @Component({ | ||
| selector: 'app-player-window', | ||
| templateUrl: './player-window.component.html', | ||
| imports: [CommonModule, DraggableDirective, SoundcloudPlayerComponent], | ||
| styleUrls: ['./player-window.component.scss'] | ||
| }) |
There was a problem hiding this comment.
Missing ChangeDetectionStrategy.OnPush in component decorator. Set changeDetection: ChangeDetectionStrategy.OnPush for better performance.
| @Input() title: string = 'Floating Window'; | ||
| @Input() initialPosition?: { x: number; y: number }; | ||
|
|
||
| // Input setters to allow parent components to set initial dimensions | ||
| // TODO: These setters aren't used - child components set width/height directly via .set() in constructor | ||
| @Input() set initialWidth(value: number) { | ||
| this.width.set(value); | ||
| } | ||
|
|
||
| @Input() set initialHeight(value: number) { | ||
| this.height.set(value); |
There was a problem hiding this comment.
Use input() function instead of @input decorator for consistency with Angular modern practices.
| import { DraggableDirective } from '../../../directives/draggable.directive'; | ||
| import { CommonModule } from '@angular/common'; | ||
| import { FormsModule } from '@angular/forms'; | ||
| import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; |
There was a problem hiding this comment.
Unused import SafeHtml.
| @@ -0,0 +1,286 @@ | |||
| import { Component, signal, computed, ElementRef, ViewChild, AfterViewInit, OnDestroy, ChangeDetectionStrategy } from '@angular/core'; | |||
There was a problem hiding this comment.
Unused import computed.
| @@ -0,0 +1,158 @@ | |||
| import { Directive, ElementRef, HostListener, inject, Input, OnInit } from '@angular/core'; | |||
There was a problem hiding this comment.
Unused import inject.
| @@ -0,0 +1,33 @@ | |||
| import { HttpClient, HttpParams } from "@angular/common/http"; | |||
There was a problem hiding this comment.
Unused import HttpParams.
| import algosdk from "algosdk"; | ||
| import { CID } from 'multiformats/cid'; | ||
| import * as Digest from "multiformats/hashes/digest"; | ||
| import { forkJoin, map, Observable, of, switchMap } from 'rxjs'; |
There was a problem hiding this comment.
Unused import switchMap.
Summary
New Features
Window System:
Games:
Utilities:
NFT/Wallet:
Test plan
🤖 Generated with Claude Code