@apteva/apteva-kit 0.1.115 → 0.1.116

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/index.js CHANGED
@@ -3376,41 +3376,56 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
3376
3376
  stopRecording(true);
3377
3377
  };
3378
3378
  }, []);
3379
- const drawWaveform = _react.useCallback.call(void 0, () => {
3379
+ const startWaveformLoop = _react.useCallback.call(void 0, () => {
3380
3380
  const canvas = canvasRef.current;
3381
3381
  const analyser = analyserRef.current;
3382
3382
  if (!canvas || !analyser) return;
3383
+ const dpr = window.devicePixelRatio || 1;
3384
+ const rect = canvas.getBoundingClientRect();
3385
+ canvas.width = rect.width * dpr;
3386
+ canvas.height = rect.height * dpr;
3383
3387
  const ctx = canvas.getContext("2d");
3384
3388
  if (!ctx) return;
3389
+ ctx.scale(dpr, dpr);
3385
3390
  const bufferLength = analyser.frequencyBinCount;
3386
3391
  const dataArray = new Uint8Array(bufferLength);
3392
+ const smoothed = new Float32Array(40).fill(2);
3387
3393
  const draw = () => {
3388
3394
  animFrameRef.current = requestAnimationFrame(draw);
3389
3395
  analyser.getByteTimeDomainData(dataArray);
3390
- const { width, height } = canvas;
3391
- ctx.clearRect(0, 0, width, height);
3392
- const barCount = 32;
3393
- const barWidth = Math.max(2, (width - (barCount - 1) * 2) / barCount);
3396
+ const w = rect.width;
3397
+ const h = rect.height;
3398
+ ctx.clearRect(0, 0, w, h);
3399
+ const barCount = 40;
3394
3400
  const gap = 2;
3401
+ const barWidth = Math.max(2, (w - (barCount - 1) * gap) / barCount);
3395
3402
  const samplesPerBar = Math.floor(bufferLength / barCount);
3396
3403
  for (let i = 0; i < barCount; i++) {
3397
- let sum = 0;
3404
+ let sumSq = 0;
3398
3405
  for (let j = 0; j < samplesPerBar; j++) {
3399
- const val = dataArray[i * samplesPerBar + j] - 128;
3400
- sum += Math.abs(val);
3406
+ const val = (dataArray[i * samplesPerBar + j] - 128) / 128;
3407
+ sumSq += val * val;
3401
3408
  }
3402
- const avg = sum / samplesPerBar;
3403
- const barHeight = Math.max(3, avg / 128 * height * 2.5);
3409
+ const rms = Math.sqrt(sumSq / samplesPerBar);
3410
+ const target = Math.max(2, rms * h * 3);
3411
+ smoothed[i] += (target - smoothed[i]) * (target > smoothed[i] ? 0.4 : 0.15);
3412
+ const barHeight = Math.min(smoothed[i], h - 2);
3404
3413
  const x = i * (barWidth + gap);
3405
- const y = (height - barHeight) / 2;
3414
+ const y = (h - barHeight) / 2;
3415
+ const radius = Math.min(barWidth / 2, barHeight / 2);
3406
3416
  ctx.fillStyle = "#3b82f6";
3407
3417
  ctx.beginPath();
3408
- ctx.roundRect(x, y, barWidth, barHeight, barWidth / 2);
3418
+ ctx.roundRect(x, y, barWidth, barHeight, radius);
3409
3419
  ctx.fill();
3410
3420
  }
3411
3421
  };
3412
3422
  draw();
3413
3423
  }, []);
3424
+ _react.useEffect.call(void 0, () => {
3425
+ if (isRecording && canvasRef.current && analyserRef.current) {
3426
+ startWaveformLoop();
3427
+ }
3428
+ }, [isRecording, startWaveformLoop]);
3414
3429
  const startRecording = _react.useCallback.call(void 0, async () => {
3415
3430
  const SpeechRecognitionCtor = getSpeechRecognition();
3416
3431
  if (!SpeechRecognitionCtor) return;
@@ -3467,7 +3482,6 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
3467
3482
  recordingTimerRef.current = setInterval(() => {
3468
3483
  setRecordingTime((t) => t + 1);
3469
3484
  }, 1e3);
3470
- requestAnimationFrame(() => drawWaveform());
3471
3485
  silenceTimerRef.current = setTimeout(() => {
3472
3486
  stopRecording(false);
3473
3487
  }, silenceTimeout + 1e3);
@@ -3476,7 +3490,7 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
3476
3490
  setFileError("Microphone access denied");
3477
3491
  setTimeout(() => setFileError(null), 3e3);
3478
3492
  }
3479
- }, [_optionalChain([sttConfig, 'optionalAccess', _57 => _57.language]), silenceTimeout, drawWaveform]);
3493
+ }, [_optionalChain([sttConfig, 'optionalAccess', _57 => _57.language]), silenceTimeout]);
3480
3494
  const finishRecording = _react.useCallback.call(void 0, () => {
3481
3495
  const transcript = finalTranscriptRef.current.trim();
3482
3496
  setIsRecording(false);
@@ -3653,10 +3667,10 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
3653
3667
  style: {
3654
3668
  gridTemplateColumns: isRecording ? gridColsRecording : gridCols,
3655
3669
  gridTemplateAreas: isRecording ? '"plus waveform stop"' : gridAreas,
3656
- alignItems: "end"
3670
+ alignItems: isRecording ? "center" : "end"
3657
3671
  },
3658
3672
  children: [
3659
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative flex-shrink-0 self-end", style: { gridArea: "plus" }, children: isRecording ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "apteva-composer-rec-dot", title: "Recording...", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", {}) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
3673
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "relative flex-shrink-0", style: { gridArea: "plus", alignSelf: isRecording ? "center" : "end" }, children: isRecording ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "apteva-composer-rec-dot", title: "Recording...", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", {}) }) : /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
3660
3674
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3661
3675
  "button",
3662
3676
  {
@@ -3717,14 +3731,12 @@ function Composer({ onSendMessage, placeholder = "Type a message...", disabled =
3717
3731
  "canvas",
3718
3732
  {
3719
3733
  ref: canvasRef,
3720
- width: 300,
3721
- height: 36,
3722
3734
  className: "apteva-composer-waveform-canvas"
3723
3735
  }
3724
3736
  ),
3725
3737
  /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "apteva-composer-recording-timer", children: formatTime(recordingTime) })
3726
3738
  ] }),
3727
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "self-end", style: { gridArea: "stop" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3739
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { className: "self-center", style: { gridArea: "stop" }, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3728
3740
  "button",
3729
3741
  {
3730
3742
  onClick: () => stopRecording(false),