Skip to content

Commit cf7b546

Browse files
the-non-expertJayantDevkarclaude
authored
fix: remove live-status coloring from historical session cards, add v… (#51)
* fix: remove live-status coloring from historical session cards, add view-mode-aware skeletons and LIVE NOW skeleton section * refactor: extract isGrid/gridClass derived helpers to deduplicate grid class strings Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Jayant Devkar <55962509+JayantDevkar@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 406b47a commit cf7b546

5 files changed

Lines changed: 142 additions & 30 deletions

File tree

frontend/src/lib/components/skeleton/SessionsPageSkeleton.svelte

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,20 @@
22
import SkeletonBox from './SkeletonBox.svelte';
33
import SkeletonText from './SkeletonText.svelte';
44
import SkeletonGlobalSessionCard from './SkeletonGlobalSessionCard.svelte';
5+
import SkeletonLiveSessionsSection from './SkeletonLiveSessionsSection.svelte';
6+
7+
interface Props {
8+
viewMode?: 'list' | 'grid';
9+
}
10+
11+
let { viewMode = 'list' }: Props = $props();
12+
13+
const isGrid = $derived(viewMode === 'grid');
14+
const gridClass = $derived(
15+
isGrid
16+
? 'grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2'
17+
: 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3'
18+
);
519
</script>
620

721
<div>
@@ -37,6 +51,9 @@
3751
<SkeletonBox width="80px" height="36px" rounded="md" />
3852
</div>
3953

54+
<!-- LIVE NOW Section -->
55+
<SkeletonLiveSessionsSection />
56+
4057
<!-- Day-based Groups -->
4158
<div class="space-y-8">
4259
<!-- Today Group -->
@@ -45,9 +62,9 @@
4562
<SkeletonText width="50px" size="sm" />
4663
<SkeletonText width="30px" size="xs" />
4764
</div>
48-
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
65+
<div class={gridClass}>
4966
{#each Array(3) as _}
50-
<SkeletonGlobalSessionCard />
67+
<SkeletonGlobalSessionCard compact={isGrid} />
5168
{/each}
5269
</div>
5370
</div>
@@ -58,9 +75,9 @@
5875
<SkeletonText width="80px" size="sm" />
5976
<SkeletonText width="30px" size="xs" />
6077
</div>
61-
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
78+
<div class={gridClass}>
6279
{#each Array(3) as _}
63-
<SkeletonGlobalSessionCard />
80+
<SkeletonGlobalSessionCard compact={isGrid} />
6481
{/each}
6582
</div>
6683
</div>
@@ -71,9 +88,9 @@
7188
<SkeletonText width="50px" size="sm" />
7289
<SkeletonText width="30px" size="xs" />
7390
</div>
74-
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
91+
<div class={gridClass}>
7592
{#each Array(2) as _}
76-
<SkeletonGlobalSessionCard />
93+
<SkeletonGlobalSessionCard compact={isGrid} />
7794
{/each}
7895
</div>
7996
</div>
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<script lang="ts">
2+
import SkeletonBox from './SkeletonBox.svelte';
3+
import SkeletonText from './SkeletonText.svelte';
4+
</script>
5+
6+
<div class="live-section mb-6">
7+
<!-- Header -->
8+
<div class="live-header">
9+
<div class="flex items-center gap-2">
10+
<div class="flex items-center gap-1.5">
11+
<!-- Chevron + Radio icon placeholders -->
12+
<SkeletonBox width="16px" height="16px" rounded="sm" />
13+
<SkeletonBox width="14px" height="14px" rounded="sm" />
14+
<span class="section-title">LIVE NOW</span>
15+
</div>
16+
<!-- Count badge -->
17+
<SkeletonBox width="80px" height="14px" rounded="sm" />
18+
</div>
19+
<!-- Pulse indicator -->
20+
<SkeletonBox width="8px" height="8px" rounded="full" />
21+
</div>
22+
23+
<!-- Session rows -->
24+
<div class="live-content">
25+
<div class="sessions-list">
26+
{#each Array(3) as _}
27+
<div class="session-row">
28+
<!-- Status dot -->
29+
<SkeletonBox width="8px" height="8px" rounded="full" class="mt-1.5 shrink-0" />
30+
<!-- Session info -->
31+
<div class="session-info">
32+
<div class="flex items-center gap-3">
33+
<SkeletonText width="120px" size="sm" />
34+
<SkeletonBox width="50px" height="12px" rounded="sm" />
35+
</div>
36+
<div class="flex items-center justify-between mt-1">
37+
<SkeletonText width="80px" size="xs" />
38+
<SkeletonText width="40px" size="xs" />
39+
</div>
40+
</div>
41+
</div>
42+
{/each}
43+
</div>
44+
</div>
45+
</div>
46+
47+
<style>
48+
.live-section {
49+
background: var(--bg-subtle);
50+
border: 1px solid var(--border);
51+
border-radius: var(--radius-md);
52+
overflow: hidden;
53+
}
54+
55+
.live-header {
56+
display: flex;
57+
justify-content: space-between;
58+
align-items: center;
59+
padding: 12px 16px;
60+
background: var(--bg-muted);
61+
}
62+
63+
.section-title {
64+
font-size: 11px;
65+
font-weight: 600;
66+
letter-spacing: 0.5px;
67+
color: var(--text-secondary);
68+
}
69+
70+
.live-content {
71+
border-top: 1px solid var(--border-subtle);
72+
}
73+
74+
.sessions-list {
75+
display: flex;
76+
flex-direction: column;
77+
}
78+
79+
.session-row {
80+
display: flex;
81+
align-items: flex-start;
82+
gap: 12px;
83+
padding: 12px 16px;
84+
border-bottom: 1px solid var(--border-subtle);
85+
}
86+
87+
.session-row:last-child {
88+
border-bottom: none;
89+
}
90+
91+
.session-info {
92+
flex: 1;
93+
min-width: 0;
94+
}
95+
</style>

frontend/src/lib/components/skeleton/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ export { default as SkillsPageSkeleton } from './SkillsPageSkeleton.svelte';
2626
export { default as PlansPageSkeleton } from './PlansPageSkeleton.svelte';
2727
export { default as PlanDetailSkeleton } from './PlanDetailSkeleton.svelte';
2828
export { default as SessionsPageSkeleton } from './SessionsPageSkeleton.svelte';
29+
export { default as SkeletonLiveSessionsSection } from './SkeletonLiveSessionsSection.svelte';
2930
export { default as HooksPageSkeleton } from './HooksPageSkeleton.svelte';
3031
export { default as ArchivedPageSkeleton } from './ArchivedPageSkeleton.svelte';

frontend/src/routes/+layout.svelte

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@
7575
return null;
7676
});
7777
78+
// Read saved view mode from localStorage for sessions skeleton
79+
const savedViewMode = $derived.by((): 'list' | 'grid' => {
80+
if (navigationSkeletonType !== 'sessions') return 'list';
81+
if (typeof window === 'undefined') return 'list';
82+
const saved = localStorage.getItem('claude-code-karma-sessions-view-mode');
83+
return saved === 'grid' ? 'grid' : 'list';
84+
});
85+
7886
// Register WebMCP tools for AI agent access (Chrome 146+, no-op otherwise)
7987
$effect(() => {
8088
registerWebMCPTools();
@@ -149,7 +157,7 @@
149157
{:else if navigationSkeletonType === 'plan-detail'}
150158
<PlanDetailSkeleton />
151159
{:else if navigationSkeletonType === 'sessions'}
152-
<SessionsPageSkeleton />
160+
<SessionsPageSkeleton viewMode={savedViewMode} />
153161
{:else if navigationSkeletonType === 'hooks'}
154162
<HooksPageSkeleton />
155163
{/if}

frontend/src/routes/sessions/+page.svelte

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,9 @@
6565
hasActiveFilters as checkHasActiveFilters,
6666
filterSessionsByStatus,
6767
filterSessionsByDateRange,
68-
createLiveSessionLookup,
6968
calculateLiveStatusCounts,
7069
createHistoricalSessionLookup,
71-
shouldShowEndedStatus,
72-
type LiveSessionLookupFn
70+
shouldShowEndedStatus
7371
} from '$lib/search';
7472
import { getProjectNameFromEncoded } from '$lib/utils';
7573
@@ -151,16 +149,6 @@
151149
})
152150
);
153151
154-
// Unified live session lookup using shared utility (slug-first strategy)
155-
const getLiveSessionFn: LiveSessionLookupFn = $derived(
156-
createLiveSessionLookup(data.liveSessions)
157-
);
158-
159-
// Wrapper function for components that need function reference
160-
function getLiveSession(session: SessionWithContext): LiveSessionSummary | null {
161-
return getLiveSessionFn(session);
162-
}
163-
164152
// Unified historical session lookup using shared utility
165153
const getHistoricalSessionFn = $derived(createHistoricalSessionLookup(data.sessions));
166154
@@ -624,6 +612,14 @@
624612
}
625613
});
626614
615+
// Derived grid helpers (avoid duplicating class strings)
616+
const isGrid = $derived(viewMode === 'grid');
617+
const gridClass = $derived(
618+
isGrid
619+
? 'grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2'
620+
: 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3'
621+
);
622+
627623
// Dropdown state
628624
let showProjectDropdown = $state(false);
629625
@@ -1315,13 +1311,9 @@
13151311
</div>
13161312

