@pie-players/pie-section-player-tools-session-debugger 0.3.3 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -12,6 +12,14 @@
12
12
 
13
13
  <script lang="ts">
14
14
  import '@pie-players/pie-theme/components.css';
15
+ import PanelResizeHandle from '@pie-players/pie-section-player-tools-shared/PanelResizeHandle.svelte';
16
+ import PanelWindowControls from '@pie-players/pie-section-player-tools-shared/PanelWindowControls.svelte';
17
+ import {
18
+ computePanelSizeFromViewport,
19
+ createFloatingPanelPointerController,
20
+ getSectionControllerFromCoordinator,
21
+ isMatchingSectionControllerLifecycleEvent
22
+ } from '@pie-players/pie-section-player-tools-shared';
15
23
  import { createEventDispatcher } from 'svelte';
16
24
  import { onMount } from 'svelte';
17
25
  const dispatch = createEventDispatcher<{ close: undefined }>();
@@ -60,17 +68,6 @@
60
68
  let sessionWindowY = $state(100);
61
69
  let sessionWindowWidth = $state(220);
62
70
  let sessionWindowHeight = $state(600);
63
- let isSessionDragging = $state(false);
64
- let isSessionResizing = $state(false);
65
-
66
- let dragStartX = 0;
67
- let dragStartY = 0;
68
- let dragStartWindowX = 0;
69
- let dragStartWindowY = 0;
70
- let resizeStartX = 0;
71
- let resizeStartY = 0;
72
- let resizeStartWidth = 0;
73
- let resizeStartHeight = 0;
74
71
 
