Skip to content

Commit

Permalink
feat: Add support for plugins and fix event emissions affecting states
Browse files Browse the repository at this point in the history
  • Loading branch information
tjtanjin committed Sep 13, 2024
1 parent ddad30f commit 5c969fc
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 93 deletions.
16 changes: 9 additions & 7 deletions src/components/ChatBot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ const ChatBot = ({
settings,
styles,
themes,
plugins
}: {
id?: string,
flow?: Flow,
settings?: Settings
styles?: Styles,
themes?: undefined | Theme | Array<Theme>,
id?: string;
flow?: Flow;
settings?: Settings;
styles?: Styles;
themes?: undefined | Theme | Array<Theme>;
plugins?: Array<(...args: unknown[]) => unknown>;
}) => {

// checks if the ChatBot is inside a provider
Expand All @@ -35,11 +37,11 @@ const ChatBot = ({
*/
const renderChatBot = () => {
if (isInsideProvider) {
return (<ChatBotContainer />);
return (<ChatBotContainer plugins={plugins} />);
}
return (
<ChatBotProvider id={id} flow={flow} settings={settings} styles={styles} themes={themes}>
<ChatBotContainer />
<ChatBotContainer plugins={plugins} />
</ChatBotProvider>
)
}
Expand Down
12 changes: 10 additions & 2 deletions src/components/ChatBotContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,17 @@ import { useStylesContext } from "../context/StylesContext";
import "./ChatBotContainer.css";

/**
* Integrates and contains the various components that makeup the chatbot.
* Integrates, loads plugins and contains the various components that makeup the chatbot.
*/
const ChatBotContainer = () => {
const ChatBotContainer = ({
plugins
}: {
plugins?: Array<(...args: unknown[]) => unknown>;
}) => {

// loads plugins
plugins?.map((plugin) => plugin());

// handles settings
const { settings } = useSettingsContext();

Expand Down
20 changes: 10 additions & 10 deletions src/hooks/internal/useChatWindowInternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ export const useChatWindowInternal = () => {
* Toggles chat window.
*/
const toggleChatWindow = useCallback(() => {
setIsChatWindowOpen(prev => {
// handles toggle chat window event
if (settings.event?.rcbToggleChatWindow) {
const event = callRcbEvent(RcbEvent.TOGGLE_CHAT_WINDOW, {currState: prev, newState: !prev});
if (event.defaultPrevented) {
return prev;
}
// handles toggle chat window event
if (settings.event?.rcbToggleChatWindow) {
const event = callRcbEvent(
RcbEvent.TOGGLE_CHAT_WINDOW,
{currState: isChatWindowOpen, newState: !isChatWindowOpen}
);
if (event.defaultPrevented) {
return;
}

return !prev
});
}
setIsChatWindowOpen(prev => !prev);
}, []);

/**
Expand Down
6 changes: 1 addition & 5 deletions src/hooks/internal/useMessagesInternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { useSettingsContext } from "../../context/SettingsContext";
import { useMessagesContext } from "../../context/MessagesContext";
import { useBotStatesContext } from "../../context/BotStatesContext";
import { useBotRefsContext } from "../../context/BotRefsContext";
import { usePathsContext } from "../../context/PathsContext";
import { Message } from "../../types/Message";
import { RcbEvent } from "../../constants/RcbEvent";

Expand All @@ -23,9 +22,6 @@ export const useMessagesInternal = () => {
// handles messages
const { messages, setMessages } = useMessagesContext();

// handles paths
const { paths } = usePathsContext();

// handles bot states
const { audioToggledOn, isChatWindowOpen, setIsBotTyping, setUnreadCount } = useBotStatesContext();

Expand Down Expand Up @@ -80,7 +76,7 @@ export const useMessagesInternal = () => {
}

return message.id;
}, [settings, paths, audioToggledOn, callRcbEvent]);
}, [settings, audioToggledOn, callRcbEvent]);

/**
* Removes a message with the given id.
Expand Down
20 changes: 10 additions & 10 deletions src/hooks/internal/useNotificationsInternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,17 @@ export const useNotificationInternal = () => {
* Handles toggling of notification feature.
*/
const toggleNotifications = useCallback(() => {
setNotificationsToggledOn((prev) => {
// handles toggle notifications event
if (settings.event?.rcbToggleNotifications) {
const event = callRcbEvent(RcbEvent.TOGGLE_NOTIFICATIONS, {currState: prev, newState: !prev});
if (event.defaultPrevented) {
return prev;
}
// handles toggle notifications event
if (settings.event?.rcbToggleNotifications) {
const event = callRcbEvent(
RcbEvent.TOGGLE_NOTIFICATIONS,
{currState: notificationsToggledOn, newState: !notificationsToggledOn}
);
if (event.defaultPrevented) {
return;
}

return !prev
});
}
setNotificationsToggledOn(prev => !prev);
}, []);

return {
Expand Down
17 changes: 7 additions & 10 deletions src/hooks/internal/useVoiceInternal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,14 @@ export const useVoiceInternal = () => {
* Toggles voice feature.
*/
const toggleVoice = useCallback(() => {
setVoiceToggledOn((prev) => {
// handles toggle voice event
if (settings.event?.rcbToggleVoice) {
const event = callRcbEvent(RcbEvent.TOGGLE_VOICE, {currState: prev, newState: !prev});
if (event.defaultPrevented) {
return prev;
}
// handles toggle voice event
if (settings.event?.rcbToggleVoice) {
const event = callRcbEvent(RcbEvent.TOGGLE_VOICE, {currState: voiceToggledOn, newState: !voiceToggledOn});
if (event.defaultPrevented) {
return;
}

return !prev
});
}
setVoiceToggledOn(prev => !prev);
}, []);

/**
Expand Down
17 changes: 7 additions & 10 deletions src/hooks/useAudio.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,14 @@ export const useAudio = () => {
* Toggles audio feature.
*/
const toggleAudio = useCallback(() => {
setAudioToggledOn(prev => {
// handles toggle audio event
if (settings.event?.rcbToggleAudio) {
const event = callRcbEvent(RcbEvent.TOGGLE_AUDIO, {currState: prev, newState: !prev});
if (event.defaultPrevented) {
return prev;
}
// handles toggle audio event
if (settings.event?.rcbToggleAudio) {
const event = callRcbEvent(RcbEvent.TOGGLE_AUDIO, {currState: audioToggledOn, newState: !audioToggledOn});
if (event.defaultPrevented) {
return;
}

return !prev
});
}
setAudioToggledOn(prev => !prev);
}, []);

return {
Expand Down
74 changes: 35 additions & 39 deletions src/hooks/useToast.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,40 +27,36 @@ export const useToast = () => {
*/
const showToast = useCallback((content: string | JSX.Element, timeout?: number): string | null => {
let id = null;
setToasts((prevToasts: Toast[]) => {
if (prevToasts.length >= (settings.toast?.maxCount || 3)) {
if (settings.toast?.forbidOnMax) {
return prevToasts;
}
id = crypto.randomUUID();
let toast = { id, content, timeout };

// handles show toast event
if (settings.event?.rcbShowToast) {
const event = callRcbEvent(RcbEvent.SHOW_TOAST, { toast });
if (event.defaultPrevented) {
return prevToasts;
}
toast = event.data.toast;
}

return [...prevToasts.slice(1), toast];
if (toasts.length >= (settings.toast?.maxCount || 3)) {
if (settings.toast?.forbidOnMax) {
return null;
}

id = crypto.randomUUID();
let toast = { id, content, timeout };

// handles show toast event
if (settings.event?.rcbShowToast) {
const event = callRcbEvent(RcbEvent.SHOW_TOAST, { toast });
if (event.defaultPrevented) {
return prevToasts;
return null;
}
toast = event.data.toast;
}
setToasts(prevToasts => [...prevToasts.slice(1), toast]);
}
id = crypto.randomUUID();
let toast = { id, content, timeout };

// handles show toast event
if (settings.event?.rcbShowToast) {
const event = callRcbEvent(RcbEvent.SHOW_TOAST, { toast });
if (event.defaultPrevented) {
return null;
}
toast = event.data.toast;
}

return [...prevToasts, toast];
});
setToasts(prevToasts => [...prevToasts, toast]);
return id;
}, [settings, callRcbEvent]);

Expand All @@ -70,24 +66,24 @@ export const useToast = () => {
* @param id id of toast to remove
*/
const dismissToast = useCallback((id: string): void => {
setToasts((prevToasts) => {
const toastToRemove = prevToasts.find((toast) => toast.id === id);
if (!toastToRemove) {
return prevToasts;
}

// handles dismiss toast event
if (settings.event?.rcbDismissToast) {
const event = callRcbEvent(RcbEvent.DISMISS_TOAST, { toast: toastToRemove });
// if prevented, don't dismiss
if (event.defaultPrevented) {
return prevToasts;
}
const toastToRemove = toasts.find((toast) => toast.id === id);

// if cannot find toast, nothing to remove
if (!toastToRemove) {
return;
}

// handles dismiss toast event
if (settings.event?.rcbDismissToast) {
const event = callRcbEvent(RcbEvent.DISMISS_TOAST, { toast: toastToRemove });
// if prevented, don't dismiss
if (event.defaultPrevented) {
return;
}

// dismiss toast
return prevToasts.filter((toast) => toast.id !== id);
});
}

// dismiss toast
setToasts((prevToasts) => prevToasts.filter((toast) => toast.id !== id));
}, []);

return {
Expand Down

0 comments on commit 5c969fc

Please sign in to comment.