@productmaker/mcp 2.9.2 → 2.9.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.
- package/dist/http.js +51 -30
- package/dist/stdio.js +51 -30
- package/dist/ui/meta-upload-app.html +242 -588
- package/package.json +3 -3
|
@@ -66,21 +66,16 @@
|
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
button,
|
|
69
|
-
input
|
|
70
|
-
select,
|
|
71
|
-
textarea {
|
|
69
|
+
input {
|
|
72
70
|
font: inherit;
|
|
73
71
|
}
|
|
74
72
|
|
|
75
73
|
button,
|
|
76
|
-
select,
|
|
77
74
|
a {
|
|
78
75
|
-webkit-tap-highlight-color: transparent;
|
|
79
76
|
}
|
|
80
77
|
|
|
81
78
|
button:focus-visible,
|
|
82
|
-
select:focus-visible,
|
|
83
|
-
textarea:focus-visible,
|
|
84
79
|
a:focus-visible,
|
|
85
80
|
[tabindex]:focus-visible {
|
|
86
81
|
outline: 3px solid
|
|
@@ -102,73 +97,10 @@
|
|
|
102
97
|
box-shadow: var(--pm-shadow);
|
|
103
98
|
}
|
|
104
99
|
|
|
105
|
-
.
|
|
106
|
-
padding: 19px 22px 14px;
|
|
107
|
-
border-bottom: 1px solid
|
|
108
|
-
color-mix(in srgb, var(--pm-line) 65%, transparent);
|
|
109
|
-
background:
|
|
110
|
-
radial-gradient(
|
|
111
|
-
circle at 100% 0%,
|
|
112
|
-
var(--pm-primary-soft),
|
|
113
|
-
transparent 48%
|
|
114
|
-
),
|
|
115
|
-
var(--pm-card);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
.upload-header {
|
|
119
|
-
display: flex;
|
|
120
|
-
align-items: center;
|
|
121
|
-
justify-content: space-between;
|
|
122
|
-
gap: 12px;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
.upload-title {
|
|
126
|
-
min-width: 0;
|
|
127
|
-
margin: 0;
|
|
128
|
-
overflow: hidden;
|
|
129
|
-
font-size: clamp(17px, 3vw, 24px);
|
|
130
|
-
font-weight: 760;
|
|
131
|
-
letter-spacing: -0.025em;
|
|
132
|
-
text-overflow: ellipsis;
|
|
133
|
-
white-space: nowrap;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
.brand-mark {
|
|
100
|
+
.upload-feedback {
|
|
137
101
|
display: grid;
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
flex: 0 0 auto;
|
|
141
|
-
place-items: center;
|
|
142
|
-
border: 1px solid
|
|
143
|
-
color-mix(in srgb, var(--pm-primary) 20%, var(--pm-line));
|
|
144
|
-
border-radius: 50%;
|
|
145
|
-
background: color-mix(
|
|
146
|
-
in srgb,
|
|
147
|
-
var(--pm-primary-soft) 70%,
|
|
148
|
-
var(--pm-card)
|
|
149
|
-
);
|
|
150
|
-
color: var(--pm-primary-strong);
|
|
151
|
-
font-size: 20px;
|
|
152
|
-
font-weight: 800;
|
|
153
|
-
line-height: 1;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
.session-row {
|
|
157
|
-
display: flex;
|
|
158
|
-
min-height: 0;
|
|
159
|
-
align-items: center;
|
|
160
|
-
gap: 10px;
|
|
161
|
-
margin-top: 8px;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
.session-id {
|
|
165
|
-
overflow: hidden;
|
|
166
|
-
max-width: 100%;
|
|
167
|
-
color: var(--pm-muted);
|
|
168
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
169
|
-
font-size: 10px;
|
|
170
|
-
text-overflow: ellipsis;
|
|
171
|
-
white-space: nowrap;
|
|
102
|
+
gap: 8px;
|
|
103
|
+
margin-top: 10px;
|
|
172
104
|
}
|
|
173
105
|
|
|
174
106
|
.fallback-link {
|
|
@@ -212,20 +144,23 @@
|
|
|
212
144
|
}
|
|
213
145
|
|
|
214
146
|
.section {
|
|
215
|
-
padding:
|
|
147
|
+
padding: 18px;
|
|
216
148
|
}
|
|
217
149
|
|
|
218
|
-
.
|
|
219
|
-
|
|
150
|
+
.media-grid {
|
|
151
|
+
display: grid;
|
|
152
|
+
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
|
153
|
+
gap: 12px;
|
|
154
|
+
align-items: start;
|
|
220
155
|
}
|
|
221
156
|
|
|
222
157
|
.dropzone {
|
|
223
158
|
display: grid;
|
|
224
|
-
|
|
159
|
+
aspect-ratio: 1;
|
|
160
|
+
min-width: 0;
|
|
225
161
|
place-items: center;
|
|
226
|
-
padding: 20px;
|
|
227
162
|
border: 2px dashed var(--pm-line);
|
|
228
|
-
border-radius:
|
|
163
|
+
border-radius: 16px;
|
|
229
164
|
background: color-mix(
|
|
230
165
|
in srgb,
|
|
231
166
|
var(--pm-card-muted) 62%,
|
|
@@ -251,13 +186,11 @@
|
|
|
251
186
|
|
|
252
187
|
.drop-trigger {
|
|
253
188
|
display: grid;
|
|
254
|
-
width:
|
|
255
|
-
|
|
189
|
+
width: 100%;
|
|
190
|
+
height: 100%;
|
|
256
191
|
place-items: center;
|
|
257
|
-
align-content: center;
|
|
258
|
-
gap: 16px;
|
|
259
192
|
border: 0;
|
|
260
|
-
border-radius:
|
|
193
|
+
border-radius: 14px;
|
|
261
194
|
background: transparent;
|
|
262
195
|
color: var(--pm-text);
|
|
263
196
|
cursor: pointer;
|
|
@@ -267,26 +200,29 @@
|
|
|
267
200
|
cursor: not-allowed;
|
|
268
201
|
}
|
|
269
202
|
|
|
270
|
-
.
|
|
271
|
-
display: grid;
|
|
272
|
-
width: 58px;
|
|
273
|
-
height: 58px;
|
|
274
|
-
place-items: center;
|
|
275
|
-
border: 1px solid var(--pm-line);
|
|
276
|
-
border-radius: 50%;
|
|
277
|
-
background: var(--pm-card);
|
|
278
|
-
box-shadow: 0 7px 20px rgb(27 36 66 / 8%);
|
|
203
|
+
.add-symbol {
|
|
279
204
|
color: var(--pm-text);
|
|
280
|
-
font-size:
|
|
281
|
-
font-weight:
|
|
205
|
+
font-size: 44px;
|
|
206
|
+
font-weight: 300;
|
|
282
207
|
line-height: 1;
|
|
283
208
|
}
|
|
284
209
|
|
|
285
|
-
.
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
210
|
+
.complete-button {
|
|
211
|
+
justify-self: start;
|
|
212
|
+
min-width: 76px;
|
|
213
|
+
margin-top: 10px;
|
|
214
|
+
padding: 10px 20px;
|
|
215
|
+
border: 0;
|
|
216
|
+
border-radius: 12px;
|
|
217
|
+
background: var(--pm-primary);
|
|
218
|
+
color: #ffffff;
|
|
219
|
+
cursor: pointer;
|
|
220
|
+
font-weight: 780;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
.complete-button:disabled {
|
|
224
|
+
cursor: not-allowed;
|
|
225
|
+
opacity: 0.5;
|
|
290
226
|
}
|
|
291
227
|
|
|
292
228
|
.drop-help {
|
|
@@ -309,47 +245,6 @@
|
|
|
309
245
|
clip-path: inset(50%);
|
|
310
246
|
}
|
|
311
247
|
|
|
312
|
-
.button {
|
|
313
|
-
display: inline-flex;
|
|
314
|
-
min-height: 42px;
|
|
315
|
-
align-items: center;
|
|
316
|
-
justify-content: center;
|
|
317
|
-
gap: 8px;
|
|
318
|
-
padding: 10px 16px;
|
|
319
|
-
border: 1px solid transparent;
|
|
320
|
-
border-radius: 12px;
|
|
321
|
-
background: var(--pm-primary);
|
|
322
|
-
color: #ffffff;
|
|
323
|
-
cursor: pointer;
|
|
324
|
-
font-size: 13px;
|
|
325
|
-
font-weight: 780;
|
|
326
|
-
line-height: 1;
|
|
327
|
-
transition:
|
|
328
|
-
background 140ms ease,
|
|
329
|
-
opacity 140ms ease,
|
|
330
|
-
transform 140ms ease;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
.button:hover:not(:disabled) {
|
|
334
|
-
background: var(--pm-primary-strong);
|
|
335
|
-
transform: translateY(-1px);
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
.button:disabled {
|
|
339
|
-
cursor: not-allowed;
|
|
340
|
-
opacity: 0.5;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
.button.secondary {
|
|
344
|
-
border-color: var(--pm-line);
|
|
345
|
-
background: var(--pm-card);
|
|
346
|
-
color: var(--pm-text);
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
.button.secondary:hover:not(:disabled) {
|
|
350
|
-
background: var(--pm-card-muted);
|
|
351
|
-
}
|
|
352
|
-
|
|
353
248
|
.batch-error {
|
|
354
249
|
display: none;
|
|
355
250
|
margin: 10px 0 0;
|
|
@@ -362,10 +257,7 @@
|
|
|
362
257
|
}
|
|
363
258
|
|
|
364
259
|
.file-list {
|
|
365
|
-
display:
|
|
366
|
-
grid-template-columns: repeat(auto-fill, minmax(170px, 1fr));
|
|
367
|
-
gap: 12px;
|
|
368
|
-
margin-top: 14px;
|
|
260
|
+
display: contents;
|
|
369
261
|
}
|
|
370
262
|
|
|
371
263
|
.file-card {
|
|
@@ -501,64 +393,11 @@
|
|
|
501
393
|
transition: width 120ms linear;
|
|
502
394
|
}
|
|
503
395
|
|
|
504
|
-
.destination-grid {
|
|
505
|
-
display: grid;
|
|
506
|
-
grid-template-columns: repeat(3, minmax(0, 1fr));
|
|
507
|
-
gap: 9px;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
.field {
|
|
511
|
-
display: grid;
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
select,
|
|
515
|
-
textarea {
|
|
516
|
-
width: 100%;
|
|
517
|
-
border: 1px solid var(--pm-line);
|
|
518
|
-
border-radius: 11px;
|
|
519
|
-
background: var(--pm-card);
|
|
520
|
-
color: var(--pm-text);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
select {
|
|
524
|
-
min-height: 42px;
|
|
525
|
-
padding: 8px 30px 8px 10px;
|
|
526
|
-
font-size: 12px;
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
textarea {
|
|
530
|
-
min-height: 135px;
|
|
531
|
-
padding: 12px;
|
|
532
|
-
resize: vertical;
|
|
533
|
-
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
|
534
|
-
font-size: 11px;
|
|
535
|
-
line-height: 1.5;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
.destination-actions,
|
|
539
|
-
.handoff-actions {
|
|
540
|
-
display: flex;
|
|
541
|
-
flex-wrap: wrap;
|
|
542
|
-
gap: 10px;
|
|
543
|
-
margin-top: 12px;
|
|
544
|
-
}
|
|
545
|
-
|
|
546
396
|
.compatibility-control {
|
|
547
397
|
/* Retained for older hosts; recovery is visible only through the secure fallback. */
|
|
548
398
|
display: none !important;
|
|
549
399
|
}
|
|
550
400
|
|
|
551
|
-
.sr-only {
|
|
552
|
-
position: absolute;
|
|
553
|
-
width: 1px;
|
|
554
|
-
height: 1px;
|
|
555
|
-
padding: 0;
|
|
556
|
-
overflow: hidden;
|
|
557
|
-
clip: rect(0, 0, 0, 0);
|
|
558
|
-
white-space: nowrap;
|
|
559
|
-
border: 0;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
401
|
[hidden] {
|
|
563
402
|
display: none !important;
|
|
564
403
|
}
|
|
@@ -572,23 +411,13 @@
|
|
|
572
411
|
border-radius: 20px;
|
|
573
412
|
}
|
|
574
413
|
|
|
575
|
-
.hero,
|
|
576
414
|
.section {
|
|
577
415
|
padding-right: 14px;
|
|
578
416
|
padding-left: 14px;
|
|
579
417
|
}
|
|
580
418
|
|
|
581
|
-
.
|
|
582
|
-
|
|
583
|
-
}
|
|
584
|
-
|
|
585
|
-
.destination-grid {
|
|
586
|
-
grid-template-columns: 1fr;
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
.destination-actions .button,
|
|
590
|
-
.handoff-actions .button {
|
|
591
|
-
width: 100%;
|
|
419
|
+
.media-grid {
|
|
420
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
592
421
|
}
|
|
593
422
|
}
|
|
594
423
|
|
|
@@ -605,71 +434,46 @@
|
|
|
605
434
|
<body>
|
|
606
435
|
<main class="app" data-testid="meta-upload-root">
|
|
607
436
|
<article class="card">
|
|
608
|
-
<header class="hero">
|
|
609
|
-
<div class="upload-header">
|
|
610
|
-
<p class="upload-title" data-testid="meta-upload-title">
|
|
611
|
-
Upload image
|
|
612
|
-
</p>
|
|
613
|
-
<span class="brand-mark" aria-label="ProductMaker" role="img"
|
|
614
|
-
>↗</span
|
|
615
|
-
>
|
|
616
|
-
</div>
|
|
617
|
-
<div class="session-row">
|
|
618
|
-
<code class="session-id" data-testid="meta-upload-session-id" hidden
|
|
619
|
-
>Esperando sesión…</code
|
|
620
|
-
>
|
|
621
|
-
<a
|
|
622
|
-
class="fallback-link"
|
|
623
|
-
data-testid="meta-upload-fallback-link"
|
|
624
|
-
href="#"
|
|
625
|
-
target="_blank"
|
|
626
|
-
rel="noopener noreferrer"
|
|
627
|
-
hidden
|
|
628
|
-
>Abrir carga segura en otra pestaña</a
|
|
629
|
-
>
|
|
630
|
-
</div>
|
|
631
|
-
<p
|
|
632
|
-
class="status"
|
|
633
|
-
data-testid="meta-upload-session-status"
|
|
634
|
-
aria-live="polite"
|
|
635
|
-
></p>
|
|
636
|
-
</header>
|
|
637
|
-
|
|
638
437
|
<section class="section" aria-label="Upload media">
|
|
639
|
-
<div
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
438
|
+
<div class="media-grid">
|
|
439
|
+
<div
|
|
440
|
+
class="file-list"
|
|
441
|
+
data-testid="meta-upload-file-list"
|
|
442
|
+
aria-live="polite"
|
|
443
|
+
></div>
|
|
444
|
+
<div
|
|
445
|
+
class="dropzone"
|
|
446
|
+
data-testid="meta-upload-dropzone"
|
|
447
|
+
data-dragging="false"
|
|
448
|
+
aria-disabled="true"
|
|
449
|
+
aria-describedby="meta-upload-constraints"
|
|
651
450
|
>
|
|
652
|
-
<
|
|
653
|
-
|
|
654
|
-
|
|
451
|
+
<button
|
|
452
|
+
class="drop-trigger"
|
|
453
|
+
type="button"
|
|
454
|
+
data-testid="meta-upload-add-tile"
|
|
455
|
+
aria-label="Agregar otro archivo"
|
|
456
|
+
disabled
|
|
655
457
|
>
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
458
|
+
<span class="add-symbol" aria-hidden="true">+</span>
|
|
459
|
+
</button>
|
|
460
|
+
<button
|
|
461
|
+
class="compatibility-control"
|
|
462
|
+
type="button"
|
|
463
|
+
data-testid="meta-upload-library-btn"
|
|
464
|
+
hidden
|
|
465
|
+
disabled
|
|
466
|
+
aria-label="Choose from ChatGPT library"
|
|
467
|
+
></button>
|
|
468
|
+
<input
|
|
469
|
+
class="native-input"
|
|
470
|
+
data-testid="meta-upload-input"
|
|
471
|
+
type="file"
|
|
472
|
+
accept="image/jpeg,image/png,image/webp,video/mp4,video/quicktime,video/webm"
|
|
473
|
+
multiple
|
|
474
|
+
disabled
|
|
475
|
+
/>
|
|
476
|
+
</div>
|
|
673
477
|
</div>
|
|
674
478
|
<p class="drop-help" id="meta-upload-constraints">
|
|
675
479
|
JPEG, PNG, WebP, MP4, MOV o WebM. Hasta 10 archivos de 350 MB; las
|
|
@@ -681,77 +485,31 @@
|
|
|
681
485
|
role="alert"
|
|
682
486
|
aria-live="assertive"
|
|
683
487
|
></p>
|
|
684
|
-
<div
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
data-testid="meta-upload-destination-section"
|
|
694
|
-
aria-label="Meta destination"
|
|
695
|
-
hidden
|
|
696
|
-
>
|
|
697
|
-
<div class="destination-grid">
|
|
698
|
-
<div class="field">
|
|
699
|
-
<label class="sr-only" for="portfolio-select">Portfolio</label>
|
|
700
|
-
<select
|
|
701
|
-
id="portfolio-select"
|
|
702
|
-
data-testid="meta-upload-portfolio-select"
|
|
703
|
-
>
|
|
704
|
-
<option value="">Portfolio</option>
|
|
705
|
-
</select>
|
|
706
|
-
</div>
|
|
707
|
-
<div class="field">
|
|
708
|
-
<label class="sr-only" for="ad-account-select">Ad account</label>
|
|
709
|
-
<select
|
|
710
|
-
id="ad-account-select"
|
|
711
|
-
data-testid="meta-upload-ad-account-select"
|
|
712
|
-
disabled
|
|
713
|
-
>
|
|
714
|
-
<option value="">Ad account</option>
|
|
715
|
-
</select>
|
|
716
|
-
</div>
|
|
717
|
-
<div class="field">
|
|
718
|
-
<label class="sr-only" for="page-select">Facebook Page</label>
|
|
719
|
-
<select id="page-select" data-testid="meta-upload-page-select">
|
|
720
|
-
<option value="">Facebook Page</option>
|
|
721
|
-
</select>
|
|
722
|
-
</div>
|
|
723
|
-
</div>
|
|
724
|
-
<div class="destination-actions">
|
|
725
|
-
<button
|
|
726
|
-
class="button"
|
|
727
|
-
type="button"
|
|
728
|
-
data-testid="meta-upload-submit-destination"
|
|
729
|
-
disabled
|
|
730
|
-
>
|
|
731
|
-
Continue
|
|
732
|
-
</button>
|
|
733
|
-
</div>
|
|
734
|
-
</section>
|
|
735
|
-
|
|
736
|
-
<section
|
|
737
|
-
class="section"
|
|
738
|
-
data-testid="meta-upload-handoff-section"
|
|
739
|
-
aria-labelledby="handoff-heading"
|
|
740
|
-
hidden
|
|
741
|
-
>
|
|
742
|
-
<p id="handoff-heading" class="section-copy muted">
|
|
743
|
-
Copy this handoff into the chat.
|
|
744
|
-
</p>
|
|
745
|
-
<textarea data-testid="meta-upload-handoff-copy" readonly></textarea>
|
|
746
|
-
<div class="handoff-actions">
|
|
747
|
-
<button
|
|
748
|
-
class="button secondary"
|
|
749
|
-
type="button"
|
|
750
|
-
data-testid="meta-upload-copy-btn"
|
|
488
|
+
<div class="upload-feedback">
|
|
489
|
+
<a
|
|
490
|
+
class="fallback-link"
|
|
491
|
+
data-testid="meta-upload-fallback-link"
|
|
492
|
+
href="#"
|
|
493
|
+
target="_blank"
|
|
494
|
+
rel="noopener noreferrer"
|
|
495
|
+
hidden
|
|
496
|
+
>Abrir carga segura en otra pestaña</a
|
|
751
497
|
>
|
|
752
|
-
|
|
753
|
-
|
|
498
|
+
<p
|
|
499
|
+
class="status"
|
|
500
|
+
data-testid="meta-upload-session-status"
|
|
501
|
+
aria-live="polite"
|
|
502
|
+
></p>
|
|
754
503
|
</div>
|
|
504
|
+
<button
|
|
505
|
+
class="complete-button"
|
|
506
|
+
type="button"
|
|
507
|
+
data-testid="meta-upload-complete-btn"
|
|
508
|
+
hidden
|
|
509
|
+
disabled
|
|
510
|
+
>
|
|
511
|
+
OK
|
|
512
|
+
</button>
|
|
755
513
|
</section>
|
|
756
514
|
</article>
|
|
757
515
|
</main>
|
|
@@ -788,10 +546,6 @@
|
|
|
788
546
|
|
|
789
547
|
const elements = {
|
|
790
548
|
root: document.querySelector('[data-testid="meta-upload-root"]'),
|
|
791
|
-
title: document.querySelector('[data-testid="meta-upload-title"]'),
|
|
792
|
-
sessionId: document.querySelector(
|
|
793
|
-
'[data-testid="meta-upload-session-id"]',
|
|
794
|
-
),
|
|
795
549
|
fallbackLink: document.querySelector(
|
|
796
550
|
'[data-testid="meta-upload-fallback-link"]',
|
|
797
551
|
),
|
|
@@ -801,11 +555,8 @@
|
|
|
801
555
|
dropzone: document.querySelector(
|
|
802
556
|
'[data-testid="meta-upload-dropzone"]',
|
|
803
557
|
),
|
|
804
|
-
dropTitle: document.querySelector(
|
|
805
|
-
'[data-testid="meta-upload-drop-title"]',
|
|
806
|
-
),
|
|
807
558
|
pickerButton: document.querySelector(
|
|
808
|
-
'[data-testid="meta-upload-
|
|
559
|
+
'[data-testid="meta-upload-add-tile"]',
|
|
809
560
|
),
|
|
810
561
|
libraryPickerButton: document.querySelector(
|
|
811
562
|
'[data-testid="meta-upload-library-btn"]',
|
|
@@ -814,33 +565,12 @@
|
|
|
814
565
|
batchError: document.querySelector(
|
|
815
566
|
'[data-testid="meta-upload-batch-error"]',
|
|
816
567
|
),
|
|
568
|
+
completeButton: document.querySelector(
|
|
569
|
+
'[data-testid="meta-upload-complete-btn"]',
|
|
570
|
+
),
|
|
817
571
|
fileList: document.querySelector(
|
|
818
572
|
'[data-testid="meta-upload-file-list"]',
|
|
819
573
|
),
|
|
820
|
-
destinationSection: document.querySelector(
|
|
821
|
-
'[data-testid="meta-upload-destination-section"]',
|
|
822
|
-
),
|
|
823
|
-
portfolio: document.querySelector(
|
|
824
|
-
'[data-testid="meta-upload-portfolio-select"]',
|
|
825
|
-
),
|
|
826
|
-
adAccount: document.querySelector(
|
|
827
|
-
'[data-testid="meta-upload-ad-account-select"]',
|
|
828
|
-
),
|
|
829
|
-
page: document.querySelector(
|
|
830
|
-
'[data-testid="meta-upload-page-select"]',
|
|
831
|
-
),
|
|
832
|
-
submitDestination: document.querySelector(
|
|
833
|
-
'[data-testid="meta-upload-submit-destination"]',
|
|
834
|
-
),
|
|
835
|
-
handoffSection: document.querySelector(
|
|
836
|
-
'[data-testid="meta-upload-handoff-section"]',
|
|
837
|
-
),
|
|
838
|
-
handoffCopy: document.querySelector(
|
|
839
|
-
'[data-testid="meta-upload-handoff-copy"]',
|
|
840
|
-
),
|
|
841
|
-
copyButton: document.querySelector(
|
|
842
|
-
'[data-testid="meta-upload-copy-btn"]',
|
|
843
|
-
),
|
|
844
574
|
};
|
|
845
575
|
|
|
846
576
|
const state = {
|
|
@@ -859,7 +589,8 @@
|
|
|
859
589
|
toolInput: {},
|
|
860
590
|
items: [],
|
|
861
591
|
assets: [],
|
|
862
|
-
|
|
592
|
+
completionNotified: false,
|
|
593
|
+
completionNotificationInFlight: false,
|
|
863
594
|
consumedBridgeIds: new Set(),
|
|
864
595
|
consumingBridgeFiles: false,
|
|
865
596
|
bridgeConsumptionQueued: false,
|
|
@@ -907,29 +638,6 @@
|
|
|
907
638
|
return null;
|
|
908
639
|
}
|
|
909
640
|
|
|
910
|
-
function defaultUploadTitle() {
|
|
911
|
-
return state.session?.mediaKind === "video"
|
|
912
|
-
? "Upload video"
|
|
913
|
-
: "Upload image";
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
function updateUploadTitle() {
|
|
917
|
-
const namedItems = state.items.filter(
|
|
918
|
-
(item) =>
|
|
919
|
-
(item.file && typeof item.file.name === "string") ||
|
|
920
|
-
(typeof item.displayName === "string" &&
|
|
921
|
-
item.displayName.length > 0),
|
|
922
|
-
);
|
|
923
|
-
const title =
|
|
924
|
-
namedItems.length === 1
|
|
925
|
-
? namedItems[0].file?.name || namedItems[0].displayName
|
|
926
|
-
: namedItems.length > 1
|
|
927
|
-
? `${namedItems.length} files`
|
|
928
|
-
: defaultUploadTitle();
|
|
929
|
-
elements.title.textContent = title;
|
|
930
|
-
elements.dropTitle.textContent = defaultUploadTitle();
|
|
931
|
-
}
|
|
932
|
-
|
|
933
641
|
function safeSessionLimit() {
|
|
934
642
|
const proposed =
|
|
935
643
|
state.session && Number.isInteger(state.session.maxFiles)
|
|
@@ -955,6 +663,38 @@
|
|
|
955
663
|
scheduleIntrinsicSizeReport(true);
|
|
956
664
|
}
|
|
957
665
|
|
|
666
|
+
function canMessageHost() {
|
|
667
|
+
return (
|
|
668
|
+
hasOpenAiFunction("sendFollowUpMessage") || state.hostCanMessage
|
|
669
|
+
);
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
function canCompleteUpload() {
|
|
673
|
+
return (
|
|
674
|
+
!state.disposed &&
|
|
675
|
+
Boolean(state.session) &&
|
|
676
|
+
!sessionExpired() &&
|
|
677
|
+
!state.busyBatch &&
|
|
678
|
+
!state.completionNotified &&
|
|
679
|
+
!state.completionNotificationInFlight &&
|
|
680
|
+
state.assets.length > 0 &&
|
|
681
|
+
state.items.length > 0 &&
|
|
682
|
+
state.assets.length === state.items.length &&
|
|
683
|
+
state.items.every((item) => item.status === "uploaded") &&
|
|
684
|
+
canMessageHost()
|
|
685
|
+
);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
function renderCompletionAction() {
|
|
689
|
+
const hasVerifiedAssets = state.assets.length > 0;
|
|
690
|
+
elements.completeButton.hidden =
|
|
691
|
+
state.completionNotified || !hasVerifiedAssets || !canMessageHost();
|
|
692
|
+
elements.completeButton.disabled = !canCompleteUpload();
|
|
693
|
+
elements.completeButton.textContent =
|
|
694
|
+
state.completionNotificationInFlight ? "…" : "OK";
|
|
695
|
+
scheduleIntrinsicSizeReport(true);
|
|
696
|
+
}
|
|
697
|
+
|
|
958
698
|
function parseFinitePositiveNumber(value) {
|
|
959
699
|
return typeof value === "number" &&
|
|
960
700
|
Number.isFinite(value) &&
|
|
@@ -1173,6 +913,8 @@
|
|
|
1173
913
|
!state.session ||
|
|
1174
914
|
sessionExpired() ||
|
|
1175
915
|
state.uploadBlocked ||
|
|
916
|
+
state.completionNotified ||
|
|
917
|
+
state.completionNotificationInFlight ||
|
|
1176
918
|
state.busyBatch ||
|
|
1177
919
|
state.items.length >= safeSessionLimit();
|
|
1178
920
|
elements.input.disabled = disabled;
|
|
@@ -1262,24 +1004,6 @@
|
|
|
1262
1004
|
void processLocalFiles(files);
|
|
1263
1005
|
});
|
|
1264
1006
|
|
|
1265
|
-
elements.portfolio.addEventListener("change", () => {
|
|
1266
|
-
renderAdAccounts();
|
|
1267
|
-
updateDestinationSubmit();
|
|
1268
|
-
});
|
|
1269
|
-
elements.adAccount.addEventListener(
|
|
1270
|
-
"change",
|
|
1271
|
-
updateDestinationSubmit,
|
|
1272
|
-
);
|
|
1273
|
-
elements.page.addEventListener("change", updateDestinationSubmit);
|
|
1274
|
-
elements.submitDestination.addEventListener(
|
|
1275
|
-
"click",
|
|
1276
|
-
() => void submitDestination(),
|
|
1277
|
-
);
|
|
1278
|
-
elements.copyButton.addEventListener(
|
|
1279
|
-
"click",
|
|
1280
|
-
() => void copyHandoff(),
|
|
1281
|
-
);
|
|
1282
|
-
|
|
1283
1007
|
state.hostMessageHandler = handleHostMessage;
|
|
1284
1008
|
window.addEventListener("message", state.hostMessageHandler);
|
|
1285
1009
|
}
|
|
@@ -1411,17 +1135,28 @@
|
|
|
1411
1135
|
const sessionChanged =
|
|
1412
1136
|
!state.session || state.session.sessionId !== session.sessionId;
|
|
1413
1137
|
if (sessionChanged) {
|
|
1138
|
+
abortActiveWork();
|
|
1139
|
+
for (const item of state.items) revokePreviewUrl(item);
|
|
1140
|
+
state.items = [];
|
|
1141
|
+
state.assets = [];
|
|
1142
|
+
state.consumedBridgeIds.clear();
|
|
1143
|
+
state.consumingBridgeFiles = false;
|
|
1144
|
+
state.bridgeConsumptionQueued = false;
|
|
1145
|
+
state.ingestionQueue = Promise.resolve();
|
|
1146
|
+
state.busyBatch = false;
|
|
1147
|
+
elements.input.value = "";
|
|
1148
|
+
renderItems();
|
|
1414
1149
|
state.uploadBlocked = false;
|
|
1415
1150
|
state.fallbackRequired = false;
|
|
1151
|
+
state.completionNotified = false;
|
|
1152
|
+
state.completionNotificationInFlight = false;
|
|
1416
1153
|
state.workCancelled = false;
|
|
1417
1154
|
if (state.abortController?.signal.aborted) {
|
|
1418
1155
|
state.abortController = null;
|
|
1419
1156
|
}
|
|
1420
1157
|
}
|
|
1421
1158
|
state.session = session;
|
|
1422
|
-
elements.sessionId.textContent = session.sessionId;
|
|
1423
1159
|
elements.fallbackLink.href = session.uploadPageUrl;
|
|
1424
|
-
updateUploadTitle();
|
|
1425
1160
|
if (sessionExpired()) {
|
|
1426
1161
|
requireFallback(
|
|
1427
1162
|
"La sesión está expirada. Abre el enlace seguro para solicitar una nueva.",
|
|
@@ -1433,6 +1168,7 @@
|
|
|
1433
1168
|
setSessionStatus("Sesión lista para recibir archivos.", "neutral");
|
|
1434
1169
|
}
|
|
1435
1170
|
setPickerAvailability();
|
|
1171
|
+
renderCompletionAction();
|
|
1436
1172
|
void consumePendingBridgeFiles();
|
|
1437
1173
|
scheduleIntrinsicSizeReport(true);
|
|
1438
1174
|
}
|
|
@@ -1548,7 +1284,9 @@
|
|
|
1548
1284
|
state.disposed ||
|
|
1549
1285
|
!state.session ||
|
|
1550
1286
|
sessionExpired() ||
|
|
1551
|
-
state.uploadBlocked
|
|
1287
|
+
state.uploadBlocked ||
|
|
1288
|
+
state.completionNotified ||
|
|
1289
|
+
state.completionNotificationInFlight
|
|
1552
1290
|
)
|
|
1553
1291
|
return;
|
|
1554
1292
|
state.workCancelled = false;
|
|
@@ -1567,7 +1305,9 @@
|
|
|
1567
1305
|
state.disposed ||
|
|
1568
1306
|
!state.session ||
|
|
1569
1307
|
sessionExpired() ||
|
|
1570
|
-
state.uploadBlocked
|
|
1308
|
+
state.uploadBlocked ||
|
|
1309
|
+
state.completionNotified ||
|
|
1310
|
+
state.completionNotificationInFlight
|
|
1571
1311
|
)
|
|
1572
1312
|
return;
|
|
1573
1313
|
const bridge = openAiBridge();
|
|
@@ -1741,6 +1481,8 @@
|
|
|
1741
1481
|
!state.session ||
|
|
1742
1482
|
sessionExpired() ||
|
|
1743
1483
|
state.uploadBlocked ||
|
|
1484
|
+
state.completionNotified ||
|
|
1485
|
+
state.completionNotificationInFlight ||
|
|
1744
1486
|
state.busyBatch
|
|
1745
1487
|
)
|
|
1746
1488
|
return;
|
|
@@ -1760,7 +1502,10 @@
|
|
|
1760
1502
|
if (!selected.length) return;
|
|
1761
1503
|
|
|
1762
1504
|
state.busyBatch = true;
|
|
1505
|
+
state.assets = [];
|
|
1506
|
+
state.completionNotified = false;
|
|
1763
1507
|
setPickerAvailability();
|
|
1508
|
+
renderCompletionAction();
|
|
1764
1509
|
for (const file of selected) {
|
|
1765
1510
|
const mediaKind = mediaKindForType(file.type) || "image";
|
|
1766
1511
|
const item = createItem(file, mediaKind);
|
|
@@ -1770,6 +1515,7 @@
|
|
|
1770
1515
|
}
|
|
1771
1516
|
state.busyBatch = false;
|
|
1772
1517
|
setPickerAvailability();
|
|
1518
|
+
renderCompletionAction();
|
|
1773
1519
|
if (state.items.some((item) => item.status === "uploaded")) {
|
|
1774
1520
|
await refreshSessionStatus();
|
|
1775
1521
|
}
|
|
@@ -2415,7 +2161,7 @@
|
|
|
2415
2161
|
fragment.append(card);
|
|
2416
2162
|
});
|
|
2417
2163
|
elements.fileList.replaceChildren(fragment);
|
|
2418
|
-
|
|
2164
|
+
renderCompletionAction();
|
|
2419
2165
|
scheduleIntrinsicSizeReport(true);
|
|
2420
2166
|
}
|
|
2421
2167
|
|
|
@@ -2429,13 +2175,21 @@
|
|
|
2429
2175
|
|
|
2430
2176
|
async function refreshSessionStatus() {
|
|
2431
2177
|
if (!state.session) return;
|
|
2178
|
+
const requestedSessionId = state.session.sessionId;
|
|
2432
2179
|
setSessionStatus("Comprobando el staging privado…", "neutral");
|
|
2433
2180
|
try {
|
|
2434
2181
|
const result = await callReadOnlyTool("check_meta_media_upload", {
|
|
2435
|
-
sessionId:
|
|
2182
|
+
sessionId: requestedSessionId,
|
|
2436
2183
|
});
|
|
2437
|
-
|
|
2184
|
+
if (
|
|
2185
|
+
state.disposed ||
|
|
2186
|
+
!state.session ||
|
|
2187
|
+
state.session.sessionId !== requestedSessionId
|
|
2188
|
+
)
|
|
2189
|
+
return;
|
|
2190
|
+
const status = parseStatusResult(result, requestedSessionId);
|
|
2438
2191
|
state.assets = status.assets;
|
|
2192
|
+
renderCompletionAction();
|
|
2439
2193
|
if (!status.assets.length) {
|
|
2440
2194
|
if (status.legacyKindAmbiguous) {
|
|
2441
2195
|
requireFallback(
|
|
@@ -2448,7 +2202,6 @@
|
|
|
2448
2202
|
"warning",
|
|
2449
2203
|
);
|
|
2450
2204
|
}
|
|
2451
|
-
elements.destinationSection.hidden = true;
|
|
2452
2205
|
return;
|
|
2453
2206
|
}
|
|
2454
2207
|
|
|
@@ -2467,15 +2220,9 @@
|
|
|
2467
2220
|
setSessionStatus(
|
|
2468
2221
|
partial
|
|
2469
2222
|
? "Carga parcial verificada. Continuaremos solo con los assets listos."
|
|
2470
|
-
: "Carga
|
|
2223
|
+
: "Carga completada.",
|
|
2471
2224
|
partial ? "warning" : "success",
|
|
2472
2225
|
);
|
|
2473
|
-
const destinationsResult = await callReadOnlyTool(
|
|
2474
|
-
"list_meta_destinations",
|
|
2475
|
-
{},
|
|
2476
|
-
);
|
|
2477
|
-
state.destinations = parseDestinationsResult(destinationsResult);
|
|
2478
|
-
renderDestinations();
|
|
2479
2226
|
} catch (error) {
|
|
2480
2227
|
const expired =
|
|
2481
2228
|
sessionExpired() ||
|
|
@@ -2492,11 +2239,7 @@
|
|
|
2492
2239
|
}
|
|
2493
2240
|
|
|
2494
2241
|
async function callReadOnlyTool(name, args) {
|
|
2495
|
-
if (
|
|
2496
|
-
!["check_meta_media_upload", "list_meta_destinations"].includes(
|
|
2497
|
-
name,
|
|
2498
|
-
)
|
|
2499
|
-
) {
|
|
2242
|
+
if (name !== "check_meta_media_upload") {
|
|
2500
2243
|
throw new Error("tool_not_allowed");
|
|
2501
2244
|
}
|
|
2502
2245
|
const bridge = openAiBridge();
|
|
@@ -2541,8 +2284,10 @@
|
|
|
2541
2284
|
return parsed;
|
|
2542
2285
|
}
|
|
2543
2286
|
|
|
2544
|
-
function parseStatusResult(result) {
|
|
2287
|
+
function parseStatusResult(result, expectedSessionId) {
|
|
2545
2288
|
const payload = resultPayload(result);
|
|
2289
|
+
if (payload.sessionId !== expectedSessionId)
|
|
2290
|
+
throw new Error("status_session_mismatch");
|
|
2546
2291
|
const status = payload.status;
|
|
2547
2292
|
if (!["pending", "uploaded"].includes(status))
|
|
2548
2293
|
throw new Error("invalid_status");
|
|
@@ -2587,175 +2332,84 @@
|
|
|
2587
2332
|
return { status, assets, legacyKindAmbiguous };
|
|
2588
2333
|
}
|
|
2589
2334
|
|
|
2590
|
-
function
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
)
|
|
2606
|
-
|
|
2607
|
-
id: boundedString(entry.id, 300),
|
|
2608
|
-
name: boundedString(entry.name, 300) || "Página sin nombre",
|
|
2609
|
-
})),
|
|
2610
|
-
};
|
|
2611
|
-
}
|
|
2612
|
-
|
|
2613
|
-
function parseDestinationList(value, mapper) {
|
|
2614
|
-
if (!Array.isArray(value)) return [];
|
|
2615
|
-
return value.slice(0, 1000).flatMap((entry) => {
|
|
2616
|
-
if (!isRecord(entry)) return [];
|
|
2617
|
-
const mapped = mapper(entry);
|
|
2618
|
-
return mapped.id ? [mapped] : [];
|
|
2619
|
-
});
|
|
2620
|
-
}
|
|
2621
|
-
|
|
2622
|
-
function renderDestinations() {
|
|
2623
|
-
fillSelect(
|
|
2624
|
-
elements.portfolio,
|
|
2625
|
-
state.destinations.portfolios,
|
|
2626
|
-
"Portfolio",
|
|
2627
|
-
(entry) => entry.name,
|
|
2628
|
-
);
|
|
2629
|
-
fillSelect(
|
|
2630
|
-
elements.page,
|
|
2631
|
-
state.destinations.pages,
|
|
2632
|
-
"Facebook Page",
|
|
2633
|
-
(entry) => entry.name,
|
|
2634
|
-
);
|
|
2635
|
-
renderAdAccounts();
|
|
2636
|
-
elements.destinationSection.hidden = false;
|
|
2637
|
-
updateDestinationSubmit();
|
|
2638
|
-
scheduleIntrinsicSizeReport(true);
|
|
2639
|
-
}
|
|
2640
|
-
|
|
2641
|
-
function renderAdAccounts() {
|
|
2642
|
-
const portfolioId = elements.portfolio.value;
|
|
2643
|
-
const accounts = portfolioId
|
|
2644
|
-
? state.destinations.adAccounts.filter(
|
|
2645
|
-
(account) => account.portfolioId === portfolioId,
|
|
2646
|
-
)
|
|
2647
|
-
: [];
|
|
2648
|
-
fillSelect(
|
|
2649
|
-
elements.adAccount,
|
|
2650
|
-
accounts,
|
|
2651
|
-
portfolioId ? "Ad account" : "Ad account",
|
|
2652
|
-
(entry) =>
|
|
2653
|
-
`${entry.name}${entry.currency ? ` · ${entry.currency}` : ""}`,
|
|
2654
|
-
);
|
|
2655
|
-
elements.adAccount.disabled = !portfolioId || !accounts.length;
|
|
2656
|
-
}
|
|
2657
|
-
|
|
2658
|
-
function fillSelect(select, entries, placeholder, labelFor) {
|
|
2659
|
-
const fragment = document.createDocumentFragment();
|
|
2660
|
-
const empty = document.createElement("option");
|
|
2661
|
-
empty.value = "";
|
|
2662
|
-
empty.textContent = placeholder;
|
|
2663
|
-
fragment.append(empty);
|
|
2664
|
-
for (const entry of entries) {
|
|
2665
|
-
const option = document.createElement("option");
|
|
2666
|
-
option.value = entry.id;
|
|
2667
|
-
option.textContent = labelFor(entry);
|
|
2668
|
-
fragment.append(option);
|
|
2669
|
-
}
|
|
2670
|
-
select.replaceChildren(fragment);
|
|
2671
|
-
select.value = "";
|
|
2672
|
-
}
|
|
2673
|
-
|
|
2674
|
-
function updateDestinationSubmit() {
|
|
2675
|
-
elements.submitDestination.disabled = !(
|
|
2676
|
-
elements.portfolio.value &&
|
|
2677
|
-
elements.adAccount.value &&
|
|
2678
|
-
elements.page.value &&
|
|
2679
|
-
state.assets.length
|
|
2680
|
-
);
|
|
2681
|
-
}
|
|
2682
|
-
|
|
2683
|
-
function exactHandoff() {
|
|
2684
|
-
return JSON.stringify({
|
|
2685
|
-
sessionId: state.session.sessionId,
|
|
2686
|
-
portfolioId: elements.portfolio.value,
|
|
2687
|
-
adAccountId: elements.adAccount.value,
|
|
2688
|
-
pageId: elements.page.value,
|
|
2689
|
-
assets: state.assets.slice(0, MAX_FILES).map((asset) => ({
|
|
2690
|
-
stagingAssetId: asset.stagingAssetId,
|
|
2691
|
-
mediaKind: asset.mediaKind,
|
|
2692
|
-
})),
|
|
2693
|
-
});
|
|
2694
|
-
}
|
|
2695
|
-
|
|
2696
|
-
async function submitDestination() {
|
|
2697
|
-
if (elements.submitDestination.disabled || !state.session) return;
|
|
2698
|
-
const handoff = exactHandoff();
|
|
2699
|
-
elements.submitDestination.disabled = true;
|
|
2335
|
+
async function notifyChatUploadComplete() {
|
|
2336
|
+
if (
|
|
2337
|
+
state.completionNotified ||
|
|
2338
|
+
state.completionNotificationInFlight ||
|
|
2339
|
+
!state.session
|
|
2340
|
+
)
|
|
2341
|
+
return;
|
|
2342
|
+
const completionSessionId = state.session.sessionId;
|
|
2343
|
+
state.completionNotificationInFlight = true;
|
|
2344
|
+
setPickerAvailability();
|
|
2345
|
+
renderCompletionAction();
|
|
2346
|
+
const assets = state.assets
|
|
2347
|
+
.map(
|
|
2348
|
+
(asset) => `${asset.mediaKind} asset_id ${asset.stagingAssetId}`,
|
|
2349
|
+
)
|
|
2350
|
+
.join(", ");
|
|
2351
|
+
const message = `The ProductMaker upload is complete. Continue my previous request using these uploaded assets: ${assets}. Do not ask me to upload them again. Do not publish anything until you have asked me for the Meta portfolio, ad account, and Facebook Page.`;
|
|
2700
2352
|
try {
|
|
2701
2353
|
const bridge = openAiBridge();
|
|
2702
2354
|
if (bridge && typeof bridge.sendFollowUpMessage === "function") {
|
|
2703
|
-
await bridge.sendFollowUpMessage({ prompt:
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
)
|
|
2355
|
+
await bridge.sendFollowUpMessage({ prompt: message });
|
|
2356
|
+
if (
|
|
2357
|
+
!state.session ||
|
|
2358
|
+
state.session.sessionId !== completionSessionId
|
|
2359
|
+
)
|
|
2360
|
+
return;
|
|
2361
|
+
state.completionNotified = true;
|
|
2362
|
+
setPickerAvailability();
|
|
2363
|
+
renderCompletionAction();
|
|
2708
2364
|
return;
|
|
2709
2365
|
}
|
|
2710
2366
|
if (state.hostCanMessage) {
|
|
2711
|
-
await rpcRequest("ui/message", {
|
|
2367
|
+
const messageResult = await rpcRequest("ui/message", {
|
|
2712
2368
|
role: "user",
|
|
2713
|
-
content: [{ type: "text", text:
|
|
2369
|
+
content: [{ type: "text", text: message }],
|
|
2714
2370
|
});
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2371
|
+
if (isRecord(messageResult) && messageResult.isError === true)
|
|
2372
|
+
throw new Error("host_message_rejected");
|
|
2373
|
+
if (
|
|
2374
|
+
!state.session ||
|
|
2375
|
+
state.session.sessionId !== completionSessionId
|
|
2376
|
+
)
|
|
2377
|
+
return;
|
|
2378
|
+
state.completionNotified = true;
|
|
2379
|
+
setPickerAvailability();
|
|
2380
|
+
renderCompletionAction();
|
|
2719
2381
|
return;
|
|
2720
2382
|
}
|
|
2721
|
-
|
|
2383
|
+
setSessionStatus(
|
|
2384
|
+
"La carga terminó, pero este host no puede continuar el chat desde el widget. Vuelve al chat para seguir.",
|
|
2385
|
+
"warning",
|
|
2386
|
+
);
|
|
2722
2387
|
} catch {
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
}
|
|
2728
|
-
|
|
2729
|
-
function showCopyableHandoff(handoff) {
|
|
2730
|
-
elements.handoffCopy.value = handoff;
|
|
2731
|
-
elements.handoffSection.hidden = false;
|
|
2732
|
-
setSessionStatus(
|
|
2733
|
-
"Copia el handoff exacto y pégalo en el chat.",
|
|
2734
|
-
"warning",
|
|
2735
|
-
);
|
|
2736
|
-
scheduleIntrinsicSizeReport(true);
|
|
2737
|
-
}
|
|
2738
|
-
|
|
2739
|
-
async function copyHandoff() {
|
|
2740
|
-
const handoff = elements.handoffCopy.value;
|
|
2741
|
-
if (!handoff) return;
|
|
2742
|
-
if (
|
|
2743
|
-
navigator.clipboard &&
|
|
2744
|
-
typeof navigator.clipboard.writeText === "function"
|
|
2745
|
-
) {
|
|
2746
|
-
try {
|
|
2747
|
-
await navigator.clipboard.writeText(handoff);
|
|
2748
|
-
elements.copyButton.textContent = "Copiado";
|
|
2388
|
+
if (
|
|
2389
|
+
!state.session ||
|
|
2390
|
+
state.session.sessionId !== completionSessionId
|
|
2391
|
+
)
|
|
2749
2392
|
return;
|
|
2750
|
-
|
|
2751
|
-
|
|
2393
|
+
setSessionStatus(
|
|
2394
|
+
"No pudimos continuar el chat. Intenta nuevamente.",
|
|
2395
|
+
"danger",
|
|
2396
|
+
);
|
|
2397
|
+
} finally {
|
|
2398
|
+
if (
|
|
2399
|
+
state.session &&
|
|
2400
|
+
state.session.sessionId === completionSessionId
|
|
2401
|
+
) {
|
|
2402
|
+
state.completionNotificationInFlight = false;
|
|
2403
|
+
setPickerAvailability();
|
|
2404
|
+
renderCompletionAction();
|
|
2752
2405
|
}
|
|
2753
2406
|
}
|
|
2754
|
-
elements.handoffCopy.focus();
|
|
2755
|
-
elements.handoffCopy.select();
|
|
2756
|
-
elements.copyButton.textContent = "Seleccionado para copiar";
|
|
2757
2407
|
}
|
|
2758
2408
|
|
|
2409
|
+
elements.completeButton.addEventListener("click", () => {
|
|
2410
|
+
if (canCompleteUpload()) void notifyChatUploadComplete();
|
|
2411
|
+
});
|
|
2412
|
+
|
|
2759
2413
|
document.addEventListener("DOMContentLoaded", initialize, {
|
|
2760
2414
|
once: true,
|
|
2761
2415
|
});
|