Skip to content

Commit 3134d91

Browse files
authored
Merge pull request #246 from n4ze3m/next
v1.7.9
2 parents a366c77 + 0042131 commit 3134d91

32 files changed

+675
-139
lines changed

app/ui/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "app",
33
"private": true,
4-
"version": "1.7.8",
4+
"version": "1.7.9",
55
"type": "module",
66
"scripts": {
77
"dev": "vite",

app/ui/src/components/Bot/Appearance/AppearanceForm.tsx

+74-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
1-
import { Divider, Form, FormInstance, Input, notification } from "antd";
1+
import {
2+
Divider,
3+
Form,
4+
FormInstance,
5+
Input,
6+
Select,
7+
Switch,
8+
notification,
9+
} from "antd";
210
import { AppearanceType } from "./types";
311
import { DbColorPicker } from "../../Common/DbColorPicker";
412
import { useMutation, useQueryClient } from "@tanstack/react-query";
@@ -16,7 +24,8 @@ export const AppearanceForm = ({
1624
}) => {
1725
const botBubbleStyle = Form.useWatch("chat_bot_bubble_style", form);
1826
const humanBubbleStyle = Form.useWatch("chat_human_bubble_style", form);
19-
27+
const isTTS = Form.useWatch("tts", form);
28+
const ttsProvider = Form.useWatch("tts_provider", form);
2029
const params = useParams<{ id: string }>();
2130

2231
const onFinish = async (values: any) => {
@@ -218,6 +227,69 @@ export const AppearanceForm = ({
218227
</div>
219228
</Form.Item>
220229

230+
<Divider orientation="left">Text to Speech (TTS) Settings</Divider>
231+
232+
<Form.Item label="Enable TTS" name="tts" valuePropName="checked">
233+
<Switch />
234+
</Form.Item>
235+
236+
{isTTS && (
237+
<>
238+
<Form.Item
239+
rules={[
240+
{
241+
required: true,
242+
message: "Please select a voice provider!",
243+
},
244+
]}
245+
label="TTS Provider"
246+
name="tts_provider"
247+
>
248+
<Select
249+
placeholder="Select a TTS provider"
250+
options={[
251+
{
252+
label: "Eleven Labs",
253+
value: "eleven_labs",
254+
},
255+
{
256+
label: "OpenAI",
257+
value: "openai",
258+
},
259+
]}
260+
/>
261+
</Form.Item>
262+
{ttsProvider === "openai" && (
263+
<Form.Item
264+
name="tts_model"
265+
label="TTS Model"
266+
rules={[
267+
{
268+
required: true,
269+
message: "Please select a TTS model!",
270+
},
271+
]}
272+
>
273+
<Select
274+
placeholder="Select a TTS model"
275+
options={initialData.tts_data.openai.models}
276+
/>
277+
</Form.Item>
278+
)}
279+
280+
<Form.Item name="tts_voice" label="TTS Voice">
281+
<Select
282+
placeholder="Select a TTS voice"
283+
options={
284+
ttsProvider === "eleven_labs"
285+
? initialData.tts_data.eleven_labs.voices
286+
: initialData.tts_data.openai.voices
287+
}
288+
/>
289+
</Form.Item>
290+
</>
291+
)}
292+
221293
<div className="mt-3 text-right">
222294
<button
223295
type="submit"

app/ui/src/components/Bot/Appearance/AppearancePreview.tsx

+11
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
import { PlayIcon } from "@heroicons/react/24/outline";
12
import { FormInstance, Form } from "antd";
23

34
export const AppearancePreview = ({ form }: { form: FormInstance }) => {
45
const botBubbleStyle = Form.useWatch("chat_bot_bubble_style", form);
56
const humanBubbleStyle = Form.useWatch("chat_human_bubble_style", form);
67
const botName = Form.useWatch("bot_name", form);
78
const firstMessage = Form.useWatch("first_message", form);
9+
10+
const isTTS = Form.useWatch("tts", form);
11+
812
return (
913
<div
1014
style={{
@@ -75,6 +79,13 @@ export const AppearancePreview = ({ form }: { form: FormInstance }) => {
7579
}}
7680
>
7781
<p className="text-sm">{firstMessage}</p>
82+
{isTTS && (
83+
<div className=" mt-3">
84+
<button className="flex bg-white shadow-md items-center border justify-center w-6 h-6 rounded-full transition-colors duration-200">
85+
<PlayIcon className="w-3 h-3" />
86+
</button>
87+
</div>
88+
)}
7889
</div>
7990
</div>
8091

+40-15
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,41 @@
11
export interface AppearanceType {
2-
public_id: string;
3-
data: {
4-
background_color?: string;
5-
bot_name: string;
6-
chat_bot_bubble_style?: {
7-
background_color?: string;
8-
text_color?: string;
9-
};
10-
chat_human_bubble_style?: {
11-
background_color?: string;
12-
text_color?: string;
13-
};
14-
first_message: string;
15-
}
16-
}
2+
public_id: string;
3+
data: {
4+
background_color?: string;
5+
bot_name: string;
6+
chat_bot_bubble_style?: {
7+
background_color?: string;
8+
text_color?: string;
9+
};
10+
chat_human_bubble_style?: {
11+
background_color?: string;
12+
text_color?: string;
13+
};
14+
first_message: string;
15+
tts: boolean;
16+
tts_voice: string | null;
17+
tts_provider: string | null;
18+
};
19+
tts_data: {
20+
eleven_labs: {
21+
models: {
22+
label: string;
23+
value: string;
24+
}[];
25+
voices: {
26+
label: string;
27+
value: string;
28+
}[];
29+
};
30+
openai: {
31+
models: {
32+
label: string;
33+
value: string;
34+
}[];
35+
voices: {
36+
label: string;
37+
value: string;
38+
}[];
39+
};
40+
};
41+
}

app/ui/src/components/Bot/Playground/Message.tsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,12 @@ export const PlaygroundMessage = (props: Props) => {
108108
cancel();
109109
}
110110
}}
111-
className="flex items-center justify-center w-6 h-6 rounded-full bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"
111+
className="flex items-center justify-center w-8 h-8 rounded-full bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"
112112
>
113113
{!isWebSpeaking ? (
114-
<PlayIcon className="w-3 h-3 text-gray-400 group-hover:text-gray-500" />
114+
<PlayIcon className="w-4 h-4 text-gray-400 group-hover:text-gray-500" />
115115
) : (
116-
<StopIcon className="w-3 h-3 text-red-400 group-hover:text-red-500" />
116+
<StopIcon className="w-4 h-4 text-red-400 group-hover:text-red-500" />
117117
)}
118118
</button>
119119
)}
@@ -131,13 +131,13 @@ export const PlaygroundMessage = (props: Props) => {
131131
cancelElevenLabs();
132132
}
133133
}}
134-
className="flex items-center justify-center w-6 h-6 rounded-full bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"
134+
className="flex items-center justify-center w-8 h-8 rounded-full bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"
135135
>
136136
{!isElevenLabsLoading ? (
137137
!isElevenLabsPlaying ? (
138-
<PlayIcon className="w-3 h-3 text-gray-400 group-hover:text-gray-500" />
138+
<PlayIcon className="w-4 h-4 text-gray-400 group-hover:text-gray-500" />
139139
) : (
140-
<StopIcon className="w-3 h-3 text-red-400 group-hover:text-red-500" />
140+
<StopIcon className="w-4 h-4 text-red-400 group-hover:text-red-500" />
141141
)
142142
) : (
143143
<svg

app/ui/src/routes/bot/appearance.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ export default function BotAppearanceRoot() {
1717
},
1818
{
1919
enabled: !!param.id,
20-
refetchInterval: 1000,
2120
}
2221
);
2322

app/widget/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"preview": "vite preview"
1111
},
1212
"dependencies": {
13+
"@heroicons/react": "^2.0.18",
1314
"@mantine/form": "^6.0.13",
1415
"@tailwindcss/forms": "^0.5.3",
1516
"@tanstack/react-query": "^4.29.12",

app/widget/src/App.tsx

+6-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,12 @@ function App() {
5050
} else {
5151
setMessages([
5252
...messages,
53-
{ isBot: true, message: botStyle.data.first_message, sources: [] },
53+
{
54+
isBot: true,
55+
message: botStyle.data.first_message,
56+
sources: [],
57+
id: "first-message",
58+
},
5459
]);
5560
}
5661
}

app/widget/src/components/BotChatBubble.tsx

+48
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1+
import { PlayIcon, StopIcon } from "@heroicons/react/20/solid";
12
import { Message } from "../store";
23
import { BotStyle } from "../utils/types";
34
import BotSource from "./BotSource";
45
import Markdown from "./Markdown";
6+
import { useVoice } from "../hooks/useVoice";
57

68
export default function BotChatBubble({
79
message,
@@ -10,6 +12,7 @@ export default function BotChatBubble({
1012
message: Message;
1113
botStyle: BotStyle;
1214
}) {
15+
const { cancel, isPlaying, loading, speak } = useVoice();
1316
return (
1417
<div className="mt-2 flex flex-col">
1518
<div
@@ -38,6 +41,51 @@ export default function BotChatBubble({
3841
<p className="text-sm">
3942
<Markdown message={message.message} />
4043
</p>
44+
{botStyle.data.tts && message.isBot && message.id !== "temp-id" && (
45+
<div className=" mt-3">
46+
<button
47+
onClick={() => {
48+
if (!isPlaying) {
49+
speak({
50+
id: message.id,
51+
});
52+
} else {
53+
cancel();
54+
}
55+
}}
56+
className="flex bg-white shadow-md items-center border justify-center w-6 h-6 rounded-full transition-colors duration-200"
57+
>
58+
{!loading ? (
59+
!isPlaying ? (
60+
<PlayIcon className="w-4 h-4 text-gray-400 group-hover:text-gray-500" />
61+
) : (
62+
<StopIcon className="w-4 h-4 text-red-400 group-hover:text-red-500" />
63+
)
64+
) : (
65+
<svg
66+
className="animate-spin h-5 w-5 text-gray-400 group-hover:text-gray-500"
67+
xmlns="http://www.w3.org/2000/svg"
68+
fill="none"
69+
viewBox="0 0 24 24"
70+
>
71+
<circle
72+
className="opacity-25"
73+
cx="12"
74+
cy="12"
75+
r="10"
76+
stroke="currentColor"
77+
strokeWidth="4"
78+
></circle>
79+
<path
80+
className="opacity-75"
81+
fill="currentColor"
82+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
83+
></path>
84+
</svg>
85+
)}
86+
</button>
87+
</div>
88+
)}
4189
</div>
4290
<div className="flex flex-wrap items-start justify-start space-x-3">
4391
{botStyle.data.show_reference &&

app/widget/src/components/BotHeader.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export default function BotHeader({
2626
setMessages([
2727
{
2828
message: botStyle?.data?.first_message,
29+
id: "first-message",
2930
isBot: true,
3031
sources: [],
3132
},

0 commit comments

Comments
 (0)