@stellartech/voice-widget-directus 1.0.8 → 1.0.10

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.
Files changed (2) hide show
  1. package/dist/index.js +38 -19
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -456,6 +456,29 @@ const VOICE_MODELS = [
456
456
  ];
457
457
  const SAMPLE_TEXT = "Hello! This is a sample of my voice. I hope you enjoy listening to how I sound.";
458
458
  const DEFAULT_FLOW_ID = "7fa08903-ed7d-4632-81fc-f422d873b8f8";
459
+ function splitMarkdownBySeparator(mdText, sep = "## ") {
460
+ const text = String(mdText || "");
461
+ if (!text.includes(sep)) {
462
+ return [text];
463
+ }
464
+ const sections = [];
465
+ let buffer = [];
466
+ let sawHeader = false;
467
+ for (const line of text.split("\n")) {
468
+ if (line.startsWith(sep)) {
469
+ if (sawHeader) sections.push(buffer.join("\n"));
470
+ sawHeader = true;
471
+ buffer = [line];
472
+ } else {
473
+ buffer.push(line);
474
+ }
475
+ }
476
+ if (sawHeader) sections.push(buffer.join("\n"));
477
+ return sections.filter((s) => s.trim().length > 0);
478
+ }
479
+ function audioFilesCollection(collection) {
480
+ return collection?.startsWith("NX_") ? "NX_AudioFiles" : "AudioFiles";
481
+ }
459
482
  function useVoicingApi(api) {
460
483
  async function fetchVoices(collection = "Voices") {
461
484
  try {
@@ -538,8 +561,7 @@ function useVoicingApi(api) {
538
561
  provider,
539
562
  preprocessing: false,
540
563
  title: `Voice Sample - ${voiceId}`,
541
- audio_files_collection: "AudioFiles",
542
- // Include lesson context for callback tracking
564
+ audio_files_collection: audioFilesCollection(collection),
543
565
  lesson_id: lessonId || null,
544
566
  collection,
545
567
  voice_config: {
@@ -575,7 +597,7 @@ function useVoicingApi(api) {
575
597
  }
576
598
  console.log("[Voice Widget] Extracted audioFileId:", audioFileId);
577
599
  if (audioFileId) {
578
- const url = await resolveAudioFileUrl(audioFileId);
600
+ const url = await resolveAudioFileUrl(audioFileId, collection);
579
601
  return { url, audioFileId };
580
602
  }
581
603
  console.log("[Voice Widget] Sample processing async, callback will update Voices.example");
@@ -606,10 +628,7 @@ function useVoicingApi(api) {
606
628
  if (!textContent.trim()) {
607
629
  throw new Error("No text content available for voiceover generation");
608
630
  }
609
- texts = textContent.split(/\n\n+/).filter((t) => t.trim().length > 0);
610
- if (texts.length === 0) {
611
- texts = [textContent];
612
- }
631
+ texts = splitMarkdownBySeparator(textContent);
613
632
  console.log(`[Voice Widget] Generating voiceover for "${lessonTitle}" with ${texts.length} text segments`);
614
633
  } catch (e) {
615
634
  console.error("Failed to fetch lesson text content:", e);
@@ -628,8 +647,7 @@ function useVoicingApi(api) {
628
647
  provider: request.provider,
629
648
  preprocessing: request.preprocessing,
630
649
  title: `Voiceover - ${lessonTitle}`,
631
- audio_files_collection: "AudioFiles",
632
- // Pass these so the flow can include them in callback_data
650
+ audio_files_collection: audioFilesCollection(collection),
633
651
  lesson_id: request.lessonId,
634
652
  collection,
635
653
  voice_config: voiceConfig
@@ -672,9 +690,10 @@ function useVoicingApi(api) {
672
690
  function getAudioUrl(fileId) {
673
691
  return `/assets/${fileId}`;
674
692
  }
675
- async function resolveAudioFileUrl(audioFilesRecordId) {
693
+ async function resolveAudioFileUrl(audioFilesRecordId, collection) {
694
+ const afCollection = collection ? audioFilesCollection(collection) : "AudioFiles";
676
695
  try {
677
- const response = await api.get(`/items/AudioFiles/${audioFilesRecordId}`, {
696
+ const response = await api.get(`/items/${afCollection}/${audioFilesRecordId}`, {
678
697
  params: { fields: ["file"] }
679
698
  });
680
699
  const fileField = response.data.data?.file;
@@ -1161,7 +1180,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
1161
1180
  for (const v of allVariants.value) {
1162
1181
  if (v.audio_file_id) {
1163
1182
  const isUuid = v.audio_file_id?.includes("-");
1164
- v.audioUrl = isUuid ? getAudioUrl(v.audio_file_id) : await resolveAudioFileUrl(v.audio_file_id);
1183
+ v.audioUrl = isUuid ? getAudioUrl(v.audio_file_id) : await resolveAudioFileUrl(v.audio_file_id, props.collection);
1165
1184
  }
1166
1185
  }
1167
1186
  currentVariantIndex.value = 0;
@@ -1340,7 +1359,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
1340
1359
  allVariants.value = variants;
1341
1360
  for (const v of allVariants.value) {
1342
1361
  const isUuid = v.audio_file_id?.includes("-");
1343
- v.audioUrl = isUuid ? getAudioUrl(v.audio_file_id) : await resolveAudioFileUrl(v.audio_file_id);
1362
+ v.audioUrl = isUuid ? getAudioUrl(v.audio_file_id) : await resolveAudioFileUrl(v.audio_file_id, props.collection);
1344
1363
  }
1345
1364
  currentVariantIndex.value = 0;
1346
1365
  hasExistingVoices.value = variants.length > 0;
@@ -1358,7 +1377,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
1358
1377
  const audioFileId = variant.audio_file_id;
1359
1378
  generatedAudioId.value = audioFileId;
1360
1379
  const isUuid = audioFileId.includes("-");
1361
- generatedAudioUrl.value = isUuid ? getAudioUrl(audioFileId) : await resolveAudioFileUrl(audioFileId);
1380
+ generatedAudioUrl.value = isUuid ? getAudioUrl(audioFileId) : await resolveAudioFileUrl(audioFileId, props.collection);
1362
1381
  const config = variant.voice_config;
1363
1382
  if (config) {
1364
1383
  isRestoringFromVariant.value = true;
@@ -1428,7 +1447,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
1428
1447
  allVariants.value = variants;
1429
1448
  for (const v of allVariants.value) {
1430
1449
  const isUuid = v.audio_file_id?.includes("-");
1431
- v.audioUrl = isUuid ? getAudioUrl(v.audio_file_id) : await resolveAudioFileUrl(v.audio_file_id);
1450
+ v.audioUrl = isUuid ? getAudioUrl(v.audio_file_id) : await resolveAudioFileUrl(v.audio_file_id, props.collection);
1432
1451
  }
1433
1452
  currentVariantIndex.value = 0;
1434
1453
  await loadVariantAtIndex(0);
@@ -1517,7 +1536,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
1517
1536
  for (const v of allVariants.value) {
1518
1537
  if (v.audio_file_id) {
1519
1538
  const isUuid = v.audio_file_id?.includes("-");
1520
- v.audioUrl = isUuid ? getAudioUrl(v.audio_file_id) : await resolveAudioFileUrl(v.audio_file_id);
1539
+ v.audioUrl = isUuid ? getAudioUrl(v.audio_file_id) : await resolveAudioFileUrl(v.audio_file_id, props.collection);
1521
1540
  }
1522
1541
  }
1523
1542
  currentVariantIndex.value = 0;
@@ -1567,7 +1586,7 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
1567
1586
  generatedAudioUrl.value = getAudioUrl(audioFileId);
1568
1587
  } else {
1569
1588
  generatedAudioId.value = audioFileId;
1570
- generatedAudioUrl.value = await resolveAudioFileUrl(audioFileId);
1589
+ generatedAudioUrl.value = await resolveAudioFileUrl(audioFileId, props.collection);
1571
1590
  }
1572
1591
  }
1573
1592
  }
@@ -2053,10 +2072,10 @@ var _sfc_main = /* @__PURE__ */ defineComponent({
2053
2072
  }
2054
2073
  });
2055
2074
 
2056
- var css = "\n.voice-widget[data-v-dbe97361] {\n font-family: var(--theme--fonts--sans--font-family);\n padding: 16px;\n border: 1px solid var(--theme--form--field--input--border-color);\n border-radius: var(--theme--border-radius);\n background: var(--theme--background);\n}\n.widget__header[data-v-dbe97361] {\n margin-bottom: 20px;\n}\n.widget__header-row[data-v-dbe97361] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n}\n.widget__header-text[data-v-dbe97361] {\n flex: 1;\n}\n.widget__title[data-v-dbe97361] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--theme--foreground);\n}\n.widget__collapse-btn[data-v-dbe97361] {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--theme--foreground-subdued);\n border-radius: 4px;\n}\n.widget__collapse-btn[data-v-dbe97361]:hover {\n background: var(--theme--background-accent);\n}\n.widget__subtitle[data-v-dbe97361] {\n margin: 0;\n font-size: 14px;\n color: var(--theme--foreground-subdued);\n}\n.widget__header-controls[data-v-dbe97361] {\n display: flex;\n gap: 16px;\n align-items: center;\n}\n.widget__url-input[data-v-dbe97361] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.widget__url-label[data-v-dbe97361] {\n font-size: 12px;\n color: var(--theme--foreground-subdued);\n white-space: nowrap;\n}\n.widget__url-field[data-v-dbe97361] {\n padding: 6px 10px;\n border: 1px solid var(--theme--form--field--input--border-color);\n border-radius: var(--theme--border-radius);\n font-size: 12px;\n width: 280px;\n background: var(--theme--form--field--input--background);\n color: var(--theme--foreground);\n}\n.widget__section[data-v-dbe97361] {\n margin-bottom: 20px;\n}\n.widget__section-label[data-v-dbe97361] {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--theme--foreground);\n}\n.widget__model-buttons[data-v-dbe97361] {\n display: flex;\n gap: 8px;\n}\n.widget__model-btn[data-v-dbe97361] {\n padding: 8px 16px;\n border: 1px solid var(--theme--form--field--input--border-color);\n border-radius: var(--theme--border-radius);\n background: var(--theme--background);\n color: var(--theme--foreground);\n cursor: pointer;\n font-size: 14px;\n transition: all 0.15s ease;\n}\n.widget__model-btn[data-v-dbe97361]:hover {\n border-color: var(--theme--primary);\n}\n.widget__model-btn--active[data-v-dbe97361] {\n background: var(--theme--primary);\n border-color: var(--theme--primary);\n color: var(--theme--primary-foreground, #fff);\n}\n.widget__voice-list[data-v-dbe97361] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.widget__section--toggle[data-v-dbe97361] {\n padding: 12px;\n background: var(--theme--background-subdued);\n border-radius: var(--theme--border-radius);\n}\n.widget__toggle[data-v-dbe97361] {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n}\n.widget__toggle input[data-v-dbe97361] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n.widget__toggle-label[data-v-dbe97361] {\n font-size: 14px;\n font-weight: 500;\n color: var(--theme--foreground);\n}\n.widget__toggle-note[data-v-dbe97361] {\n margin: 4px 0 0 24px;\n font-size: 12px;\n color: var(--theme--foreground-subdued);\n}\n.widget__footer[data-v-dbe97361] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-top: 16px;\n border-top: 1px solid var(--theme--border-color-subdued);\n margin-top: 20px;\n}\n.widget__footer-left[data-v-dbe97361],\n.widget__footer-right[data-v-dbe97361] {\n display: flex;\n gap: 8px;\n}\n.widget__variant-nav[data-v-dbe97361] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n margin-bottom: 16px;\n padding: 8px 0;\n}\n.widget__variant-counter[data-v-dbe97361] {\n font-size: 14px;\n font-weight: 500;\n color: var(--theme--foreground-subdued);\n min-width: 60px;\n text-align: center;\n}\n.widget__btn--icon[data-v-dbe97361] {\n padding: 6px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.widget__result-date[data-v-dbe97361] {\n margin-top: 8px;\n font-size: 12px;\n color: var(--theme--foreground-subdued);\n}\n.widget__btn[data-v-dbe97361] {\n padding: 8px 16px;\n border: none;\n border-radius: var(--theme--border-radius);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.widget__btn[data-v-dbe97361]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.widget__btn--primary[data-v-dbe97361] {\n background: var(--theme--primary);\n color: var(--theme--primary-foreground, #fff);\n}\n.widget__btn--primary[data-v-dbe97361]:hover:not(:disabled) {\n background: var(--theme--primary-accent);\n}\n.widget__btn--secondary[data-v-dbe97361] {\n background: var(--theme--background-accent);\n color: var(--theme--foreground);\n border: 1px solid var(--theme--form--field--input--border-color);\n}\n.widget__btn--secondary[data-v-dbe97361]:hover:not(:disabled) {\n background: var(--theme--background-normal);\n}\n\n/* Processing State */\n.widget__processing[data-v-dbe97361] {\n padding: 40px 20px;\n text-align: center;\n}\n.widget__progress[data-v-dbe97361] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n margin-bottom: 16px;\n font-size: 16px;\n color: var(--theme--foreground);\n}\n.widget__progress-bar[data-v-dbe97361] {\n height: 8px;\n background: var(--theme--background-accent);\n border-radius: 4px;\n overflow: hidden;\n max-width: 400px;\n margin: 0 auto;\n}\n.widget__progress-fill[data-v-dbe97361] {\n height: 100%;\n background: var(--theme--primary);\n transition: width 0.3s ease;\n}\n\n/* Error State */\n.widget__error[data-v-dbe97361] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 20px;\n color: var(--theme--danger);\n text-align: center;\n}\n.widget__error-actions[data-v-dbe97361] {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n}\n.widget__retry[data-v-dbe97361] {\n padding: 6px 12px;\n background: var(--theme--danger);\n color: #fff;\n border: none;\n border-radius: var(--theme--border-radius);\n cursor: pointer;\n}\n\n/* Loading State */\n.widget__loading[data-v-dbe97361] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--theme--foreground-subdued);\n}\n\n/* Result State */\n.widget__result[data-v-dbe97361] {\n padding: 20px;\n background: var(--theme--background-subdued);\n border-radius: var(--theme--border-radius);\n margin-bottom: 20px;\n}\n.widget__result-info[data-v-dbe97361] {\n margin-top: 16px;\n padding-top: 16px;\n border-top: 1px solid var(--theme--border-color-subdued);\n}\n.widget__result-info p[data-v-dbe97361] {\n margin: 4px 0;\n font-size: 14px;\n color: var(--theme--foreground-subdued);\n}\n.widget__result-info strong[data-v-dbe97361] {\n color: var(--theme--foreground);\n}\n\n/* Variants List View */\n.widget__variants-list[data-v-dbe97361] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n max-height: 400px;\n overflow-y: auto;\n margin-bottom: 16px;\n}\n.widget__variant-item[data-v-dbe97361] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n border: 1px solid var(--theme--border-color-subdued);\n border-radius: var(--theme--border-radius);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.widget__variant-item[data-v-dbe97361]:hover {\n border-color: var(--theme--primary);\n}\n.widget__variant-item--selected[data-v-dbe97361] {\n border-color: var(--theme--primary);\n background: var(--theme--primary-background);\n}\n.widget__variant-radio[data-v-dbe97361] {\n flex-shrink: 0;\n}\n.widget__variant-radio input[data-v-dbe97361] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n.widget__variant-player[data-v-dbe97361] {\n flex: 1;\n min-width: 200px;\n}\n.widget__variant-meta[data-v-dbe97361] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 120px;\n}\n.widget__variant-voice[data-v-dbe97361] {\n font-size: 13px;\n font-weight: 500;\n color: var(--theme--foreground);\n}\n.widget__variant-date[data-v-dbe97361] {\n font-size: 11px;\n color: var(--theme--foreground-subdued);\n}\n.widget__btn--danger[data-v-dbe97361] {\n color: var(--theme--danger);\n background: transparent;\n border: none;\n}\n.widget__btn--danger[data-v-dbe97361]:hover {\n background: var(--theme--danger-background);\n}\n.widget__selected-info[data-v-dbe97361] {\n padding: 12px;\n background: var(--theme--background-subdued);\n border-radius: var(--theme--border-radius);\n margin-bottom: 16px;\n}\n.widget__selected-info p[data-v-dbe97361] {\n margin: 4px 0;\n font-size: 14px;\n color: var(--theme--foreground-subdued);\n}\n.widget__selected-info strong[data-v-dbe97361] {\n color: var(--theme--foreground);\n}\n.widget__progress-status[data-v-dbe97361] {\n text-align: center;\n font-size: 12px;\n color: var(--theme--foreground-subdued);\n margin-top: 8px;\n}\n\n/* Animations */\n.spinning[data-v-dbe97361] {\n animation: spin-dbe97361 1s linear infinite;\n}\n@keyframes spin-dbe97361 {\nfrom { transform: rotate(0deg);\n}\nto { transform: rotate(360deg);\n}\n}\n";
2075
+ var css = "\n.voice-widget[data-v-6d27bc73] {\n font-family: var(--theme--fonts--sans--font-family);\n padding: 16px;\n border: 1px solid var(--theme--form--field--input--border-color);\n border-radius: var(--theme--border-radius);\n background: var(--theme--background);\n}\n.widget__header[data-v-6d27bc73] {\n margin-bottom: 20px;\n}\n.widget__header-row[data-v-6d27bc73] {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n gap: 16px;\n}\n.widget__header-text[data-v-6d27bc73] {\n flex: 1;\n}\n.widget__title[data-v-6d27bc73] {\n display: flex;\n align-items: center;\n gap: 8px;\n margin: 0 0 4px 0;\n font-size: 18px;\n font-weight: 600;\n color: var(--theme--foreground);\n}\n.widget__collapse-btn[data-v-6d27bc73] {\n background: none;\n border: none;\n padding: 4px;\n cursor: pointer;\n color: var(--theme--foreground-subdued);\n border-radius: 4px;\n}\n.widget__collapse-btn[data-v-6d27bc73]:hover {\n background: var(--theme--background-accent);\n}\n.widget__subtitle[data-v-6d27bc73] {\n margin: 0;\n font-size: 14px;\n color: var(--theme--foreground-subdued);\n}\n.widget__header-controls[data-v-6d27bc73] {\n display: flex;\n gap: 16px;\n align-items: center;\n}\n.widget__url-input[data-v-6d27bc73] {\n display: flex;\n align-items: center;\n gap: 8px;\n}\n.widget__url-label[data-v-6d27bc73] {\n font-size: 12px;\n color: var(--theme--foreground-subdued);\n white-space: nowrap;\n}\n.widget__url-field[data-v-6d27bc73] {\n padding: 6px 10px;\n border: 1px solid var(--theme--form--field--input--border-color);\n border-radius: var(--theme--border-radius);\n font-size: 12px;\n width: 280px;\n background: var(--theme--form--field--input--background);\n color: var(--theme--foreground);\n}\n.widget__section[data-v-6d27bc73] {\n margin-bottom: 20px;\n}\n.widget__section-label[data-v-6d27bc73] {\n display: block;\n margin-bottom: 8px;\n font-size: 14px;\n font-weight: 500;\n color: var(--theme--foreground);\n}\n.widget__model-buttons[data-v-6d27bc73] {\n display: flex;\n gap: 8px;\n}\n.widget__model-btn[data-v-6d27bc73] {\n padding: 8px 16px;\n border: 1px solid var(--theme--form--field--input--border-color);\n border-radius: var(--theme--border-radius);\n background: var(--theme--background);\n color: var(--theme--foreground);\n cursor: pointer;\n font-size: 14px;\n transition: all 0.15s ease;\n}\n.widget__model-btn[data-v-6d27bc73]:hover {\n border-color: var(--theme--primary);\n}\n.widget__model-btn--active[data-v-6d27bc73] {\n background: var(--theme--primary);\n border-color: var(--theme--primary);\n color: var(--theme--primary-foreground, #fff);\n}\n.widget__voice-list[data-v-6d27bc73] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n.widget__section--toggle[data-v-6d27bc73] {\n padding: 12px;\n background: var(--theme--background-subdued);\n border-radius: var(--theme--border-radius);\n}\n.widget__toggle[data-v-6d27bc73] {\n display: flex;\n align-items: center;\n gap: 8px;\n cursor: pointer;\n}\n.widget__toggle input[data-v-6d27bc73] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n.widget__toggle-label[data-v-6d27bc73] {\n font-size: 14px;\n font-weight: 500;\n color: var(--theme--foreground);\n}\n.widget__toggle-note[data-v-6d27bc73] {\n margin: 4px 0 0 24px;\n font-size: 12px;\n color: var(--theme--foreground-subdued);\n}\n.widget__footer[data-v-6d27bc73] {\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding-top: 16px;\n border-top: 1px solid var(--theme--border-color-subdued);\n margin-top: 20px;\n}\n.widget__footer-left[data-v-6d27bc73],\n.widget__footer-right[data-v-6d27bc73] {\n display: flex;\n gap: 8px;\n}\n.widget__variant-nav[data-v-6d27bc73] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n margin-bottom: 16px;\n padding: 8px 0;\n}\n.widget__variant-counter[data-v-6d27bc73] {\n font-size: 14px;\n font-weight: 500;\n color: var(--theme--foreground-subdued);\n min-width: 60px;\n text-align: center;\n}\n.widget__btn--icon[data-v-6d27bc73] {\n padding: 6px;\n min-width: 32px;\n min-height: 32px;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.widget__result-date[data-v-6d27bc73] {\n margin-top: 8px;\n font-size: 12px;\n color: var(--theme--foreground-subdued);\n}\n.widget__btn[data-v-6d27bc73] {\n padding: 8px 16px;\n border: none;\n border-radius: var(--theme--border-radius);\n font-size: 14px;\n font-weight: 500;\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.widget__btn[data-v-6d27bc73]:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.widget__btn--primary[data-v-6d27bc73] {\n background: var(--theme--primary);\n color: var(--theme--primary-foreground, #fff);\n}\n.widget__btn--primary[data-v-6d27bc73]:hover:not(:disabled) {\n background: var(--theme--primary-accent);\n}\n.widget__btn--secondary[data-v-6d27bc73] {\n background: var(--theme--background-accent);\n color: var(--theme--foreground);\n border: 1px solid var(--theme--form--field--input--border-color);\n}\n.widget__btn--secondary[data-v-6d27bc73]:hover:not(:disabled) {\n background: var(--theme--background-normal);\n}\n\n/* Processing State */\n.widget__processing[data-v-6d27bc73] {\n padding: 40px 20px;\n text-align: center;\n}\n.widget__progress[data-v-6d27bc73] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n margin-bottom: 16px;\n font-size: 16px;\n color: var(--theme--foreground);\n}\n.widget__progress-bar[data-v-6d27bc73] {\n height: 8px;\n background: var(--theme--background-accent);\n border-radius: 4px;\n overflow: hidden;\n max-width: 400px;\n margin: 0 auto;\n}\n.widget__progress-fill[data-v-6d27bc73] {\n height: 100%;\n background: var(--theme--primary);\n transition: width 0.3s ease;\n}\n\n/* Error State */\n.widget__error[data-v-6d27bc73] {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 12px;\n padding: 20px;\n color: var(--theme--danger);\n text-align: center;\n}\n.widget__error-actions[data-v-6d27bc73] {\n display: flex;\n gap: 8px;\n margin-top: 8px;\n}\n.widget__retry[data-v-6d27bc73] {\n padding: 6px 12px;\n background: var(--theme--danger);\n color: #fff;\n border: none;\n border-radius: var(--theme--border-radius);\n cursor: pointer;\n}\n\n/* Loading State */\n.widget__loading[data-v-6d27bc73] {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 12px;\n padding: 40px 20px;\n color: var(--theme--foreground-subdued);\n}\n\n/* Result State */\n.widget__result[data-v-6d27bc73] {\n padding: 20px;\n background: var(--theme--background-subdued);\n border-radius: var(--theme--border-radius);\n margin-bottom: 20px;\n}\n.widget__result-info[data-v-6d27bc73] {\n margin-top: 16px;\n padding-top: 16px;\n border-top: 1px solid var(--theme--border-color-subdued);\n}\n.widget__result-info p[data-v-6d27bc73] {\n margin: 4px 0;\n font-size: 14px;\n color: var(--theme--foreground-subdued);\n}\n.widget__result-info strong[data-v-6d27bc73] {\n color: var(--theme--foreground);\n}\n\n/* Variants List View */\n.widget__variants-list[data-v-6d27bc73] {\n display: flex;\n flex-direction: column;\n gap: 8px;\n max-height: 400px;\n overflow-y: auto;\n margin-bottom: 16px;\n}\n.widget__variant-item[data-v-6d27bc73] {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px;\n border: 1px solid var(--theme--border-color-subdued);\n border-radius: var(--theme--border-radius);\n cursor: pointer;\n transition: all 0.15s ease;\n}\n.widget__variant-item[data-v-6d27bc73]:hover {\n border-color: var(--theme--primary);\n}\n.widget__variant-item--selected[data-v-6d27bc73] {\n border-color: var(--theme--primary);\n background: var(--theme--primary-background);\n}\n.widget__variant-radio[data-v-6d27bc73] {\n flex-shrink: 0;\n}\n.widget__variant-radio input[data-v-6d27bc73] {\n width: 16px;\n height: 16px;\n cursor: pointer;\n}\n.widget__variant-player[data-v-6d27bc73] {\n flex: 1;\n min-width: 200px;\n}\n.widget__variant-meta[data-v-6d27bc73] {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 120px;\n}\n.widget__variant-voice[data-v-6d27bc73] {\n font-size: 13px;\n font-weight: 500;\n color: var(--theme--foreground);\n}\n.widget__variant-date[data-v-6d27bc73] {\n font-size: 11px;\n color: var(--theme--foreground-subdued);\n}\n.widget__btn--danger[data-v-6d27bc73] {\n color: var(--theme--danger);\n background: transparent;\n border: none;\n}\n.widget__btn--danger[data-v-6d27bc73]:hover {\n background: var(--theme--danger-background);\n}\n.widget__selected-info[data-v-6d27bc73] {\n padding: 12px;\n background: var(--theme--background-subdued);\n border-radius: var(--theme--border-radius);\n margin-bottom: 16px;\n}\n.widget__selected-info p[data-v-6d27bc73] {\n margin: 4px 0;\n font-size: 14px;\n color: var(--theme--foreground-subdued);\n}\n.widget__selected-info strong[data-v-6d27bc73] {\n color: var(--theme--foreground);\n}\n.widget__progress-status[data-v-6d27bc73] {\n text-align: center;\n font-size: 12px;\n color: var(--theme--foreground-subdued);\n margin-top: 8px;\n}\n\n/* Animations */\n.spinning[data-v-6d27bc73] {\n animation: spin-6d27bc73 1s linear infinite;\n}\n@keyframes spin-6d27bc73 {\nfrom { transform: rotate(0deg);\n}\nto { transform: rotate(360deg);\n}\n}\n";
2057
2076
  n(css,{});
2058
2077
 
2059
- var InterfaceComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-dbe97361"], ["__file", "interface.vue"]]);
2078
+ var InterfaceComponent = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-6d27bc73"], ["__file", "interface.vue"]]);
2060
2079
 
2061
2080
  var index = defineInterface({
2062
2081
  id: "voice-widget",
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@stellartech/voice-widget-directus",
3
3
  "description": "Voice generation widget with model/voice selection and audio preview for Directus",
4
4
  "icon": "mic",
5
- "version": "1.0.8",
5
+ "version": "1.0.10",
6
6
  "license": "MIT",
7
7
  "readme": "README.md",
8
8
  "repository": {