@goodandready/dsh-tts 0.3.1 → 0.3.2

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/lib/client.js +51 -2
  2. package/package.json +1 -1
package/lib/client.js CHANGED
@@ -353,6 +353,7 @@ window.__ModuleLoader__.load({
353
353
  'down': 'Down',
354
354
  'save': 'Save',
355
355
  'saved': 'Saved',
356
+ 'cardHint': 'Provider chain, voices and playback options.',
356
357
  }
357
358
  const ru = {
358
359
  'general': 'Общее',
@@ -400,6 +401,7 @@ window.__ModuleLoader__.load({
400
401
  'down': 'Ниже',
401
402
  'save': 'Сохранить',
402
403
  'saved': 'Сохранено',
404
+ 'cardHint': 'Цепочка провайдеров, голоса и параметры чтения.',
403
405
  }
404
406
 
405
407
  function TtsSection(props) {
@@ -565,6 +567,32 @@ window.__ModuleLoader__.load({
565
567
  )
566
568
  }
567
569
 
570
+
571
+ // Карточка настроек во вкладке «Плагины»: заголовок, пояснение и
572
+ // сворачивание рисуем сами — ядро даёт только рамку списка.
573
+ function TtsCard(props) {
574
+ const t = (props && props.t) || ((key) => key)
575
+ const [open, setOpen] = React.useState(false)
576
+ return React.createElement('div',
577
+ {
578
+ className: 'dts-wrap',
579
+ style: { border: '1px solid var(--dsw-alias-border-l2)', borderRadius: '8px', marginBottom: '10px' },
580
+ },
581
+ React.createElement('button',
582
+ {
583
+ type: 'button',
584
+ 'aria-expanded': open ? 'true' : 'false',
585
+ onClick: () => setOpen((v) => !v),
586
+ style: { display: 'flex', width: '100%', gap: '8px', alignItems: 'baseline', background: 'none', border: 'none', padding: '10px 12px', cursor: 'pointer', textAlign: 'left' },
587
+ },
588
+ React.createElement('strong', null, t('title')),
589
+ React.createElement('span', { className: 'dts-sub' }, t('cardHint')),
590
+ React.createElement('span', { style: { marginLeft: 'auto', color: 'var(--dsw-alias-label-secondary)' } }, open ? '\u25be' : '\u25b8'),
591
+ ),
592
+ open ? React.createElement(TtsSection, props) : null,
593
+ )
594
+ }
595
+
568
596
  // Кнопка в строке ввода: видно, что сейчас читается, и можно остановить.
569
597
  function SpeakerControl() {
570
598
  const p = usePlayer()
@@ -598,12 +626,30 @@ window.__ModuleLoader__.load({
598
626
  // Подпись раздела рисует боковой список, а не наш компонент: props.t
599
627
  // туда не доходит, поэтому берём переводчик, привязанный к namespace.
600
628
  const t = ctx.locale.bind(NS)
629
+ // Штатное место настроек — карточка во вкладке «Настройки плагинов».
630
+ // Вкладка перебирает пространства настроек и ищет слот по entryKey,
631
+ // равному имени пространства: ключ обязан равняться NS, иначе карточка
632
+ // не появится молча, без единой ошибки в журнале.
633
+ let moved = false
634
+ try {
635
+ moved = !!ctx.slots.inject('settings.plugin.item', () => ctx.slots.register(
636
+ {
637
+ name: 'settings.plugin.item',
638
+ key: NS,
639
+ locale: NS,
640
+ inject: () => ({ ctx: ctx }),
641
+ },
642
+ TtsCard,
643
+ ))
644
+ } catch (noPluginItemSlot) { moved = false }
645
+ if (moved) return
646
+ // Запасной путь для сборок без settings.plugin.item: прежний раздел
647
+ // в боковом списке, чтобы настройки не пропали.
601
648
  ctx.slots.inject('settings.section', () => ctx.slots.register(
602
649
  {
603
650
  name: 'settings.section',
604
651
  id: '@goodandready/dsh-tts',
605
652
  order: 32,
606
- // locale в записи слота — то, из-за чего компонент получает props.t.
607
653
  locale: NS,
608
654
  label: () => t('title'),
609
655
  inject: () => ({ ctx: ctx }),
@@ -617,7 +663,10 @@ window.__ModuleLoader__.load({
617
663
  registerSettings(ctx)
618
664
  registerSpeaker(ctx)
619
665
  ctx.effect(() => listenForVoice(), 'dsh-tts: замолкать, когда человек заговорил')
620
- setInterval(pollPending, 1000)
666
+ ctx.effect(() => {
667
+ const timer = setInterval(pollPending, 1000)
668
+ return () => clearInterval(timer)
669
+ }, 'dsh-tts: опрос готовых озвучек')
621
670
  }
622
671
  return module.exports
623
672
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goodandready/dsh-tts",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Text-to-speech for DeepSeek Harness: speak agent replies in the Web UI with a provider fallback chain (OpenAI, ElevenLabs, Google, Azure, Groq, Deepgram, OpenRouter, Edge, Piper, eSpeak).",
5
5
  "license": "MIT",
6
6
  "type": "module",