Skip to content

Commit

Permalink
Merge pull request #300 from priyanshuverma-dev/feat-read-aloud-switch
Browse files Browse the repository at this point in the history
feat: Adds Read Aloud Switch in chatbot and Settings
  • Loading branch information
kom-senapati authored Nov 10, 2024
2 parents e38709a + faa4463 commit ccda7a1
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 50 deletions.
Binary file modified client/bun.lockb
Binary file not shown.
11 changes: 11 additions & 0 deletions client/src/components/modals/settings-modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { Save } from "lucide-react";
import { useState } from "react";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";
import { Switch } from "../ui/switch";

const chatbotEngines = ["openai", "groq", "anthropic", "gemini"];

Expand All @@ -34,6 +35,8 @@ export default function SettingsModal() {
setConfigurations,
currentConfig,
setCurrentConfig,
readAloudEnabled,
updateReadAloud,
} = useSettings();
const { t } = useTranslation();
const [apiKey, setApiKey] = useState(
Expand Down Expand Up @@ -100,6 +103,14 @@ export default function SettingsModal() {
<div className="flex items-center justify-between">
<ToggleButton />
</div>
<div className="flex items-center justify-between">
<Label htmlFor="voice-mode">Global Read Aloud</Label>
<Switch
id="voice-mode"
checked={readAloudEnabled}
onCheckedChange={(b) => updateReadAloud(b)}
/>
</div>

<div className="flex flex-col space-y-4">
<Label className="text-center">
Expand Down
23 changes: 23 additions & 0 deletions client/src/contexts/settings-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ interface SettingsContextProps {
setConfigurations: (configs: EngineConfig[]) => void;
currentConfig: EngineConfig | null;
setCurrentConfig: (config: EngineConfig | null) => void;
updateReadAloud: (s: boolean) => void;
readAloudEnabled: boolean;
// Add more settings as needed
}

Expand All @@ -29,13 +31,16 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = ({

const [configurations, setConfigurations] = useState<EngineConfig[]>([]);
const [currentConfig, setCurrentConfig] = useState<EngineConfig | null>(null);
const [readAloudEnabled, setReadAloudEnabled] = useState<boolean>(false);

useEffect(() => {
const savedFontSize = localStorage.getItem("fontSize") as
| "small"
| "medium"
| "large";

const savedRealAloudStatus = localStorage.getItem("enableReadAloud");

const savedConfigs = localStorage.getItem("configurations");
if (savedConfigs) {
try {
Expand All @@ -54,13 +59,29 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = ({
}

if (savedFontSize) setFontSize(savedFontSize);
if (savedRealAloudStatus) {
if (savedRealAloudStatus == "1") {
setReadAloudEnabled(true);
} else {
setReadAloudEnabled(false);
}
}
}, []);

const updateFontSize = (size: "small" | "medium" | "large") => {
setFontSize(size);
localStorage.setItem("fontSize", size);
};

const updateReadAloud = (s: boolean) => {
setReadAloudEnabled(s);
if (s == true) {
localStorage.setItem("enableReadAloud", "1");
} else {
localStorage.setItem("enableReadAloud", "0");
}
};

const saveConfigurations = (configs: EngineConfig[]) => {
setConfigurations(configs);
localStorage.setItem("configurations", JSON.stringify(configs));
Expand All @@ -85,6 +106,8 @@ export const SettingsProvider: React.FC<{ children: React.ReactNode }> = ({
setConfigurations: saveConfigurations,
currentConfig,
setCurrentConfig,
readAloudEnabled,
updateReadAloud,
}}
>
<ThemeProvider enableSystem={false} themes={themes}>
Expand Down
114 changes: 64 additions & 50 deletions client/src/pages/Chatbot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ import EmojiPicker from "emoji-picker-react";
import exportFromJSON, { ExportType } from "export-from-json";
import { useTranslation } from "react-i18next";
import transition from "@/components/transition";
import { Switch } from "@/components/ui/switch";
import { Label } from "@/components/ui/label";

function ChatbotPage() {
const { id } = useParams();
Expand All @@ -67,7 +69,9 @@ function ChatbotPage() {
const ttsMagicModal = useTtsMagicModal();
const ttHMagicModal = usettHMagic();
const translateMagicModal = useTranslateMagicModal();
const { currentConfig } = useSettings();
const { currentConfig, readAloudEnabled } = useSettings();
const [localreadAloudState, setLocalreadAloudState] =
useState<boolean>(readAloudEnabled);
const [loading, setLoading] = useState(false);
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
const rq = useQueryClient();
Expand Down Expand Up @@ -134,7 +138,9 @@ function ChatbotPage() {
if (response.data?.success) {
form.reset();
rq.invalidateQueries({ queryKey: ["chatbot", id] });
speak(response.data.response);
if (localreadAloudState) {
speak(response.data.response);
}
} else {
throw new Error(response.data?.message || "failed. Please try again.");
}
Expand Down Expand Up @@ -226,54 +232,62 @@ function ChatbotPage() {
</Link>
)}
</div>
<DropdownMenu>
<DropdownMenuTrigger>
<Menu />
</DropdownMenuTrigger>
<DropdownMenuContent className="mr-8">
<DropdownMenuItem onClick={() => settingsModal.onOpen()}>
{t("navbar.settings")}
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
{t("chatbot_page.export")}
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem
onClick={() => handleExport(exportFromJSON.types.csv)}
>
CSV
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleExport(exportFromJSON.types.json)}
>
JSON
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleExport(exportFromJSON.types.html)}
>
HTML
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleExport(exportFromJSON.types.xml)}
>
XML
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem
className="text-destructive hover:text-destructive/90"
onClick={() => {
mutation.mutate(id);
}}
>
{t("clear")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
<div className="flex items-center space-x-2">
<Label htmlFor="voice-mode">Read Aloud</Label>
<Switch
id="voice-mode"
checked={localreadAloudState}
onCheckedChange={(b) => setLocalreadAloudState(b)}
/>
<DropdownMenu>
<DropdownMenuTrigger>
<Menu />
</DropdownMenuTrigger>
<DropdownMenuContent className="mr-8">
<DropdownMenuItem onClick={() => settingsModal.onOpen()}>
{t("navbar.settings")}
</DropdownMenuItem>
<DropdownMenuSub>
<DropdownMenuSubTrigger>
{t("chatbot_page.export")}
</DropdownMenuSubTrigger>
<DropdownMenuPortal>
<DropdownMenuSubContent>
<DropdownMenuItem
onClick={() => handleExport(exportFromJSON.types.csv)}
>
CSV
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleExport(exportFromJSON.types.json)}
>
JSON
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleExport(exportFromJSON.types.html)}
>
HTML
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleExport(exportFromJSON.types.xml)}
>
XML
</DropdownMenuItem>
</DropdownMenuSubContent>
</DropdownMenuPortal>
</DropdownMenuSub>
<DropdownMenuSeparator />
<DropdownMenuItem
className="text-destructive hover:text-destructive/90"
onClick={() => {
mutation.mutate(id);
}}
>
{t("clear")}
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
<Separator className="my-0" />

Expand Down

0 comments on commit ccda7a1

Please sign in to comment.