13171313
<!-- Recently Ended Cards Grid - respects view mode -->
1318-
<div
1319-
class={viewMode === 'grid'
1320-
? 'grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2'
1321-
: 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3'}
1322-
>
1314+
<div class={gridClass}>
13231315
{#each recentlyEndedSessions as { session, liveSession } (session.uuid)}
1324-
<GlobalSessionCard {session} {liveSession} compact={viewMode === 'grid'} />
1316+
<GlobalSessionCard {session} {liveSession} compact={isGrid} />
13251317
{/each}
13261318
</div>
13271319
</div>
@@ -1336,9 +1328,9 @@
13361328
<div class="h-4 w-16 skeleton-shimmer rounded"></div>
13371329
<div class="h-3 w-8 skeleton-shimmer rounded"></div>
13381330
</div>
1339-
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
1331+
<div class={gridClass}>
13401332
{#each Array(6) as _}
1341-
<SkeletonGlobalSessionCard />
1333+
<SkeletonGlobalSessionCard compact={isGrid} />
13421334
{/each}
13431335
</div>
13441336
</div>
@@ -1405,7 +1397,7 @@
14051397
<!-- Session Cards Grid -->
14061398
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-3">
14071399
{#each group.sessions as session (session.uuid)}
1408-
<GlobalSessionCard {session} liveSession={getLiveSession(session)} />
1400+
<GlobalSessionCard {session} />
14091401
{/each}
14101402
</div>
14111403
</div>
@@ -1444,7 +1436,6 @@
14441436
<GlobalSessionCard
14451437
{session}
14461438
compact
1447-
liveSession={getLiveSession(session)}
14481439
/>
14491440
{/each}
14501441
</div>

0 commit comments

Comments
 (0)