Skip to content

Commit 2e1338c

Browse files
committed
fix: simplify delivery demo chrome and role toggle
Remove the delivery side control panel and make the player area single-pane, then add a Student|Scorer toggle next to Reset Input to mirror pie-players behavior. Made-with: Cursor
1 parent 46e30e2 commit 2e1338c

2 files changed

Lines changed: 40 additions & 137 deletions

File tree

apps/element-demo/src/lib/element-player/components/DeliveryPlayerLayout.svelte

Lines changed: 4 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,9 @@
22
/**
33
* Delivery Player Layout Component
44
*
5-
* Extended layout with mode/role/session/model controls for delivery view.
5+
* Delivery layout wrapper for the element player.
66
*/
77
import { onMount } from 'svelte';
8-
import { page } from '$app/stores';
9-
import ModeSelector from './ModeSelector.svelte';
10-
import SessionPanel from './SessionPanel.svelte';
11-
import ScoringPanel from './ScoringPanel.svelte';
12-
import ModelPanel from './ModelPanel.svelte';
138
import { loadController } from '../lib/demo-element-loader';
149
import type { PieController } from '../lib/types';
1510
import type { PlayerType } from '$lib/config/player-runtime';
@@ -44,44 +39,15 @@ let {
4439
// State
4540
let loading = $state(true);
4641
let error = $state<string | null>(null);
47-
let score = $state<any>(null);
4842
let controllerWarning = $state<string | null>(null);
49-
let roleLocked = $state(false);
50-
let splitRatio = $state(50);
5143
5244
// Effects
5345
$effect(() => {
54-
roleLocked = mode === 'evaluate';
5546
if (playerRole !== 'instructor' && mode === 'evaluate') {
5647
mode = 'view';
5748
}
5849
});
5950
60-
// Call controller in evaluate mode
61-
$effect(() => {
62-
if (mode === 'evaluate' && controller && model && session) {
63-
if (debug) console.log('[delivery-player-layout] Calling controller.score()');
64-
65-
const scoreMethod = controller.score || controller.outcome;
66-
67-
if (scoreMethod) {
68-
scoreMethod(model, session, { mode, role: playerRole, partialScoring })
69-
.then((result: any) => {
70-
score = result;
71-
if (debug) console.log('[delivery-player-layout] Score result:', result);
72-
})
73-
.catch((err: any) => {
74-
console.error('[delivery-player-layout] Scoring error:', err);
75-
if (debug) score = { error: err.message };
76-
});
77-
} else {
78-
console.warn('[delivery-player-layout] Controller has no score or outcome method');
79-
}
80-
} else {
81-
score = null;
82-
}
83-
});
84-
8551
onMount(async () => {
8652
try {
8753
if (!elementName) {
@@ -113,47 +79,10 @@ onMount(async () => {
11379
}
11480
});
11581
116-
function handleSplitPointerDown(event: PointerEvent) {
117-
const container = (event.currentTarget as HTMLElement)?.parentElement;
118-
if (!container) return;
119-
120-
event.preventDefault();
121-
const target = event.currentTarget as HTMLElement;
122-
target.setPointerCapture(event.pointerId);
123-
124-
const startX = event.clientX;
125-
const startRatio = splitRatio;
126-
const rect = container.getBoundingClientRect();
127-
128-
const onMove = (moveEvent: PointerEvent) => {
129-
const delta = moveEvent.clientX - startX;
130-
const next = ((startRatio / 100) * rect.width + delta) / rect.width;
131-
splitRatio = Math.min(80, Math.max(20, Math.round(next * 100)));
132-
};
133-
134-
const onUp = () => {
135-
target.releasePointerCapture(event.pointerId);
136-
document.body.style.cursor = '';
137-
window.removeEventListener('pointermove', onMove);
138-
window.removeEventListener('pointerup', onUp);
139-
};
140-
141-
document.body.style.cursor = 'col-resize';
142-
window.addEventListener('pointermove', onMove);
143-
window.addEventListener('pointerup', onUp);
144-
}
145-
14682
function handleModelApply(nextModel: any) {
14783
// Model updates are handled by the store in parent routes
14884
console.log('[delivery-player-layout] Model apply requested:', nextModel);
14985
}
150-
151-
// Build URL for role change, preserving other params
152-
function getRoleUrl(newRole: 'student' | 'instructor'): string {
153-
const url = new URL($page.url);
154-
url.searchParams.set('role', newRole);
155-
return url.pathname + url.search;
156-
}
15786
</script>
15887

15988
<div class="layout-container">
@@ -182,56 +111,10 @@ function getRoleUrl(newRole: 'student' | 'instructor'): string {
182111
</div>
183112
{/if}
184113

185-
<div class="player-content" style={`grid-template-columns: ${splitRatio}% 12px ${100 - splitRatio}%`}>
186-
<main class="min-w-0 pr-3 overflow-auto">
114+
<div class="player-content">
115+
<main class="flex-1 min-w-0 overflow-auto">
187116
{@render children?.()}
188117
</main>
189-
190-
<div class="divider divider-horizontal cursor-col-resize" onpointerdown={handleSplitPointerDown} role="separator" aria-orientation="vertical"></div>
191-
192-
<aside class="min-w-0 pl-3 overflow-auto space-y-4">
193-
<div class="card bg-base-100 border border-base-300">
194-
<div class="card-body p-4">
195-
<h3 class="card-title text-sm uppercase text-base-content/60">Mode</h3>
196-
<ModeSelector bind:mode evaluateDisabled={playerRole !== 'instructor'} />
197-
</div>
198-
</div>
199-
200-
<div class="card bg-base-100 border border-base-300">
201-
<div class="card-body p-4">
202-
<h3 class="card-title text-sm uppercase text-base-content/60">Role</h3>
203-
<div class="flex flex-col gap-2">
204-
<a
205-
href={getRoleUrl('student')}
206-
data-sveltekit-reload
207-
class="btn btn-sm justify-start"
208-
class:btn-primary={playerRole === 'student'}
209-
class:btn-outline={playerRole !== 'student'}
210-
class:btn-disabled={roleLocked}
211-
aria-disabled={roleLocked}
212-
tabindex={roleLocked ? -1 : 0}
213-
data-testid="role-student"
214-
>
215-
Student
216-
</a>
217-
<a
218-
href={getRoleUrl('instructor')}
219-
data-sveltekit-reload
220-
class="btn btn-sm justify-start"
221-
class:btn-primary={playerRole === 'instructor'}
222-
class:btn-outline={playerRole !== 'instructor'}
223-
data-testid="role-instructor"
224-
>
225-
Instructor
226-
</a>
227-
</div>
228-
</div>
229-
</div>
230-
231-
<SessionPanel {session} />
232-
233-
<ScoringPanel {score} />
234-
</aside>
235118
</div>
236119
{/if}
237120
</div>
@@ -245,25 +128,9 @@ function getRoleUrl(newRole: 'student' | 'instructor'): string {
245128
}
246129
247130
.player-content {
248-
display: grid;
131+
display: flex;
249132
flex: 1;
250133
min-height: 0;
251134
overflow: hidden;
252135
}
253-
254-
.player-content > main,
255-
.player-content > aside {
256-
min-height: 0; /* Allow grid children to shrink below content size */
257-
}
258-
259-
/* Responsive */
260-
@media (max-width: 900px) {
261-
.player-content {
262-
grid-template-columns: 1fr !important;
263-
}
264-
265-
.divider-horizontal {
266-
display: none;
267-
}
268-
}
269136
</style>

apps/element-demo/src/routes/[element]/+layout.svelte

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,18 @@ function resetDemoSessionFromToolbar() {
254254
}
255255
}
256256
257+
function getDeliveryRoleModeUrl(viewMode: 'student' | 'scorer') {
258+
const url = new URL($page.url);
259+
if (viewMode === 'student') {
260+
url.searchParams.set('role', 'student');
261+
url.searchParams.set('mode', 'gather');
262+
} else {
263+
url.searchParams.set('role', 'instructor');
264+
url.searchParams.set('mode', 'evaluate');
265+
}
266+
return url.pathname + url.search;
267+
}
268+
257269
// Bidirectional sync: URL ↔ stores
258270
$effect(() => {
259271
const isDeliverRoute = $page.url.pathname.endsWith('/deliver');
@@ -352,6 +364,30 @@ function handleThemeToggle(event: Event) {
352364
>
353365
Reset Input
354366
</button>
367+
<div class="join" aria-label="Demo role mode">
368+
<a
369+
href={getDeliveryRoleModeUrl('student')}
370+
data-sveltekit-reload
371+
class="btn btn-sm join-item"
372+
class:btn-active={$role === 'student' && $mode === 'gather'}
373+
aria-current={$role === 'student' && $mode === 'gather' ? 'page' : undefined}
374+
title="Student view - gather mode"
375+
data-testid="role-student"
376+
>
377+
Student
378+
</a>
379+
<a
380+
href={getDeliveryRoleModeUrl('scorer')}
381+
data-sveltekit-reload
382+
class="btn btn-sm join-item"
383+
class:btn-active={$role === 'instructor' && $mode === 'evaluate'}
384+
aria-current={$role === 'instructor' && $mode === 'evaluate' ? 'page' : undefined}
385+
title="Scorer view - evaluate mode"
386+
data-testid="role-instructor"
387+
>
388+
Scorer
389+
</a>
390+
</div>
355391
{/if}
356392
</div>
357393

0 commit comments

Comments
 (0)