Skip to content

Commit b25110f

Browse files
authored
[FEATURE] "Ghost City" Mode for Zero Contributions (JhaSourav07#114)
## Description Fixes JhaSourav07#97 1. Ghost City Mode: Zero-contribution days now show as thin 4px blueprint foundations to maintain a premium 3D look across the entire calendar. 2. Auto-Theme Support: Refactored the logic so these new foundations automatically switch colors between Dark and Light mode. 3. Modular Rendering: Moved tower calculations into helper functions (computeTowers, computeFaceOpacity) to make the code cleaner and easier to manage. 4. Upstream Sync: Integrated the changes with the latest project updates (Auto-Theme and Dynamic Fonts) to ensure no features were broken. 5. Documentation: Preserved all original maintainer comments and added new JSDoc for the refactored functions. ## Pillar - [ ] 🎨 Pillar 1 — New Theme Design - [x ] 📐 Pillar 2 — Geometric SVG Improvement - [ ] 🕐 Pillar 3 — Timezone Logic Optimization - [ ] 🛠️ Other (Bug fix, refactoring, docs) ## Visual Preview Preview in the comments ## Checklist before requesting a review: - [x ] I have read the `CONTRIBUTING.md` file. - [ x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [x ] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [ x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). - [ x] I have updated `README.md` if I added a new theme or URL parameter. - [x ] I have started the repo. - [x ] I have made sure that i have only one commit to merge in this PR. - [ x] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts).
2 parents 0acbebc + 941d3c4 commit b25110f

3 files changed

Lines changed: 195 additions & 251 deletions

File tree

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,11 @@ Most GitHub stat badges are **flat**. Flat bars, flat text, flat colors. They bl
3232

3333
**CommitPulse is different.**
3434

35-
We render your contribution data as a **3D Isometric City** — a grid of glowing towers where each column's height is directly proportional to your commit count that day. The more you grind, the taller your skyline grows. This is not decoration. This is a **live, animated data visualization** that makes your dedication impossible to ignore.
35+
We render your contribution data as a **3D Isometric City** — a grid of glowing towers where each column's height is directly proportional to your commit count that day. The more you grind, the taller your skyline grows.
36+
37+
**Ghost City Architecture:** In this mode, zero-contribution days aren't just empty space. They are rendered as thin, wireframe-style **blueprint foundations** (4px high). This gives your commit landscape a structured, architectural "work-in-progress" look even during rest days, maintaining the premium 3D aesthetic across the entire calendar.
38+
39+
This is not decoration. This is a **live, animated data visualization** that makes your dedication impossible to ignore.
3640

3741
### Why Isometric > Flat
3842

lib/svg/generator.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,4 +202,51 @@ describe('generateSVG', () => {
202202
expect(svg).toContain('prefers-reduced-motion');
203203
});
204204
});
205+
206+
// Ghost City Placeholder Mode tests
207+
describe('Ghost City Mode', () => {
208+
const emptyCalendar: ContributionCalendar = {
209+
totalContributions: 0,
210+
weeks: [
211+
{
212+
contributionDays: [
213+
{ contributionCount: 0, date: '2024-06-10' },
214+
{ contributionCount: 0, date: '2024-06-11' },
215+
],
216+
},
217+
],
218+
};
219+
220+
const activeCalendar: ContributionCalendar = {
221+
totalContributions: 5,
222+
weeks: [
223+
{
224+
contributionDays: [
225+
{ contributionCount: 0, date: '2024-06-10' },
226+
{ contributionCount: 5, date: '2024-06-11' },
227+
],
228+
},
229+
],
230+
};
231+
232+
it('renders Ghost City blueprint when user has 0 total contributions', () => {
233+
const svg = generateSVG(mockStats, { user: 'avi' } as unknown as BadgeParams, emptyCalendar);
234+
235+
// Should contain wireframe strokes
236+
expect(svg).toContain('stroke-width="0.5"');
237+
expect(svg).toContain('stroke-opacity="0.3"');
238+
// Should use the GHOST_HEIGHT_PX which is 4 (10 + 4 = 14)
239+
expect(svg).toContain('L0 14 L-16 4 L-16 0 Z');
240+
});
241+
242+
it('does not render Ghost City when user has active contributions', () => {
243+
const svg = generateSVG(mockStats, { user: 'avi' } as unknown as BadgeParams, activeCalendar);
244+
245+
// Should NOT contain wireframe strokes
246+
expect(svg).not.toContain('stroke-width="0.5"');
247+
expect(svg).not.toContain('stroke-opacity="0.3"');
248+
// Active mode empty days should have h=0 (10 + 0 = 10)
249+
expect(svg).toContain('L0 10 L-16 0 L-16 0 Z');
250+
});
251+
});
205252
});

0 commit comments

Comments
 (0)