1
0
mirror of https://github.com/avinal/avinal.github.io.git synced 2026-07-03 23:30:09 +05:30

fix: update wakatime graph and now playing

Signed-off-by: Avinal Kumar <avinal.xlvii@gmail.com>
This commit is contained in:
2026-03-17 21:27:07 +05:30
committed by Morumotto
parent cda0b2e6be
commit 6e7b3c86ee
3 changed files with 27 additions and 30 deletions
+1 -1
View File
@@ -112,7 +112,7 @@ const hasWaka = activity.wakatime.available;
{hasWaka && ( {hasWaka && (
<Fragment> <Fragment>
<div class="stat-item waka"> <div class="stat-item waka">
<dt>Coded (year)</dt> <dt>Tracked (year)</dt>
<dd>{activity.wakatime.totalText}</dd> <dd>{activity.wakatime.totalText}</dd>
</div> </div>
<div class="stat-item waka"> <div class="stat-item waka">
+11 -7
View File
@@ -23,16 +23,15 @@ const hero = lb.nowPlaying ?? lb.recentTracks[0] ?? null;
<div class="mc card" id="music-widget" data-user={lb.username} data-live={isLive ? "1" : "0"}> <div class="mc card" id="music-widget" data-user={lb.username} data-live={isLive ? "1" : "0"}>
<div class="mc-header"> <div class="mc-header">
<h3 class="widget-title"> <a href={profileUrl} target="_blank" rel="noopener noreferrer" class="widget-title mc-link" aria-label="ListenBrainz profile">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></svg> <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 18V5l12-2v13"/><circle cx="6" cy="18" r="3"/><circle cx="18" cy="16" r="3"/></svg>
<a href={profileUrl} target="_blank" rel="noopener noreferrer" class="mc-link">Listening</a> </a>
</h3>
</div> </div>
<div class="mc-body" id="mc-body"> <div class="mc-body" id="mc-body">
{hero ? ( {hero ? (
<> <>
<div class="mc-hero" id="mc-hero"> <a href={profileUrl} target="_blank" rel="noopener noreferrer" class="mc-hero" id="mc-hero">
<div class="mc-art-wrap"> <div class="mc-art-wrap">
<img <img
class="mc-art" class="mc-art"
@@ -52,7 +51,7 @@ const hero = lb.nowPlaying ?? lb.recentTracks[0] ?? null;
<span class="mc-marquee" id="mc-marquee">{hero.trackName} &mdash; {hero.artistName}</span> <span class="mc-marquee" id="mc-marquee">{hero.trackName} &mdash; {hero.artistName}</span>
</div> </div>
</div> </div>
</div> </a>
<ul class="mc-recent" id="mc-recent"> <ul class="mc-recent" id="mc-recent">
{lb.recentTracks.slice(0, 4).map((t) => ( {lb.recentTracks.slice(0, 4).map((t) => (
@@ -115,9 +114,13 @@ const hero = lb.nowPlaying ?? lb.recentTracks[0] ?? null;
/* ---- Hero: art + overlay ---- */ /* ---- Hero: art + overlay ---- */
.mc-hero { .mc-hero {
display: block;
text-decoration: none;
color: inherit;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
border-radius: var(--radius-sm); border-radius: var(--radius-sm);
cursor: pointer;
flex-shrink: 0; flex-shrink: 0;
} }
@@ -391,8 +394,9 @@ const hero = lb.nowPlaying ?? lb.recentTracks[0] ?? null;
? `<span class="mc-dot"></span>playing` ? `<span class="mc-dot"></span>playing`
: "last played"; : "last played";
const profileHref = `https://listenbrainz.org/user/${widget.dataset.user}`;
return ` return `
<div class="mc-hero"> <a class="mc-hero" href="${profileHref}" target="_blank" rel="noopener noreferrer">
<div class="mc-art-wrap"> <div class="mc-art-wrap">
${cover ? `<img class="mc-art" src="${cover}" alt="" data-track="${track}" data-artist="${artist}" />` : `<img class="mc-art" src="" alt="" data-track="${track}" data-artist="${artist}" data-no-cover="1" style="display:none" />`} ${cover ? `<img class="mc-art" src="${cover}" alt="" data-track="${track}" data-artist="${artist}" />` : `<img class="mc-art" src="" alt="" data-track="${track}" data-artist="${artist}" data-no-cover="1" style="display:none" />`}
<div class="mc-art-ph"> <div class="mc-art-ph">
@@ -405,7 +409,7 @@ const hero = lb.nowPlaying ?? lb.recentTracks[0] ?? null;
<span class="mc-marquee">${marqueeText}${isLive ? `&nbsp;&nbsp;&nbsp;&nbsp;${marqueeText}` : ""}</span> <span class="mc-marquee">${marqueeText}${isLive ? `&nbsp;&nbsp;&nbsp;&nbsp;${marqueeText}` : ""}</span>
</div> </div>
</div> </div>
</div>`; </a>`;
} }
function renderRecent(listens: any[]): string { function renderRecent(listens: any[]): string {
+15 -22
View File
@@ -27,13 +27,8 @@ interface RawDay {
categories?: RawCategory[]; categories?: RawCategory[];
} }
const EXCLUDED_CATEGORIES = new Set(["Browsing"]); function totalSeconds(day: RawDay): number {
return day.total ?? 0;
function codingSeconds(categories: RawCategory[] | undefined): number {
if (!categories) return 0;
return categories
.filter((c) => !EXCLUDED_CATEGORIES.has(c.name))
.reduce((sum, c) => sum + (c.total ?? 0), 0);
} }
function formatSeconds(s: number): string { function formatSeconds(s: number): string {
@@ -54,32 +49,30 @@ export async function fetchWakaTimeData(): Promise<WakaTimeData | null> {
if (rawDays.length === 0) return null; if (rawDays.length === 0) return null;
const days = new Map<string, WakaTimeDaySummary>(); const days = new Map<string, WakaTimeDaySummary>();
let codingTotal = 0; let total = 0;
let fullTotal = 0; let bestDay = 0;
let bestCodingDay = 0; let activeDays = 0;
let codingActiveDays = 0;
for (const d of rawDays) { for (const d of rawDays) {
const coding = codingSeconds(d.categories); const secs = totalSeconds(d);
fullTotal += d.total ?? 0; total += secs;
codingTotal += coding; if (secs > bestDay) bestDay = secs;
if (coding > bestCodingDay) bestCodingDay = coding; if (secs > 0) activeDays++;
if (coding > 0) codingActiveDays++;
days.set(d.date, { days.set(d.date, {
date: d.date, date: d.date,
totalSeconds: coding, totalSeconds: secs,
text: coding > 0 ? formatSeconds(coding) : "0m", text: secs > 0 ? formatSeconds(secs) : "0m",
}); });
} }
const dailyAvg = codingActiveDays > 0 ? codingTotal / codingActiveDays : 0; const dailyAvg = activeDays > 0 ? total / activeDays : 0;
return { return {
totalSeconds: codingTotal, totalSeconds: total,
totalText: formatSeconds(codingTotal), totalText: formatSeconds(total),
dailyAvgText: formatSeconds(dailyAvg), dailyAvgText: formatSeconds(dailyAvg),
bestDayText: formatSeconds(bestCodingDay), bestDayText: formatSeconds(bestDay),
days, days,
topLangs: [], topLangs: [],
}; };