@fluencypassdevs/cycle 1.32.0 → 1.33.1
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/bin/components.generated.mjs +70 -3
- package/dist/{chunk-GDPUWRNH.js → chunk-2MGHBZ7I.js} +9 -6
- package/dist/chunk-2MGHBZ7I.js.map +1 -0
- package/dist/{chunk-KNJTTOAD.js → chunk-2NVKK7UB.js} +3 -3
- package/dist/chunk-2NVKK7UB.js.map +1 -0
- package/dist/{chunk-VZ2GYSNK.js → chunk-OE4CHHIW.js} +46 -11
- package/dist/chunk-OE4CHHIW.js.map +1 -0
- package/dist/{chunk-OFGJDRRR.js → chunk-OZCMOOT7.js} +3 -3
- package/dist/{chunk-OFGJDRRR.js.map → chunk-OZCMOOT7.js.map} +1 -1
- package/dist/{chunk-WVCNTN4F.js → chunk-R7QITHNQ.js} +3 -3
- package/dist/{chunk-WVCNTN4F.js.map → chunk-R7QITHNQ.js.map} +1 -1
- package/dist/composites/chat-thread.js +2 -2
- package/dist/index.js +5 -5
- package/dist/lib/utils.js +0 -1
- package/dist/styles/tokens.css +24 -24
- package/dist/ui/chat-message.d.ts +20 -3
- package/dist/ui/chat-message.js +1 -1
- package/dist/ui/circular-progress.d.ts +6 -2
- package/dist/ui/circular-progress.js +1 -1
- package/dist/ui/file-dropzone.js +2 -2
- package/dist/ui/progress.d.ts +3 -1
- package/dist/ui/progress.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-GDPUWRNH.js.map +0 -1
- package/dist/chunk-KNJTTOAD.js.map +0 -1
- package/dist/chunk-VZ2GYSNK.js.map +0 -1
|
@@ -227,7 +227,7 @@ export const COMPONENTS = [
|
|
|
227
227
|
{
|
|
228
228
|
"name": "Progress",
|
|
229
229
|
"import": "import { Progress } from \"@fluencypassdevs/cycle\"",
|
|
230
|
-
"description": "Barra de progresso. 4 sizes (xs, sm, default, lg), 4 variants (default, secondary, destructive, muted). Prop theme aplica cor apenas no indicator.",
|
|
230
|
+
"description": "Barra de progresso. 4 sizes (xs, sm, default, lg), 4 variants (default, secondary, destructive, muted). Prop theme aplica cor apenas no indicator. `className` vai para o track; `indicatorClassName` para a barra preenchida. Transicao respeita prefers-reduced-motion. Anuncia aria-valuenow.",
|
|
231
231
|
"props": [
|
|
232
232
|
{
|
|
233
233
|
"name": "value",
|
|
@@ -248,6 +248,11 @@ export const COMPONENTS = [
|
|
|
248
248
|
"name": "theme",
|
|
249
249
|
"type": "string",
|
|
250
250
|
"default": "-"
|
|
251
|
+
},
|
|
252
|
+
{
|
|
253
|
+
"name": "indicatorClassName",
|
|
254
|
+
"type": "string",
|
|
255
|
+
"default": "-"
|
|
251
256
|
}
|
|
252
257
|
],
|
|
253
258
|
"example": "<Progress value={60} />\n<Progress value={80} size=\"lg\" theme=\"brand\" />",
|
|
@@ -371,7 +376,7 @@ export const COMPONENTS = [
|
|
|
371
376
|
{
|
|
372
377
|
"name": "CircularProgress",
|
|
373
378
|
"import": "import { CircularProgress } from \"@fluencypassdevs/cycle\"",
|
|
374
|
-
"description": "Indicador de progresso circular com porcentagem 0-100 no centro. 4 sizes (xs=48px, sm=64px, default=80px, lg=120px). Prop autoTheme escolhe cor baseada no value (0-33 critical, 34-66 warning, 67-100 positive). Prop theme aceita qualquer dos 8 temas Cycle.",
|
|
379
|
+
"description": "Indicador de progresso circular com porcentagem 0-100 no centro. 4 sizes (xs=48px, sm=64px, default=80px, lg=120px). Prop autoTheme escolhe cor baseada no value (0-33 critical, 34-66 warning, 67-100 positive). Prop theme aceita qualquer dos 8 temas Cycle. `label` aceita ReactNode para tipografar o centro (ex.: numero grande + unidade).",
|
|
375
380
|
"props": [
|
|
376
381
|
{
|
|
377
382
|
"name": "value",
|
|
@@ -400,7 +405,7 @@ export const COMPONENTS = [
|
|
|
400
405
|
},
|
|
401
406
|
{
|
|
402
407
|
"name": "label",
|
|
403
|
-
"type": "
|
|
408
|
+
"type": "React.ReactNode",
|
|
404
409
|
"default": "-"
|
|
405
410
|
}
|
|
406
411
|
],
|
|
@@ -1047,6 +1052,68 @@ export const COMPONENTS = [
|
|
|
1047
1052
|
"bot"
|
|
1048
1053
|
]
|
|
1049
1054
|
},
|
|
1055
|
+
{
|
|
1056
|
+
"name": "ChatAudio",
|
|
1057
|
+
"import": "import { ChatAudio } from \"@fluencypassdevs/cycle\"",
|
|
1058
|
+
"description": "Player de audio compacto do chat (waveform, tempo, velocidade) — o mesmo usado dentro do ChatMessage. Com `src` toca o arquivo e analisa o waveform. Sem `src` vira casca visual controlada pelo consumidor: `playing` + `onPlayingChange`, `currentTime`/`duration` e `onSpeedChange` — para TTS sem arquivo (speechSynthesis). Sem arquivo, passe `peaks` ou usa o waveform padrao.",
|
|
1059
|
+
"props": [
|
|
1060
|
+
{
|
|
1061
|
+
"name": "src",
|
|
1062
|
+
"type": "string",
|
|
1063
|
+
"default": "-"
|
|
1064
|
+
},
|
|
1065
|
+
{
|
|
1066
|
+
"name": "playing",
|
|
1067
|
+
"type": "boolean",
|
|
1068
|
+
"default": "- (nao controlado)"
|
|
1069
|
+
},
|
|
1070
|
+
{
|
|
1071
|
+
"name": "onPlayingChange",
|
|
1072
|
+
"type": "(playing: boolean) => void",
|
|
1073
|
+
"default": "-"
|
|
1074
|
+
},
|
|
1075
|
+
{
|
|
1076
|
+
"name": "currentTime",
|
|
1077
|
+
"type": "number",
|
|
1078
|
+
"default": "-"
|
|
1079
|
+
},
|
|
1080
|
+
{
|
|
1081
|
+
"name": "duration",
|
|
1082
|
+
"type": "number",
|
|
1083
|
+
"default": "-"
|
|
1084
|
+
},
|
|
1085
|
+
{
|
|
1086
|
+
"name": "onSpeedChange",
|
|
1087
|
+
"type": "(speed: number) => void",
|
|
1088
|
+
"default": "-"
|
|
1089
|
+
},
|
|
1090
|
+
{
|
|
1091
|
+
"name": "peaks",
|
|
1092
|
+
"type": "number[] (0-1)",
|
|
1093
|
+
"default": "-"
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
"name": "barCount",
|
|
1097
|
+
"type": "number",
|
|
1098
|
+
"default": "60"
|
|
1099
|
+
},
|
|
1100
|
+
{
|
|
1101
|
+
"name": "variant",
|
|
1102
|
+
"type": "\"neutral\" | \"brand\"",
|
|
1103
|
+
"default": "\"neutral\""
|
|
1104
|
+
}
|
|
1105
|
+
],
|
|
1106
|
+
"example": "<ChatAudio src=\"/resposta.mp3\" />\n\n// TTS sem arquivo (speechSynthesis):\n<ChatAudio playing={playing} onPlayingChange={handlePlaying} onSpeedChange={setRate} />",
|
|
1107
|
+
"keywords": [
|
|
1108
|
+
"audio",
|
|
1109
|
+
"tts",
|
|
1110
|
+
"voz",
|
|
1111
|
+
"chat",
|
|
1112
|
+
"waveform",
|
|
1113
|
+
"speechSynthesis",
|
|
1114
|
+
"player"
|
|
1115
|
+
]
|
|
1116
|
+
},
|
|
1050
1117
|
{
|
|
1051
1118
|
"name": "MessageRating",
|
|
1052
1119
|
"import": "import { MessageRating } from \"@fluencypassdevs/cycle\"",
|
|
@@ -21,7 +21,7 @@ var progressVariants = cva(
|
|
|
21
21
|
}
|
|
22
22
|
);
|
|
23
23
|
var indicatorVariants = cva(
|
|
24
|
-
"h-full w-full flex-1 rounded-full transition-all",
|
|
24
|
+
"h-full w-full flex-1 rounded-full motion-safe:transition-all",
|
|
25
25
|
{
|
|
26
26
|
variants: {
|
|
27
27
|
variant: {
|
|
@@ -42,25 +42,28 @@ function Progress(_a) {
|
|
|
42
42
|
value,
|
|
43
43
|
size,
|
|
44
44
|
variant,
|
|
45
|
-
theme
|
|
45
|
+
theme,
|
|
46
|
+
indicatorClassName
|
|
46
47
|
} = _b, props = __objRest(_b, [
|
|
47
48
|
"className",
|
|
48
49
|
"value",
|
|
49
50
|
"size",
|
|
50
51
|
"variant",
|
|
51
|
-
"theme"
|
|
52
|
+
"theme",
|
|
53
|
+
"indicatorClassName"
|
|
52
54
|
]);
|
|
53
55
|
return /* @__PURE__ */ jsx(
|
|
54
56
|
Progress$1.Root,
|
|
55
57
|
__spreadProps(__spreadValues({
|
|
56
58
|
"data-slot": "progress",
|
|
59
|
+
value,
|
|
57
60
|
className: cn(progressVariants({ size }), className)
|
|
58
61
|
}, props), {
|
|
59
62
|
children: /* @__PURE__ */ jsx(
|
|
60
63
|
Progress$1.Indicator,
|
|
61
64
|
{
|
|
62
65
|
"data-slot": "progress-indicator",
|
|
63
|
-
className: cn(theme, indicatorVariants({ variant })),
|
|
66
|
+
className: cn(theme, indicatorVariants({ variant }), indicatorClassName),
|
|
64
67
|
style: { transform: `translateX(-${100 - (value || 0)}%)` }
|
|
65
68
|
}
|
|
66
69
|
)
|
|
@@ -69,5 +72,5 @@ function Progress(_a) {
|
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
export { Progress, indicatorVariants, progressVariants };
|
|
72
|
-
//# sourceMappingURL=chunk-
|
|
73
|
-
//# sourceMappingURL=chunk-
|
|
75
|
+
//# sourceMappingURL=chunk-2MGHBZ7I.js.map
|
|
76
|
+
//# sourceMappingURL=chunk-2MGHBZ7I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ui/progress.tsx"],"names":["ProgressPrimitive"],"mappings":";;;;;;AAUA,IAAM,gBAAA,GAAmB,GAAA;AAAA,EACvB,+DAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,IAAA,EAAM;AAAA,QACJ,EAAA,EAAI,KAAA;AAAA,QACJ,EAAA,EAAI,OAAA;AAAA,QACJ,OAAA,EAAS,KAAA;AAAA,QACT,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,IAAA,EAAM;AAAA;AACR;AAEJ;AAIA,IAAM,iBAAA,GAAoB,GAAA;AAAA,EACxB,8DAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA,QACP,OAAA,EAAS,YAAA;AAAA,QACT,SAAA,EAAW,cAAA;AAAA,QACX,WAAA,EAAa,gBAAA;AAAA,QACb,KAAA,EAAO;AAAA;AACT,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS;AAAA;AACX;AAEJ;AAYA,SAAS,SAAS,EAAA,EAQA;AARA,EAAA,IAAA,EAAA,GAAA,EAAA,EAChB;AAAA,IAAA,SAAA;AAAA,IACA,KAAA;AAAA,IACA,IAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA;AAAA,GA9DF,GAwDkB,EAAA,EAOb,KAAA,GAAA,SAAA,CAPa,EAAA,EAOb;AAAA,IANH,WAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA;AAAA,IACA,OAAA;AAAA,IACA;AAAA,GAAA,CAAA;AAGA,EAAA,uBACE,GAAA;AAAA,IAACA,UAAA,CAAkB,IAAA;AAAA,IAAlB,aAAA,CAAA,cAAA,CAAA;AAAA,MACC,WAAA,EAAU,UAAA;AAAA,MACV,KAAA;AAAA,MACA,WAAW,EAAA,CAAG,gBAAA,CAAiB,EAAE,IAAA,EAAM,GAAG,SAAS;AAAA,KAAA,EAC/C,KAAA,CAAA,EAJL;AAAA,MAMC,QAAA,kBAAA,GAAA;AAAA,QAACA,UAAA,CAAkB,SAAA;AAAA,QAAlB;AAAA,UACC,WAAA,EAAU,oBAAA;AAAA,UACV,SAAA,EAAW,GAAG,KAAA,EAAO,iBAAA,CAAkB,EAAE,OAAA,EAAS,GAAG,kBAAkB,CAAA;AAAA,UACvE,OAAO,EAAE,SAAA,EAAW,eAAe,GAAA,IAAO,KAAA,IAAS,EAAE,CAAA,EAAA,CAAA;AAAK;AAAA;AAC5D,KAAA;AAAA,GACF;AAEJ","file":"chunk-2MGHBZ7I.js","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { Progress as ProgressPrimitive } from \"radix-ui\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* ─── Track variants ─── */\n\nconst progressVariants = cva(\n \"relative w-full overflow-hidden rounded-full bg-neutral-input\",\n {\n variants: {\n size: {\n xs: \"h-1\",\n sm: \"h-1.5\",\n default: \"h-2\",\n lg: \"h-3\",\n },\n },\n defaultVariants: {\n size: \"default\",\n },\n }\n)\n\n/* ─── Indicator variants ─── */\n\nconst indicatorVariants = cva(\n \"h-full w-full flex-1 rounded-full motion-safe:transition-all\",\n {\n variants: {\n variant: {\n default: \"bg-primary\",\n secondary: \"bg-secondary\",\n destructive: \"bg-destructive\",\n muted: \"bg-muted-foreground\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n },\n }\n)\n\nexport interface ProgressProps\n extends Omit<React.ComponentProps<typeof ProgressPrimitive.Root>, \"children\">,\n VariantProps<typeof progressVariants>,\n VariantProps<typeof indicatorVariants> {\n /** Classe de tema aplicada apenas no indicator (ex: \"theme-class\") */\n theme?: string\n /** Classes extras no indicator (a barra preenchida). `className` vai para o track. */\n indicatorClassName?: string\n}\n\nfunction Progress({\n className,\n value,\n size,\n variant,\n theme,\n indicatorClassName,\n ...props\n}: ProgressProps) {\n return (\n <ProgressPrimitive.Root\n data-slot=\"progress\"\n value={value}\n className={cn(progressVariants({ size }), className)}\n {...props}\n >\n <ProgressPrimitive.Indicator\n data-slot=\"progress-indicator\"\n className={cn(theme, indicatorVariants({ variant }), indicatorClassName)}\n style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n />\n </ProgressPrimitive.Root>\n )\n}\n\nexport { Progress, progressVariants, indicatorVariants }\n"]}
|
|
@@ -61,7 +61,7 @@ function CircularProgress(_a) {
|
|
|
61
61
|
"aria-valuenow": clamped,
|
|
62
62
|
"aria-valuemin": 0,
|
|
63
63
|
"aria-valuemax": 100,
|
|
64
|
-
"aria-label": !showLabel &&
|
|
64
|
+
"aria-label": !showLabel && label == null ? `Progress: ${Math.round(clamped)}%` : void 0,
|
|
65
65
|
className: cn(circularProgressVariants({ size }), resolvedTheme, className),
|
|
66
66
|
style: { width: px, height: px }
|
|
67
67
|
}, props), {
|
|
@@ -126,5 +126,5 @@ function CircularProgress(_a) {
|
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
export { CircularProgress, circularProgressVariants };
|
|
129
|
-
//# sourceMappingURL=chunk-
|
|
130
|
-
//# sourceMappingURL=chunk-
|
|
129
|
+
//# sourceMappingURL=chunk-2NVKK7UB.js.map
|
|
130
|
+
//# sourceMappingURL=chunk-2NVKK7UB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ui/circular-progress.tsx"],"names":[],"mappings":"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","file":"chunk-2NVKK7UB.js","sourcesContent":["import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\n/* ─── Size config ─── */\n\nconst SIZE_CONFIG = {\n xs: { px: 48, stroke: 4, fontClass: \"text-sm font-semibold\" },\n sm: { px: 64, stroke: 5, fontClass: \"text-base font-semibold\" },\n default: { px: 80, stroke: 6, fontClass: \"text-2xl font-semibold\" },\n lg: { px: 120, stroke: 8, fontClass: \"text-3xl font-semibold\" },\n} as const\n\nconst circularProgressVariants = cva(\"relative inline-flex shrink-0\", {\n variants: {\n size: {\n xs: \"size-12\",\n sm: \"size-16\",\n default: \"size-20\",\n lg: \"size-30\",\n },\n },\n defaultVariants: {\n size: \"default\",\n },\n})\n\n/* ─── Auto-theme thresholds ─── */\n\nfunction getAutoTheme(value: number): string {\n if (value < 34) return \"theme-critical\"\n if (value < 67) return \"theme-warning\"\n return \"theme-positive\"\n}\n\nexport interface CircularProgressProps\n extends Omit<React.ComponentProps<\"div\">, \"children\">,\n VariantProps<typeof circularProgressVariants> {\n /** Valor de 0 a 100 (clamped) */\n value: number\n /** Classe de tema fixa (ex: \"theme-brand\", \"theme-class\"). Tem precedencia sobre autoTheme. */\n theme?: string\n /** Se true, escolhe o tema automaticamente: 0–33 critical, 34–66 warning, 67–100 positive. */\n autoTheme?: boolean\n /** Mostrar label central com a porcentagem (default true) */\n showLabel?: boolean\n /**\n * Label customizado — sobrescreve `${value}%`. Aceita ReactNode para tipografar o\n * centro (ex.: numero grande + unidade menor). A fonte padrao do size continua\n * aplicada no wrapper; elementos internos podem sobrescrever.\n */\n label?: React.ReactNode\n}\n\nfunction CircularProgress({\n value,\n size = \"default\",\n theme,\n autoTheme = false,\n showLabel = true,\n label,\n className,\n ...props\n}: CircularProgressProps) {\n const clamped = Math.min(100, Math.max(0, value))\n const config = SIZE_CONFIG[size ?? \"default\"]\n const { px, stroke, fontClass } = config\n\n const radius = (px - stroke) / 2\n const circumference = 2 * Math.PI * radius\n const dash = (clamped / 100) * circumference\n\n const resolvedTheme = theme ?? (autoTheme ? getAutoTheme(clamped) : undefined)\n const displayLabel: React.ReactNode = label ?? `${Math.round(clamped)}%`\n\n return (\n <div\n data-slot=\"circular-progress\"\n role=\"progressbar\"\n aria-valuenow={clamped}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-label={!showLabel && label == null ? `Progress: ${Math.round(clamped)}%` : undefined}\n className={cn(circularProgressVariants({ size }), resolvedTheme, className)}\n style={{ width: px, height: px }}\n {...props}\n >\n {/* Inner pastel fill */}\n <div\n className={cn(\n \"absolute rounded-full\",\n resolvedTheme ? \"bg-accent\" : \"bg-neutral-input/40\"\n )}\n style={{ inset: stroke }}\n />\n\n {/* Progress arcs */}\n <svg\n className=\"absolute inset-0 size-full -rotate-90\"\n viewBox={`0 0 ${px} ${px}`}\n aria-hidden=\"true\"\n >\n <circle\n cx={px / 2}\n cy={px / 2}\n r={radius}\n fill=\"none\"\n strokeWidth={stroke}\n className={cn(resolvedTheme ? \"stroke-muted\" : \"stroke-neutral-input\")}\n />\n <circle\n cx={px / 2}\n cy={px / 2}\n r={radius}\n fill=\"none\"\n strokeWidth={stroke}\n strokeLinecap=\"round\"\n strokeDasharray={`${dash} ${circumference}`}\n className={cn(\"transition-[stroke-dasharray] duration-500\", resolvedTheme ? \"stroke-primary\" : \"stroke-neutral-foreground\")}\n />\n </svg>\n\n {/* Center label */}\n {showLabel && (\n <span\n className={cn(\n \"relative z-10 flex size-full items-center justify-center text-neutral-foreground\",\n fontClass\n )}\n >\n {displayLabel}\n </span>\n )}\n </div>\n )\n}\n\nexport { CircularProgress, circularProgressVariants }\n"]}
|
|
@@ -189,23 +189,50 @@ function ChatAudio(_a) {
|
|
|
189
189
|
variant = "neutral",
|
|
190
190
|
peaks: providedPeaks,
|
|
191
191
|
barCount = 60,
|
|
192
|
+
playing: playingProp,
|
|
193
|
+
onPlayingChange,
|
|
194
|
+
currentTime: currentTimeProp,
|
|
195
|
+
duration: durationProp,
|
|
196
|
+
onSpeedChange,
|
|
192
197
|
className
|
|
193
198
|
} = _b, props = __objRest(_b, [
|
|
194
199
|
"src",
|
|
195
200
|
"variant",
|
|
196
201
|
"peaks",
|
|
197
202
|
"barCount",
|
|
203
|
+
"playing",
|
|
204
|
+
"onPlayingChange",
|
|
205
|
+
"currentTime",
|
|
206
|
+
"duration",
|
|
207
|
+
"onSpeedChange",
|
|
198
208
|
"className"
|
|
199
209
|
]);
|
|
200
210
|
var _a2;
|
|
201
211
|
const audioRef = React.useRef(null);
|
|
202
|
-
const
|
|
203
|
-
const [
|
|
204
|
-
const
|
|
212
|
+
const isControlled = playingProp !== void 0;
|
|
213
|
+
const [internalPlaying, setInternalPlaying] = React.useState(false);
|
|
214
|
+
const isPlaying = isControlled ? playingProp : internalPlaying;
|
|
215
|
+
const [mediaTime, setCurrentTime] = React.useState(0);
|
|
216
|
+
const [mediaDuration, setDuration] = React.useState(0);
|
|
217
|
+
const currentTime = currentTimeProp != null ? currentTimeProp : mediaTime;
|
|
218
|
+
const duration = durationProp != null ? durationProp : mediaDuration;
|
|
219
|
+
const handleMediaPlaying = React.useCallback(
|
|
220
|
+
(next) => {
|
|
221
|
+
setInternalPlaying(next);
|
|
222
|
+
onPlayingChange == null ? void 0 : onPlayingChange(next);
|
|
223
|
+
},
|
|
224
|
+
[onPlayingChange]
|
|
225
|
+
);
|
|
226
|
+
React.useEffect(() => {
|
|
227
|
+
const audio = audioRef.current;
|
|
228
|
+
if (!isControlled || !audio) return;
|
|
229
|
+
if (playingProp && audio.paused) audio.play().catch(() => onPlayingChange == null ? void 0 : onPlayingChange(false));
|
|
230
|
+
else if (!playingProp && !audio.paused) audio.pause();
|
|
231
|
+
}, [isControlled, playingProp, src, onPlayingChange]);
|
|
205
232
|
const [speed, setSpeed] = React.useState(1);
|
|
206
233
|
const [computedPeaks, setComputedPeaks] = React.useState(null);
|
|
207
234
|
React.useEffect(() => {
|
|
208
|
-
if (providedPeaks) return;
|
|
235
|
+
if (providedPeaks || !src) return;
|
|
209
236
|
let cancelled = false;
|
|
210
237
|
getPeaks(src, barCount).then((p) => {
|
|
211
238
|
if (!cancelled) setComputedPeaks(p);
|
|
@@ -259,8 +286,15 @@ function ChatAudio(_a) {
|
|
|
259
286
|
return () => cancelAnimationFrame(rafId);
|
|
260
287
|
}, [isPlaying]);
|
|
261
288
|
const togglePlay = () => {
|
|
289
|
+
if (isControlled) {
|
|
290
|
+
onPlayingChange == null ? void 0 : onPlayingChange(!playingProp);
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
262
293
|
const audio = audioRef.current;
|
|
263
|
-
if (!audio)
|
|
294
|
+
if (!audio) {
|
|
295
|
+
handleMediaPlaying(!internalPlaying);
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
264
298
|
if (audio.paused) {
|
|
265
299
|
audio.play().catch(() => {
|
|
266
300
|
});
|
|
@@ -274,6 +308,7 @@ function ChatAudio(_a) {
|
|
|
274
308
|
const next = (_a3 = SPEED_OPTIONS[(idx + 1) % SPEED_OPTIONS.length]) != null ? _a3 : 1;
|
|
275
309
|
setSpeed(next);
|
|
276
310
|
if (audioRef.current) audioRef.current.playbackRate = next;
|
|
311
|
+
onSpeedChange == null ? void 0 : onSpeedChange(next);
|
|
277
312
|
};
|
|
278
313
|
const waveformRef = React.useRef(null);
|
|
279
314
|
const isDraggingRef = React.useRef(false);
|
|
@@ -375,19 +410,19 @@ function ChatAudio(_a) {
|
|
|
375
410
|
)
|
|
376
411
|
}, props), {
|
|
377
412
|
children: [
|
|
378
|
-
/* @__PURE__ */ jsx(
|
|
413
|
+
src && /* @__PURE__ */ jsx(
|
|
379
414
|
"audio",
|
|
380
415
|
{
|
|
381
416
|
ref: audioRef,
|
|
382
417
|
src,
|
|
383
418
|
preload: "metadata",
|
|
384
|
-
onPlay: () =>
|
|
385
|
-
onPause: () =>
|
|
419
|
+
onPlay: () => handleMediaPlaying(true),
|
|
420
|
+
onPause: () => handleMediaPlaying(false),
|
|
386
421
|
onTimeUpdate: (e) => {
|
|
387
422
|
setCurrentTime(e.currentTarget.currentTime);
|
|
388
423
|
setDurationSafe(e.currentTarget.duration);
|
|
389
424
|
},
|
|
390
|
-
onEnded: () =>
|
|
425
|
+
onEnded: () => handleMediaPlaying(false)
|
|
391
426
|
}
|
|
392
427
|
),
|
|
393
428
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 flex-1 min-w-0", children: [
|
|
@@ -508,5 +543,5 @@ function ChatMessage(_a) {
|
|
|
508
543
|
}
|
|
509
544
|
|
|
510
545
|
export { ChatAudio, ChatMessage, chatMessageVariants };
|
|
511
|
-
//# sourceMappingURL=chunk-
|
|
512
|
-
//# sourceMappingURL=chunk-
|
|
546
|
+
//# sourceMappingURL=chunk-OE4CHHIW.js.map
|
|
547
|
+
//# sourceMappingURL=chunk-OE4CHHIW.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/ui/chat-message.tsx"],"names":["_a","waveform"],"mappings":"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","file":"chunk-OE4CHHIW.js","sourcesContent":["\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Play, Pause, User } from \"lucide-react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Avatar, AvatarImage, AvatarFallback } from \"@/components/ui/avatar\"\nimport { LikeDislike, type LikeDislikeValue } from \"@/components/ui/like-dislike\"\nimport { Ai, CycleIcon } from \"@/components/icons\"\n\n/* ─── Container variants ──────────────────────────────────────── */\n\nconst chatMessageVariants = cva(\"flex w-full text-sm\", {\n variants: {\n persona: {\n ai: \"justify-start\",\n user: \"justify-end\",\n system: \"justify-center\",\n },\n },\n defaultVariants: {\n persona: \"ai\",\n },\n})\n\n/* ─── Types ───────────────────────────────────────────────────── */\n\nexport interface ChatMessageProps\n extends Omit<React.ComponentProps<\"div\">, \"content\">,\n VariantProps<typeof chatMessageVariants> {\n /** Quem enviou: AI (assistente), user (aluno), system (mensagem do sistema) */\n persona: \"ai\" | \"user\" | \"system\"\n /** Texto da mensagem. Convencao do produto:\n * - Em `persona=\"ai\"` com `audioSrc`, o texto e o roteiro/legenda do audio TTS.\n * - Em `persona=\"user\"` com `audioSrc`, o texto e a transcricao do audio (gerada por IA).\n * Em ambos os casos, aparece em bubble separada acima do audio. */\n text?: string\n /** URL do audio — renderiza AudioPlayer dentro do bubble. Convencao do produto:\n * toda msg da IA tem `text` + `audioSrc` (TTS) e toda msg do user com audio tem\n * `text` (transcricao). Garante acessibilidade (leitura + escuta) e busca no historico. */\n audioSrc?: string\n /** Avatar do user (so usado em persona=\"user\") */\n avatar?: string\n /** Nome do user para fallback do avatar */\n author?: string\n /** Mostrar like/dislike inline (so faz sentido em persona=\"ai\") */\n showFeedback?: boolean\n /** Valor controlado do feedback */\n feedbackValue?: LikeDislikeValue\n /** Callback quando feedback muda */\n onFeedbackChange?: (value: LikeDislikeValue) => void\n /** Estado de loading: mostra typing indicator (\"...\") */\n loading?: boolean\n /**\n * Classe de tema da bolha do user (bubble, audio e badge de velocidade herdam\n * `bg-accent`/`bg-primary` dela). Default `\"theme-positive\"` — verde, leitura\n * familiar de \"mensagem enviada\" (WhatsApp); nao colide com critical nem disputa\n * com os botoes brand. So tem efeito em `persona=\"user\"`. Ex.: `theme=\"theme-class\"`.\n */\n theme?: string\n}\n\n/* ─── Helpers ─────────────────────────────────────────────────── */\n\nfunction getInitials(name?: string): string {\n if (!name) return \"\"\n return name\n .split(\" \")\n .slice(0, 2)\n .map((w) => w[0])\n .join(\"\")\n .toUpperCase()\n}\n\n/* ─── Typing indicator ────────────────────────────────────────── */\n\nfunction TypingDots() {\n return (\n <span\n className=\"inline-flex items-center gap-1\"\n aria-label=\"Digitando...\"\n role=\"status\"\n >\n <span className=\"size-1.5 rounded-full bg-current opacity-40 animate-bounce [animation-delay:-0.3s]\" />\n <span className=\"size-1.5 rounded-full bg-current opacity-40 animate-bounce [animation-delay:-0.15s]\" />\n <span className=\"size-1.5 rounded-full bg-current opacity-40 animate-bounce\" />\n </span>\n )\n}\n\n/* ─── ChatAudio (compact inline audio player com waveform real) ── */\n\n/** Fallback estatico (valores 0-1) — usado enquanto peaks reais carregam ou quando audio nao pode ser analisado (CORS/decode error) */\nconst STATIC_FALLBACK_PEAKS = [\n 2, 2, 2, 2, 8, 24, 18, 24, 8, 18, 24, 24, 18, 24, 18, 18, 24, 24, 32, 24,\n 24, 32, 24, 32, 32, 24, 18, 24, 24, 18, 24, 18, 18, 24, 24, 24, 24, 24, 32, 24,\n 32, 18, 24, 18, 24, 18, 24, 18, 18, 24, 24, 24, 24, 24, 32, 24, 32, 18, 24, 18,\n 24, 8, 18, 24, 8, 4, 2, 2, 2, 2, 4, 8, 24, 24, 18, 24, 18, 18, 24, 24,\n 32, 24, 24, 32, 24, 32, 32, 24, 18, 24, 24, 18, 24, 8, 18, 24, 8, 2, 2, 4,\n].map((h) => h / 32)\n\nconst MIN_BAR_HEIGHT = 2 // px (silencio)\nconst MAX_BAR_HEIGHT = 32 // px (pico maximo)\nconst SPEED_OPTIONS = [1, 1.25, 1.5, 2, 0.75]\n\n/** Cache modular para evitar re-computar peaks do mesmo audio em multiplas instancias */\nconst peaksCache = new Map<string, number[]>()\n\n/**\n * Calcula picos (amplitude maxima) de um audio dividido em N buckets.\n * Usa Web Audio API (decodeAudioData) — sem dependencias externas.\n * Retorna array de valores 0-1 (normalizado pelo pico maximo).\n */\nasync function calculatePeaks(audioUrl: string, barCount: number): Promise<number[]> {\n const response = await fetch(audioUrl)\n const arrayBuffer = await response.arrayBuffer()\n\n const AudioContextClass =\n window.AudioContext ||\n (window as unknown as { webkitAudioContext: typeof AudioContext }).webkitAudioContext\n const audioContext = new AudioContextClass()\n const audioBuffer = await audioContext.decodeAudioData(arrayBuffer)\n\n const channelData = audioBuffer.getChannelData(0) // mono ou canal esquerdo\n const samplesPerBar = Math.floor(channelData.length / barCount)\n const peaks: number[] = []\n\n for (let i = 0; i < barCount; i++) {\n const start = i * samplesPerBar\n const end = Math.min(start + samplesPerBar, channelData.length)\n let max = 0\n for (let j = start; j < end; j++) {\n const absSample = Math.abs(channelData[j])\n if (absSample > max) max = absSample\n }\n peaks.push(max)\n }\n\n // Normaliza para 0-1 relativo ao pico maximo do clip\n const maxPeak = Math.max(...peaks, 0.01)\n\n // Fecha o AudioContext (libera recursos)\n void audioContext.close()\n\n return peaks.map((p) => p / maxPeak)\n}\n\n/** Wrapper com cache */\nasync function getPeaks(url: string, barCount: number): Promise<number[]> {\n const cacheKey = `${url}|${barCount}`\n const cached = peaksCache.get(cacheKey)\n if (cached) return cached\n const peaks = await calculatePeaks(url, barCount)\n peaksCache.set(cacheKey, peaks)\n return peaks\n}\n\nfunction formatAudioTime(seconds: number): string {\n if (!Number.isFinite(seconds) || seconds < 0) return \"00:00\"\n const m = Math.floor(seconds / 60)\n const s = Math.floor(seconds % 60)\n return `${m.toString().padStart(2, \"0\")}:${s.toString().padStart(2, \"0\")}`\n}\n\nexport interface ChatAudioProps extends React.ComponentProps<\"div\"> {\n /**\n * URL do audio. Opcional: sem `src` o componente vira so a casca visual e o\n * consumidor dirige o estado (`playing`/`onPlayingChange`, `currentTime`/`duration`)\n * — ex.: TTS via speechSynthesis, que nao gera arquivo.\n */\n src?: string\n /**\n * Controla play/pause de fora. Definido = modo controlado: o botao so chama\n * `onPlayingChange` e nao muda sozinho. Com `src`, o <audio> segue a prop.\n */\n playing?: boolean\n /** Chamado quando o usuario pede play/pause (e, com `src`, quando o <audio> muda de estado). */\n onPlayingChange?: (playing: boolean) => void\n /** Tempo atual em segundos, fornecido pelo consumidor. Sobrescreve o do <audio>. */\n currentTime?: number\n /** Duracao em segundos, fornecida pelo consumidor. Sobrescreve a do <audio>. */\n duration?: number\n /** Chamado ao trocar a velocidade no badge (ex.: repassar ao `rate` do speechSynthesis). */\n onSpeedChange?: (speed: number) => void\n /**\n * Variante visual:\n * - `neutral`: container `bg-muted` (cinza claro) — usado em AI messages\n * - `brand`: container `bg-accent` tematizado — usado em User messages.\n * A cor vem do wrapper `.theme-*` do componente pai (ChatMessage aplica\n * `theme-positive` por default; nome mantido por retrocompatibilidade)\n */\n variant?: \"neutral\" | \"brand\"\n /**\n * Array de picos pre-calculados (valores 0-1). Quando fornecido, o componente\n * usa direto sem analisar o audio. Util para SSR, performance ou audios sem CORS.\n * Se nao fornecido, o componente analisa o audio automaticamente via Web Audio API.\n */\n peaks?: number[]\n /**\n * Numero de barras no waveform (default: 60).\n * Ignorado se `peaks` for fornecido (usa o length do array).\n * Reduzido de 100 → 60 para barras nao ficarem finas demais em containers menores.\n */\n barCount?: number\n}\n\nfunction ChatAudio({\n src,\n variant = \"neutral\",\n peaks: providedPeaks,\n barCount = 60,\n playing: playingProp,\n onPlayingChange,\n currentTime: currentTimeProp,\n duration: durationProp,\n onSpeedChange,\n className,\n ...props\n}: ChatAudioProps) {\n const audioRef = React.useRef<HTMLAudioElement>(null)\n const isControlled = playingProp !== undefined\n const [internalPlaying, setInternalPlaying] = React.useState(false)\n const isPlaying = isControlled ? playingProp : internalPlaying\n const [mediaTime, setCurrentTime] = React.useState(0)\n const [mediaDuration, setDuration] = React.useState(0)\n const currentTime = currentTimeProp ?? mediaTime\n const duration = durationProp ?? mediaDuration\n\n /** Estado do <audio> mudou: espelha no interno e avisa o consumidor. */\n const handleMediaPlaying = React.useCallback(\n (next: boolean) => {\n setInternalPlaying(next)\n onPlayingChange?.(next)\n },\n [onPlayingChange]\n )\n\n /** Modo controlado com arquivo: o <audio> segue a prop `playing`. */\n React.useEffect(() => {\n const audio = audioRef.current\n if (!isControlled || !audio) return\n if (playingProp && audio.paused) audio.play().catch(() => onPlayingChange?.(false))\n else if (!playingProp && !audio.paused) audio.pause()\n }, [isControlled, playingProp, src, onPlayingChange])\n const [speed, setSpeed] = React.useState(1)\n const [computedPeaks, setComputedPeaks] = React.useState<number[] | null>(null)\n\n /** Auto-computa peaks se nao foram fornecidos */\n React.useEffect(() => {\n if (providedPeaks || !src) return // consumer ja forneceu (ou nao ha arquivo), skip analise\n let cancelled = false\n getPeaks(src, barCount)\n .then((p) => {\n if (!cancelled) setComputedPeaks(p)\n })\n .catch((err) => {\n /* fallback silencioso: mantem null, usa fallback estatico.\n Causa comum: CORS (audio source nao tem Access-Control-Allow-Origin).\n Log apenas em dev para nao poluir prod. */\n if (process.env.NODE_ENV !== \"production\") {\n console.warn(\n `[ChatAudio] Failed to analyze waveform for \"${src}\". ` +\n `Falling back to static waveform. ` +\n `Reason: ${err instanceof Error ? err.message : String(err)}. ` +\n `Audio source likely missing CORS headers (Access-Control-Allow-Origin).`\n )\n }\n })\n return () => {\n cancelled = true\n }\n }, [src, providedPeaks, barCount])\n\n /** Fallback estatico ajustado para o barCount atual (evita troca visual brusca quando peaks reais carregam) */\n const fallbackPeaks = React.useMemo(() => {\n return Array.from(\n { length: barCount },\n (_, i) => STATIC_FALLBACK_PEAKS[i % STATIC_FALLBACK_PEAKS.length]\n )\n }, [barCount])\n\n /** Resolve peaks: provided > computed > fallback (ajustado por barCount) */\n const peaks = providedPeaks ?? computedPeaks ?? fallbackPeaks\n\n /** Seta duracao apenas se valor for finito e positivo (evita Infinity/NaN) */\n const setDurationSafe = React.useCallback((value: number) => {\n if (Number.isFinite(value) && value > 0) {\n setDuration((prev) => (prev !== value ? value : prev))\n }\n }, [])\n\n /** Subscribe a multiplos eventos para garantir captura da duracao\n * (alguns audio sources nao disparam loadedmetadata, so durationchange/canplay) */\n React.useEffect(() => {\n const audio = audioRef.current\n if (!audio) return\n\n const handleDuration = () => setDurationSafe(audio.duration)\n handleDuration() // checa se ja esta carregado\n\n audio.addEventListener(\"loadedmetadata\", handleDuration)\n audio.addEventListener(\"durationchange\", handleDuration)\n audio.addEventListener(\"canplay\", handleDuration)\n return () => {\n audio.removeEventListener(\"loadedmetadata\", handleDuration)\n audio.removeEventListener(\"durationchange\", handleDuration)\n audio.removeEventListener(\"canplay\", handleDuration)\n }\n }, [src, setDurationSafe])\n\n /** Progresso fluido durante o playback.\n * `timeupdate` dispara ~4x/s (250ms) — a bolinha pulava em stop motion.\n * Enquanto toca, lemos `currentTime` a cada frame via rAF (60fps).\n * `timeupdate` continua como fallback (pause, seek, ended). */\n React.useEffect(() => {\n if (!isPlaying) return\n const audio = audioRef.current\n if (!audio) return\n let rafId = 0\n const tick = () => {\n setCurrentTime(audio.currentTime)\n rafId = requestAnimationFrame(tick)\n }\n rafId = requestAnimationFrame(tick)\n return () => cancelAnimationFrame(rafId)\n }, [isPlaying])\n\n const togglePlay = () => {\n // Controlado: so pede a mudanca — quem decide e o consumidor.\n if (isControlled) {\n onPlayingChange?.(!playingProp)\n return\n }\n const audio = audioRef.current\n // Sem arquivo e sem controle: casca visual, alterna so o estado local.\n if (!audio) {\n handleMediaPlaying(!internalPlaying)\n return\n }\n if (audio.paused) {\n audio.play().catch(() => {})\n } else {\n audio.pause()\n }\n }\n\n const cycleSpeed = () => {\n const idx = SPEED_OPTIONS.indexOf(speed)\n const next = SPEED_OPTIONS[(idx + 1) % SPEED_OPTIONS.length] ?? 1\n setSpeed(next)\n if (audioRef.current) audioRef.current.playbackRate = next\n onSpeedChange?.(next)\n }\n\n /* ─── Seek/drag via pointer no waveform ───────────────────── */\n\n const waveformRef = React.useRef<HTMLDivElement>(null)\n const isDraggingRef = React.useRef(false)\n\n /** Converte clientX (event) em time do audio, baseado na largura do container do waveform */\n const seekToClientX = React.useCallback(\n (clientX: number) => {\n const audio = audioRef.current\n const waveform = waveformRef.current\n if (!audio || !waveform || !duration) return\n const rect = waveform.getBoundingClientRect()\n const x = clientX - rect.left\n const newProgress = Math.max(0, Math.min(x / rect.width, 1))\n audio.currentTime = newProgress * duration\n },\n [duration]\n )\n\n const handlePointerDown = (e: React.PointerEvent<HTMLDivElement>) => {\n if (!duration) return\n isDraggingRef.current = true\n e.currentTarget.setPointerCapture(e.pointerId)\n seekToClientX(e.clientX)\n }\n\n const handlePointerMove = (e: React.PointerEvent<HTMLDivElement>) => {\n if (!isDraggingRef.current) return\n seekToClientX(e.clientX)\n }\n\n const handlePointerUp = (e: React.PointerEvent<HTMLDivElement>) => {\n if (!isDraggingRef.current) return\n isDraggingRef.current = false\n e.currentTarget.releasePointerCapture(e.pointerId)\n }\n\n const progress = duration > 0 ? currentTime / duration : 0\n const displayTime = formatAudioTime(currentTime)\n\n /* Waveform JSX — reusado entre layouts mobile (top) e desktop (inline).\n Barras com largura FIXA de 2px (matches Figma) distribuidas via justify-between\n para preencher toda a largura do container — gap entre barras se torna fluido\n conforme o waveform expande. Garante espacamento simetrico com time (esquerda)\n e speed badge (direita). Pointer events permitem clicar/arrastar para seek. */\n const waveform = (\n <div\n ref={waveformRef}\n className=\"flex-1 relative h-8 min-w-0 touch-none cursor-pointer select-none\"\n onPointerDown={handlePointerDown}\n onPointerMove={handlePointerMove}\n onPointerUp={handlePointerUp}\n onPointerCancel={handlePointerUp}\n role=\"slider\"\n aria-label=\"Posicao do audio\"\n aria-valuemin={0}\n aria-valuemax={Math.round(duration)}\n aria-valuenow={Math.round(currentTime)}\n >\n <div className=\"absolute inset-0 flex items-center justify-between\">\n {peaks.map((peak, i) => {\n const isPlayed = i / peaks.length <= progress\n const height = Math.max(\n MIN_BAR_HEIGHT,\n Math.round(peak * MAX_BAR_HEIGHT)\n )\n return (\n <div\n key={i}\n className={cn(\n \"w-[2px] shrink-0 rounded-full\",\n isPlayed ? \"bg-neutral-foreground\" : \"bg-neutral-ring\"\n )}\n style={{ height: `${height}px` }}\n />\n )\n })}\n </div>\n {/* Bolinha verde — posicionada em PORCENTAGEM da largura do container,\n alinhada com a distribuicao fluida das barras. */}\n {duration > 0 && (\n <div\n className=\"absolute top-1/2 z-10 -translate-y-1/2 -translate-x-1/2 size-3 rounded-full bg-[#098A5E] pointer-events-none shadow-md\"\n style={{ left: `${progress * 100}%` }}\n aria-hidden=\"true\"\n />\n )}\n </div>\n )\n\n /* Time display — reusado entre layouts */\n const timeDisplay = (\n <span className=\"shrink-0 text-sm text-neutral-ring tabular-nums\">\n {displayTime}\n </span>\n )\n\n /* Speed badge — reusado entre layouts */\n const speedBadge = (\n <button\n type=\"button\"\n onClick={cycleSpeed}\n className={cn(\n \"shrink-0 h-[26px] min-w-16 rounded-full text-sm font-medium px-2 transition-opacity hover:opacity-80\",\n variant === \"brand\"\n ? \"bg-muted text-muted-foreground\"\n : \"bg-background text-neutral-muted-foreground\"\n )}\n aria-label={`Velocidade ${speed}x. Clique para alternar.`}\n >\n {speed === 1 ? \"1x\" : `${speed}x`}\n </button>\n )\n\n return (\n <div\n data-slot=\"chat-audio\"\n className={cn(\n \"rounded-2xl w-full max-w-md flex flex-col gap-2 p-3 sm:flex-row sm:items-center sm:gap-2 sm:pl-5 sm:pr-3 sm:py-3\",\n variant === \"brand\" ? \"bg-accent\" : \"bg-muted\",\n className\n )}\n {...props}\n >\n {src && (\n <audio\n ref={audioRef}\n src={src}\n preload=\"metadata\"\n onPlay={() => handleMediaPlaying(true)}\n onPause={() => handleMediaPlaying(false)}\n onTimeUpdate={(e) => {\n setCurrentTime(e.currentTarget.currentTime)\n /* Fallback: alguns sources so expoem duration durante o playback */\n setDurationSafe(e.currentTarget.duration)\n }}\n onEnded={() => handleMediaPlaying(false)}\n />\n )}\n\n {/* Mobile top row + Desktop inline row */}\n <div className=\"flex items-center gap-2 flex-1 min-w-0\">\n {/* Play/Pause — icones FILLED */}\n <button\n type=\"button\"\n onClick={togglePlay}\n className=\"shrink-0 flex items-center justify-center text-neutral-foreground hover:opacity-80 transition-opacity\"\n aria-label={isPlaying ? \"Pausar\" : \"Reproduzir\"}\n >\n {isPlaying ? (\n <Pause className=\"size-4\" fill=\"currentColor\" strokeWidth={0} />\n ) : (\n <Play className=\"size-4\" fill=\"currentColor\" strokeWidth={0} />\n )}\n </button>\n\n {/* Time — apenas desktop (no mobile aparece embaixo) */}\n <div className=\"hidden sm:contents\">{timeDisplay}</div>\n\n {waveform}\n\n {/* Speed — apenas desktop (no mobile aparece embaixo) */}\n <div className=\"hidden sm:contents\">{speedBadge}</div>\n </div>\n\n {/* Mobile bottom row: time + speed badge */}\n <div className=\"flex items-center justify-between sm:hidden\">\n {timeDisplay}\n {speedBadge}\n </div>\n </div>\n )\n}\n\nexport { ChatAudio }\n\n/* ─── Component ───────────────────────────────────────────────── */\n\nfunction ChatMessage({\n persona,\n text,\n audioSrc,\n avatar,\n author,\n showFeedback = false,\n feedbackValue,\n onFeedbackChange,\n loading = false,\n theme = \"theme-positive\",\n className,\n ...props\n}: ChatMessageProps) {\n /* System: centered italic */\n if (persona === \"system\") {\n return (\n <div\n data-slot=\"chat-message\"\n data-persona=\"system\"\n className={cn(chatMessageVariants({ persona }), className)}\n {...props}\n >\n <span className=\"text-xs text-muted-foreground italic\">{text}</span>\n </div>\n )\n }\n\n /* AI: badge quadrado (esquerda, apenas desktop) + conteudo empilhado */\n if (persona === \"ai\") {\n return (\n <div\n data-slot=\"chat-message\"\n data-persona=\"ai\"\n className={cn(chatMessageVariants({ persona }), className)}\n {...props}\n >\n <div className=\"flex gap-3 max-w-[85%] sm:max-w-[75%] w-full\">\n {/* AI badge: oculto no mobile, visivel no desktop */}\n <div className=\"hidden sm:flex shrink-0 size-8 rounded-md bg-primary items-center justify-center theme-brand\">\n <span className=\"text-primary-foreground\">\n <Ai size=\"sm\" decorative />\n </span>\n </div>\n <div className=\"flex flex-col gap-2 min-w-0 flex-1\">\n {loading ? (\n /* Loading: dots dentro de bubble cinza (speech bubble shape — top-left reto em todos os breakpoints) */\n <div className=\"self-start inline-flex items-center rounded-2xl rounded-tl-none bg-muted p-5 text-muted-foreground\">\n <TypingDots />\n </div>\n ) : (\n <>\n {text && (\n /* Text bubble: bg-muted sempre, speech bubble shape (tl-none) em todos os breakpoints */\n <div className=\"rounded-2xl rounded-tl-none bg-muted p-5\">\n <p className=\"text-base leading-6 text-neutral-foreground break-words\">{text}</p>\n </div>\n )}\n {audioSrc && <ChatAudio src={audioSrc} variant=\"neutral\" />}\n {showFeedback && (\n <LikeDislike\n size=\"xs\"\n value={feedbackValue}\n onValueChange={onFeedbackChange}\n />\n )}\n </>\n )}\n </div>\n </div>\n </div>\n )\n }\n\n /* User: bubble (direita) + avatar (apenas desktop, alinhado ao topo) */\n return (\n <div\n data-slot=\"chat-message\"\n data-persona=\"user\"\n className={cn(chatMessageVariants({ persona }), className)}\n {...props}\n >\n <div className=\"flex items-start gap-3 max-w-[85%] sm:max-w-[75%] w-full justify-end\">\n <div className={cn(\"flex flex-col gap-2 min-w-0 items-end flex-1\", theme)}>\n {loading ? (\n /* Loading: dots dentro de bubble tematizada (speech bubble shape — top-right reto em todos os breakpoints) */\n <div className=\"inline-flex items-center rounded-2xl rounded-tr-none bg-accent p-5 text-neutral-muted-foreground\">\n <TypingDots />\n </div>\n ) : (\n <>\n {text && (\n /* Text bubble: speech bubble shape (top-right reto) em todos os breakpoints.\n text-neutral-foreground = preto neutro fixo, nao muda com o tema */\n <div className=\"rounded-2xl rounded-tr-none bg-accent p-5\">\n <p className=\"text-base leading-6 text-neutral-foreground break-words\">{text}</p>\n </div>\n )}\n {audioSrc && <ChatAudio src={audioSrc} variant=\"brand\" />}\n </>\n )}\n </div>\n {/* Avatar: 40x40 rounded-lg, oculto no mobile, alinhado ao topo */}\n <Avatar size=\"lg\" className=\"hidden sm:flex shrink-0 rounded-lg\">\n {avatar && (\n <AvatarImage src={avatar} alt={author ?? \"User\"} className=\"rounded-lg\" />\n )}\n <AvatarFallback className=\"rounded-lg bg-muted text-muted-foreground text-sm\">\n {author ? (\n getInitials(author)\n ) : (\n <CycleIcon icon={User} size=\"sm\" decorative />\n )}\n </AvatarFallback>\n </Avatar>\n </div>\n </div>\n )\n}\n\nexport { ChatMessage, chatMessageVariants }\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogCancel, AlertDialogAction } from './chunk-MQTQIX4N.js';
|
|
2
|
-
import { ChatMessage } from './chunk-
|
|
2
|
+
import { ChatMessage } from './chunk-OE4CHHIW.js';
|
|
3
3
|
import { DEFAULT_MESSAGE_RATING_LABELS, MessageRating } from './chunk-YIOXPV2N.js';
|
|
4
4
|
import { MessageBar } from './chunk-5AH2PNYW.js';
|
|
5
5
|
import { useCountdown, StatusBanner } from './chunk-VMUNB4RA.js';
|
|
@@ -460,5 +460,5 @@ function ChatThread(_a) {
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
export { ChatThread };
|
|
463
|
-
//# sourceMappingURL=chunk-
|
|
464
|
-
//# sourceMappingURL=chunk-
|
|
463
|
+
//# sourceMappingURL=chunk-OZCMOOT7.js.map
|
|
464
|
+
//# sourceMappingURL=chunk-OZCMOOT7.js.map
|