@alliance-droid/status-feedback-system 1.2.0 → 1.3.0
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.
|
@@ -92,6 +92,35 @@
|
|
|
92
92
|
let screenshotData = $state<string | null>(null);
|
|
93
93
|
let capturingScreenshot = $state(false);
|
|
94
94
|
|
|
95
|
+
// Drag state
|
|
96
|
+
let isDragging = $state(false);
|
|
97
|
+
let dragOffsetX = 0;
|
|
98
|
+
let dragOffsetY = 0;
|
|
99
|
+
let modalX = $state(0);
|
|
100
|
+
let modalY = $state(0);
|
|
101
|
+
let modalPositioned = $state(false);
|
|
102
|
+
|
|
103
|
+
function handleDragStart(e: MouseEvent) {
|
|
104
|
+
isDragging = true;
|
|
105
|
+
const modalEl = (e.currentTarget as HTMLElement).closest('.sf-modal') as HTMLElement;
|
|
106
|
+
if (!modalEl) return;
|
|
107
|
+
const rect = modalEl.getBoundingClientRect();
|
|
108
|
+
dragOffsetX = e.clientX - rect.left;
|
|
109
|
+
dragOffsetY = e.clientY - rect.top;
|
|
110
|
+
e.preventDefault();
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function handleDragMove(e: MouseEvent) {
|
|
114
|
+
if (!isDragging) return;
|
|
115
|
+
modalX = e.clientX - dragOffsetX;
|
|
116
|
+
modalY = e.clientY - dragOffsetY;
|
|
117
|
+
modalPositioned = true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function handleDragEnd() {
|
|
121
|
+
isDragging = false;
|
|
122
|
+
}
|
|
123
|
+
|
|
95
124
|
// Console error capture
|
|
96
125
|
let consoleErrors: string[] = [];
|
|
97
126
|
let originalConsoleError: typeof console.error;
|
|
@@ -118,6 +147,9 @@
|
|
|
118
147
|
document.addEventListener('click', closeMenu);
|
|
119
148
|
// Escape closes everything
|
|
120
149
|
document.addEventListener('keydown', handleKeydown);
|
|
150
|
+
// Drag listeners (on document so drag continues outside modal)
|
|
151
|
+
document.addEventListener('mousemove', handleDragMove);
|
|
152
|
+
document.addEventListener('mouseup', handleDragEnd);
|
|
121
153
|
|
|
122
154
|
// Onboarding toast
|
|
123
155
|
if (showOnboarding && !localStorage.getItem(ONBOARDING_KEY)) {
|
|
@@ -133,6 +165,8 @@
|
|
|
133
165
|
document.removeEventListener('contextmenu', handleContextMenu);
|
|
134
166
|
document.removeEventListener('click', closeMenu);
|
|
135
167
|
document.removeEventListener('keydown', handleKeydown);
|
|
168
|
+
document.removeEventListener('mousemove', handleDragMove);
|
|
169
|
+
document.removeEventListener('mouseup', handleDragEnd);
|
|
136
170
|
});
|
|
137
171
|
|
|
138
172
|
function handleContextMenu(e: MouseEvent) {
|
|
@@ -218,6 +252,10 @@
|
|
|
218
252
|
submitResult = null;
|
|
219
253
|
menuOpen = false;
|
|
220
254
|
formOpen = true;
|
|
255
|
+
// Reset drag position (center on screen)
|
|
256
|
+
modalPositioned = false;
|
|
257
|
+
modalX = 0;
|
|
258
|
+
modalY = 0;
|
|
221
259
|
|
|
222
260
|
// Auto-capture screenshot for bugs
|
|
223
261
|
if (type === 'bug') {
|
|
@@ -334,34 +372,43 @@
|
|
|
334
372
|
|
|
335
373
|
<!-- Form modal -->
|
|
336
374
|
{#if formOpen}
|
|
337
|
-
<!--
|
|
338
|
-
<div
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
class="
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
<
|
|
360
|
-
|
|
375
|
+
<!-- No backdrop — modal floats freely over the page -->
|
|
376
|
+
<div
|
|
377
|
+
class="sf-modal fixed z-[99998] w-full max-w-lg flex flex-col"
|
|
378
|
+
style={modalPositioned
|
|
379
|
+
? `left: ${modalX}px; top: ${modalY}px;`
|
|
380
|
+
: 'left: 50%; top: 50%; transform: translate(-50%, -50%);'
|
|
381
|
+
}
|
|
382
|
+
>
|
|
383
|
+
<Card variant="elevated" padding="none" class="flex flex-col max-h-[calc(100vh-2rem)] overflow-hidden">
|
|
384
|
+
<!-- Header (fixed) -->
|
|
385
|
+
<!-- svelte-ignore a11y_no_static_element_interactions — drag handle needs mousedown -->
|
|
386
|
+
<div
|
|
387
|
+
class="flex items-center justify-between px-5 py-4 border-b border-border shrink-0 select-none"
|
|
388
|
+
style="cursor: {isDragging ? 'grabbing' : 'grab'};"
|
|
389
|
+
onmousedown={handleDragStart}
|
|
390
|
+
>
|
|
391
|
+
<div class="flex items-center gap-2">
|
|
392
|
+
{#if formType === 'bug'}
|
|
393
|
+
<i class="fa-solid fa-bug text-red-400"></i>
|
|
394
|
+
<h3 class="text-base font-semibold">Report Bug</h3>
|
|
395
|
+
{:else}
|
|
396
|
+
<i class="fa-solid fa-lightbulb text-amber-400"></i>
|
|
397
|
+
<h3 class="text-base font-semibold">Request Feature</h3>
|
|
398
|
+
{/if}
|
|
399
|
+
<Badge variant="neutral" size="sm">{getEnvironmentName()}</Badge>
|
|
361
400
|
</div>
|
|
401
|
+
<button
|
|
402
|
+
class="text-foreground-tertiary hover:text-foreground transition-colors bg-transparent border-none cursor-pointer text-lg"
|
|
403
|
+
onclick={() => (formOpen = false)}
|
|
404
|
+
aria-label="Close feedback form"
|
|
405
|
+
>
|
|
406
|
+
<i class="fa-solid fa-xmark"></i>
|
|
407
|
+
</button>
|
|
408
|
+
</div>
|
|
362
409
|
|
|
363
|
-
|
|
364
|
-
|
|
410
|
+
<!-- Body (scrollable) -->
|
|
411
|
+
<div class="p-5 space-y-4 overflow-y-auto">
|
|
365
412
|
{#if submitResult === 'success'}
|
|
366
413
|
<div class="text-center py-6">
|
|
367
414
|
<i class="fa-solid fa-check-circle text-3xl text-green-400"></i>
|
|
@@ -451,24 +498,27 @@
|
|
|
451
498
|
</p>
|
|
452
499
|
{/if}
|
|
453
500
|
|
|
454
|
-
|
|
455
|
-
<Button variant="neutral" style="outline" onclick={() => (formOpen = false)}>
|
|
456
|
-
Cancel
|
|
457
|
-
</Button>
|
|
458
|
-
<Button
|
|
459
|
-
variant={formType === 'bug' ? 'danger' : 'primary'}
|
|
460
|
-
disabled={submitting || !formMessage.trim()}
|
|
461
|
-
loading={submitting}
|
|
462
|
-
onclick={handleSubmit}
|
|
463
|
-
>
|
|
464
|
-
{formType === 'bug' ? 'Report Bug' : 'Submit Request'}
|
|
465
|
-
</Button>
|
|
466
|
-
</div>
|
|
467
|
-
{/if}
|
|
501
|
+
{/if}
|
|
468
502
|
</div>
|
|
503
|
+
|
|
504
|
+
<!-- Footer (fixed) -->
|
|
505
|
+
{#if submitResult !== 'success'}
|
|
506
|
+
<div class="flex justify-end gap-2 px-5 py-4 border-t border-border shrink-0">
|
|
507
|
+
<Button variant="neutral" style="outline" onclick={() => (formOpen = false)}>
|
|
508
|
+
Cancel
|
|
509
|
+
</Button>
|
|
510
|
+
<Button
|
|
511
|
+
variant={formType === 'bug' ? 'danger' : 'primary'}
|
|
512
|
+
disabled={submitting || !formMessage.trim()}
|
|
513
|
+
loading={submitting}
|
|
514
|
+
onclick={handleSubmit}
|
|
515
|
+
>
|
|
516
|
+
{formType === 'bug' ? 'Report Bug' : 'Submit Request'}
|
|
517
|
+
</Button>
|
|
518
|
+
</div>
|
|
519
|
+
{/if}
|
|
469
520
|
</Card>
|
|
470
521
|
</div>
|
|
471
|
-
</div>
|
|
472
522
|
{/if}
|
|
473
523
|
|
|
474
524
|
<!-- Onboarding toast -->
|
|
@@ -560,4 +610,9 @@
|
|
|
560
610
|
.sf-toast-close:hover {
|
|
561
611
|
color: #e2e8f0;
|
|
562
612
|
}
|
|
613
|
+
|
|
614
|
+
/* Floating modal shadow — no backdrop so needs strong depth cue */
|
|
615
|
+
.sf-modal :global(.card) {
|
|
616
|
+
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.05);
|
|
617
|
+
}
|
|
563
618
|
</style>
|
|
@@ -241,16 +241,16 @@
|
|
|
241
241
|
<main class="flex-1 min-w-0">
|
|
242
242
|
<div class="flex items-start justify-between mb-4">
|
|
243
243
|
<div>
|
|
244
|
-
|
|
245
|
-
|
|
244
|
+
{#if activeCategory}
|
|
245
|
+
<h2 class="text-xl font-bold flex items-center gap-2">
|
|
246
246
|
<i class={getCategoryIcon(activeCategory)}></i>
|
|
247
247
|
{getCategoryLabel(activeCategory)}
|
|
248
|
-
|
|
249
|
-
|
|
248
|
+
</h2>
|
|
249
|
+
{#if getCategoryDescription(activeCategory)}
|
|
250
|
+
<p class="text-sm text-foreground-secondary mt-1">{getCategoryDescription(activeCategory)}</p>
|
|
250
251
|
{/if}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
<p class="text-sm text-foreground-secondary mt-1">{getCategoryDescription(activeCategory)}</p>
|
|
252
|
+
{:else if title}
|
|
253
|
+
<h2 class="text-xl font-bold">{title}</h2>
|
|
254
254
|
{/if}
|
|
255
255
|
</div>
|
|
256
256
|
{#if showSubmit}
|
package/package.json
CHANGED