Skip to content

Commit 7311512

Browse files
feat: add WebP export support for generated badges (JhaSourav07#1112)
## Description Added WebP export support for generated dashboard badges. Fixes JhaSourav07#1002 ## Pillar * [x] Other (Bug fix, refactoring, docs) ## Checklist - [x] Code follows the project style guidelines - [x] Tested the feature locally - [x] No breaking changes introduced - [x] Linked the PR to the assigned issue ## Changes Made * Added handleDownloadWEBP export handler * Integrated WebP option into the ShareSheet export menu * Added .webp image generation using `toCanvas()` and `canvas.toDataURL('image/webp')` ## Result Users can now export optimized WebP images with improved compression and better compatibility for modern platforms while preserving dashboard visuals.
1 parent d6e94fc commit 7311512

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

components/dashboard/ShareSheet.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export default function ShareSheet({ username, isOpen, onClose, exportData }: Sh
5656
handleLinkedIn,
5757
handleReddit,
5858
handleDownloadPNG,
59+
handleDownloadWEBP,
5960
handleDownloadSVG,
6061
handleCopyMarkdown,
6162
handleDownloadJSON,
@@ -180,6 +181,15 @@ endsolid commitpulse_monolith`;
180181
glow: 'transparent',
181182
action: handleDownloadPNG,
182183
},
184+
{
185+
key: 'webp',
186+
icon: Download,
187+
label: 'Download as WebP',
188+
description: 'Download optimized WebP image',
189+
gradient: 'bg-zinc-800',
190+
glow: 'transparent',
191+
action: handleDownloadWEBP,
192+
},
183193
{
184194
key: 'svg',
185195
icon: Download,

hooks/useShareActions.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use client';
22
import { useState, useRef, useEffect } from 'react';
3-
import { toPng } from 'html-to-image';
3+
import { toPng, toCanvas } from 'html-to-image';
44
import type { DashboardExportData } from '@/types/dashboard';
55

66
type OptionState = 'idle' | 'loading' | 'success' | 'error';
@@ -104,6 +104,38 @@ export function useShareActions(
104104
}
105105
};
106106

107+
const handleDownloadWEBP = async () => {
108+
setOptionState('webp', 'loading');
109+
try {
110+
const node =
111+
document.getElementById('dashboard-root') ??
112+
document.querySelector<HTMLElement>('[data-dashboard]') ??
113+
document.body;
114+
const isDark =
115+
typeof document !== 'undefined' && document.documentElement.classList.contains('dark');
116+
const canvas = await toCanvas(node, {
117+
quality: 0.95,
118+
pixelRatio: 2,
119+
backgroundColor: isDark ? '#050505' : '#ffffff',
120+
filter: (el) => {
121+
if (el instanceof HTMLElement) {
122+
if (el.id === 'share-sheet-overlay') return false;
123+
if (el.id === 'generate-dashboard-btn') return false;
124+
}
125+
return true;
126+
},
127+
});
128+
const dataUrl = canvas.toDataURL('image/webp');
129+
const link = document.createElement('a');
130+
link.download = `${username}-commitpulse.webp`;
131+
link.href = dataUrl;
132+
link.click();
133+
setOptionState('webp', 'success');
134+
} catch {
135+
setOptionState('webp', 'error');
136+
}
137+
};
138+
107139
const handleDownloadSVG = async () => {
108140
setOptionState('svg', 'loading');
109141
try {
@@ -192,6 +224,7 @@ export function useShareActions(
192224
handleLinkedIn,
193225
handleReddit,
194226
handleDownloadPNG,
227+
handleDownloadWEBP,
195228
handleDownloadSVG,
196229
handleCopyMarkdown,
197230
handleDownloadJSON,

0 commit comments

Comments
 (0)