75
72
  let sessionPanelSnapshot = $state<SessionPanelSnapshot>({
76
73
  currentItemIndex: null,
@@ -100,8 +97,13 @@
100
97
  }
101
98
 
102
99
  function getController(): SectionControllerLike | undefined {
103
- if (!toolkitCoordinator || !sectionId) return undefined;
104
- return toolkitCoordinator.getSectionController?.({ sectionId, attemptId });
100
+ return (
101
+ getSectionControllerFromCoordinator(
102
+ toolkitCoordinator,
103
+ sectionId,
104
+ attemptId
105
+ ) || undefined
106
+ );
105
107
  }
106
108
 
107
109
  function refreshFromController(
@@ -195,10 +197,7 @@
195
197
  ensureControllerSubscription();
196
198
  detachLifecycleSubscription();
197
199
  unsubscribeLifecycle = toolkitCoordinator.onSectionControllerLifecycle?.((event) => {
198
- const eventSectionId = event?.key?.sectionId || '';
199
- const eventAttemptId = event?.key?.attemptId || undefined;
200
- if (eventSectionId !== sectionId) return;
201
- if ((eventAttemptId || undefined) !== (attemptId || undefined)) return;
200
+ if (!isMatchingSectionControllerLifecycleEvent(event, sectionId, attemptId)) return;
202
201
  ensureControllerSubscription();
203
202
  refreshFromController({
204
203
  updatedAt: Date.now()
@@ -211,13 +210,25 @@
211
210
  });
212
211
 
213
212
  onMount(() => {
214
- const clamp = (value: number, min: number, max: number) => Math.max(min, Math.min(value, max));
215
- const viewportWidth = window.innerWidth;
216
- const viewportHeight = window.innerHeight;
217
- sessionWindowWidth = clamp(Math.round(viewportWidth * 0.29), 280, 560);
218
- sessionWindowHeight = clamp(Math.round(viewportHeight * 0.72), 360, 860);
219
- sessionWindowX = Math.max(16, Math.round(viewportWidth * 0.08));
220
- sessionWindowY = Math.max(16, Math.round((viewportHeight - sessionWindowHeight) / 2));
213
+ const initial = computePanelSizeFromViewport(
214
+ { width: window.innerWidth, height: window.innerHeight },
215
+ {
216
+ widthRatio: 0.29,
217
+ heightRatio: 0.72,
218
+ minWidth: 280,
219
+ maxWidth: 560,
220
+ minHeight: 360,
221
+ maxHeight: 860,
222
+ alignX: 'left',
223
+ alignY: 'center',
224
+ paddingX: 16,
225
+ paddingY: 16
226
+ }
227
+ );
228
+ sessionWindowX = initial.x;
229
+ sessionWindowY = initial.y;
230
+ sessionWindowWidth = initial.width;
231
+ sessionWindowHeight = initial.height;
221
232
 
222
233
  const handleRuntimeSessionEvent = () => {
223
234
  queueRefresh({
@@ -234,65 +245,26 @@
234
245
  };
235
246
  });
236
247
 
237
- function startSessionDrag(e: MouseEvent) {
238
- isSessionDragging = true;
239
- dragStartX = e.clientX;
240
- dragStartY = e.clientY;
241
- dragStartWindowX = sessionWindowX;
242
- dragStartWindowY = sessionWindowY;
243
-
244
- document.addEventListener('mousemove', onSessionDrag);
245
- document.addEventListener('mouseup', stopSessionDrag);
246
- }
247
-
248
- function onSessionDrag(e: MouseEvent) {
249
- if (!isSessionDragging) return;
250
- const deltaX = e.clientX - dragStartX;
251
- const deltaY = e.clientY - dragStartY;
252
- sessionWindowX = dragStartWindowX + deltaX;
253
- sessionWindowY = dragStartWindowY + deltaY;
254
- sessionWindowX = Math.max(0, Math.min(sessionWindowX, window.innerWidth - sessionWindowWidth));
255
- sessionWindowY = Math.max(0, Math.min(sessionWindowY, window.innerHeight - 100));
256
- }
257
-
258
- function stopSessionDrag() {
259
- isSessionDragging = false;
260
- document.removeEventListener('mousemove', onSessionDrag);
261
- document.removeEventListener('mouseup', stopSessionDrag);
262
- }
263
-
264
- function startSessionResize(e: MouseEvent) {
265
- isSessionResizing = true;
266
- resizeStartX = e.clientX;
267
- resizeStartY = e.clientY;
268
- resizeStartWidth = sessionWindowWidth;
269
- resizeStartHeight = sessionWindowHeight;
270
- document.addEventListener('mousemove', onSessionResize);
271
- document.addEventListener('mouseup', stopSessionResize);
272
- e.stopPropagation();
273
- }
274
-
275
- function onSessionResize(e: MouseEvent) {
276
- if (!isSessionResizing) return;
277
- const deltaX = e.clientX - resizeStartX;
278
- const deltaY = e.clientY - resizeStartY;
279
- sessionWindowWidth = Math.max(300, Math.min(resizeStartWidth + deltaX, window.innerWidth - sessionWindowX));
280
- sessionWindowHeight = Math.max(
281
- 200,
282
- Math.min(resizeStartHeight + deltaY, window.innerHeight - sessionWindowY)
283
- );
284
- }
285
-
286
- function stopSessionResize() {
287
- isSessionResizing = false;
288
- document.removeEventListener('mousemove', onSessionResize);
289
- document.removeEventListener('mouseup', stopSessionResize);
290
- }
248
+ const pointerController = createFloatingPanelPointerController({
249
+ getState: () => ({
250
+ x: sessionWindowX,
251
+ y: sessionWindowY,
252
+ width: sessionWindowWidth,
253
+ height: sessionWindowHeight
254
+ }),
255
+ setState: (next) => {
256
+ sessionWindowX = next.x;
257
+ sessionWindowY = next.y;
258
+ sessionWindowWidth = next.width;
259
+ sessionWindowHeight = next.height;
260
+ },
261
+ minWidth: 300,
262
+ minHeight: 200
263
+ });
291
264
 
292
265
  $effect(() => {
293
266
  return () => {
294
- stopSessionDrag();
295
- stopSessionResize();
267
+ pointerController.stop();
296
268
  };
297
269
  });
298
270
  </script>
@@ -303,7 +275,7 @@
303
275
  >
304
276
  <div
305
277
  class="pie-section-player-tools-session-debugger__header"
306
- onmousedown={startSessionDrag}
278
+ onmousedown={(event: MouseEvent) => pointerController.startDrag(event)}
307
279
  role="button"
308
280
  tabindex="0"
309
281
  aria-label="Drag session panel"
@@ -321,49 +293,16 @@
321
293
  <h3 class="pie-section-player-tools-session-debugger__title">Session Data</h3>
322
294
  </div>
323
295
  <div class="pie-section-player-tools-session-debugger__header-actions">
324
- <button
325
- class="pie-section-player-tools-session-debugger__icon-button"
326
- onclick={() => (isSessionMinimized = !isSessionMinimized)}
327
- title={isSessionMinimized ? 'Maximize' : 'Minimize'}
328
- >
329
- {#if isSessionMinimized}
330
- <svg
331
- xmlns="http://www.w3.org/2000/svg"
332
- class="pie-section-player-tools-session-debugger__icon-xs"
333
- fill="none"
334
- viewBox="0 0 24 24"
335
- stroke="currentColor"
336
- >
337
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 15l7-7 7 7" />
338
- </svg>
339
- {:else}
340
- <svg
341
- xmlns="http://www.w3.org/2000/svg"
342
- class="pie-section-player-tools-session-debugger__icon-xs"
343
- fill="none"
344
- viewBox="0 0 24 24"
345
- stroke="currentColor"
346
- >
347
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
348
- </svg>
349
- {/if}
350
- </button>
351
- <button class="pie-section-player-tools-session-debugger__icon-button" onclick={() => dispatch('close')} title="Close">
352
- <svg
353
- xmlns="http://www.w3.org/2000/svg"
354
- class="pie-section-player-tools-session-debugger__icon-xs"
355
- fill="none"
356
- viewBox="0 0 24 24"
357
- stroke="currentColor"
358
- >
359
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
360
- </svg>
361
- </button>
296
+ <PanelWindowControls
297
+ minimized={isSessionMinimized}
298
+ onToggle={() => (isSessionMinimized = !isSessionMinimized)}
299
+ onClose={() => dispatch('close')}
300
+ />
362
301
  </div>
363
302
  </div>
364
303
 
365
304
  {#if !isSessionMinimized}
366
- <div class="pie-section-player-tools-session-debugger__content-shell" style="height: {sessionWindowHeight - 60}px;">
305
+ <div class="pie-section-player-tools-session-debugger__content-shell" style="height: {sessionWindowHeight - 50}px;">
367
306
  <div class="pie-section-player-tools-session-debugger__content">
368
307
  <div class="pie-section-player-tools-session-debugger__section-intro">
369
308
  <div class="pie-section-player-tools-session-debugger__heading">PIE Session Data (Persistent)</div>
@@ -406,18 +345,64 @@
406
345
  {/if}
407
346
 
408
347
  {#if !isSessionMinimized}
409
- <div
410
- class="pie-section-player-tools-session-debugger__resize-handle"
411
- onmousedown={startSessionResize}
412
- role="button"
413
- tabindex="0"
414
- title="Resize window"
415
- >
416
- <svg class="pie-section-player-tools-session-debugger__resize-icon" viewBox="0 0 16 16" fill="currentColor">
417
- <path d="M16 16V14H14V16H16Z" />
418
- <path d="M16 11V9H14V11H16Z" />
419
- <path d="M13 16V14H11V16H13Z" />
420
- </svg>
421
- </div>
348
+ <PanelResizeHandle onPointerDown={(event: MouseEvent) => pointerController.startResize(event)} />
422
349
  {/if}
423
350
  </div>
351
+
352
+ <style>
353
+ .pie-section-player-tools-session-debugger {
354
+ position: fixed;
355
+ z-index: 9999;
356
+ background: var(--color-base-100, #fff);
357
+ color: var(--color-base-content, #1f2937);
358
+ border: 2px solid var(--color-base-300, #d1d5db);
359
+ border-radius: 8px;
360
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
361
+ overflow: hidden;
362
+ font-family: var(--pie-font-family, Inter, system-ui, sans-serif);
363
+ }
364
+
365
+ .pie-section-player-tools-session-debugger__header {
366
+ padding: 8px 16px;
367
+ display: flex;
368
+ align-items: center;
369
+ justify-content: space-between;
370
+ background: var(--color-base-200, #f3f4f6);
371
+ cursor: move;
372
+ user-select: none;
373
+ border-bottom: 1px solid var(--color-base-300, #d1d5db);
374
+ }
375
+
376
+ .pie-section-player-tools-session-debugger__header-title {
377
+ display: flex;
378
+ align-items: center;
379
+ gap: 8px;
380
+ }
381
+
382
+ .pie-section-player-tools-session-debugger__icon-sm {
383
+ width: 1rem;
384
+ height: 1rem;
385
+ }
386
+
387
+ .pie-section-player-tools-session-debugger__title {
388
+ margin: 0;
389
+ font-size: 0.95rem;
390
+ font-weight: 700;
391
+ }
392
+
393
+ .pie-section-player-tools-session-debugger__header-actions {
394
+ display: flex;
395
+ gap: 4px;
396
+ }
397
+
398
+ .pie-section-player-tools-session-debugger__content-shell {
399
+ display: flex;
400
+ flex-direction: column;
401
+ min-height: 0;
402
+ }
403
+
404
+ .pie-section-player-tools-session-debugger__resize-handle {
405
+ user-select: none;
406
+ }
407
+
408
+ </style>