Skip to content

Commit

Permalink
Touchpoint QA round 1 (#173)
Browse files Browse the repository at this point in the history
* Fine-tune touchpoint animation

* Add image upload handling

* Styling updates

* Fix responsive layout

* Remove scroll test

* Set up easing for loader movement
  • Loading branch information
peterszerzo authored Jan 8, 2025
1 parent ddebbc8 commit debf0b2
Show file tree
Hide file tree
Showing 11 changed files with 403 additions and 252 deletions.
104 changes: 61 additions & 43 deletions packages/touchpoint-ui/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,21 @@ import {
type Response,
type Config,
type BotResponse,
type BotMessage,
} from "@nlxai/chat-core";
import { clsx } from "clsx";
import { findLastIndex } from "ramda";

import { LaunchButton } from "./components/ui/LaunchButton";
import ChatHeader from "./components/ChatHeader";
import { ChatHeader } from "./components/ChatHeader";
import { ChatSettings } from "./components/ChatSettings";
import { MessageChoices, ChatMessages } from "./components/ChatMessages";
import { ChatMessages } from "./components/ChatMessages";
import ChatInput from "./components/ChatInput";
import { type ColorMode, type WindowSize, type LogoUrl } from "./types";
import {
type ColorMode,
type WindowSize,
type LogoUrl,
type ChoiceMessage,
} from "./types";
import { Context } from "./context";

export interface Props {
Expand Down Expand Up @@ -61,7 +65,7 @@ const App = forwardRef<AppRef, Props>((props, ref) => {

const [isExpanded, setIsExpanded] = useState(isDev);

const [settingsOpen, setSettingsOpen] = useState<boolean>(false);
const [isSettingsOpen, setIsSettingsOpen] = useState<boolean>(false);

const expand = useCallback(() => {
setIsExpanded(true);
Expand Down Expand Up @@ -130,24 +134,20 @@ const App = forwardRef<AppRef, Props>((props, ref) => {
return { index, response };
}, [responses]);

const choiceMessage = useMemo<{
message: BotMessage;
responseIndex: number;
messageIndex: number;
} | null>(() => {
const choiceMessage = useMemo<ChoiceMessage | undefined>(() => {
if (lastBotResponse == null) {
return null;
return;
}
const choiceMessageIndex = findLastIndex((message) => {
return message.choices.length > 0;
}, lastBotResponse.response.payload.messages);
if (choiceMessageIndex === -1) {
return null;
return;
}
const choiceMessage =
lastBotResponse.response.payload.messages[choiceMessageIndex];
if (choiceMessage == null) {
return null;
return;
}
return {
message: choiceMessage,
Expand All @@ -156,33 +156,56 @@ const App = forwardRef<AppRef, Props>((props, ref) => {
};
}, [lastBotResponse]);

const [uploadedFiles, setUploadedFiles] = useState<Record<string, File>>({});

if (handler == null) {
return null;
}

return (
<Context.Provider value={{ colorMode, windowSize, handler }}>
<Context.Provider value={{ handler }}>
{isExpanded ? (
<div
data-theme={colorMode}
className="grid grid-cols-2 fixed inset-0 z-touchpoint"
className="grid grid-cols-2 xl:grid-cols-[1fr_632px] fixed inset-0 z-touchpoint font-sans"
>
{windowSize === "half" ? (
<div className="hidden md:block bg-overlay" />
<div className="hidden md:block bg-overlay"></div>
) : null}
<div
className={clsx(
"w-full bg-background text-primary-80 flex relative flex-col backdrop-blur",
"w-full bg-background text-primary-80 flex relative flex-col h-full backdrop-blur-overlay",
{
"col-span-2 md:col-span-1 h-full": windowSize === "half",
"col-span-2 md:col-span-1": windowSize === "half",
"col-span-2": windowSize === "full",
},
)}
>
{settingsOpen ? (
<ChatHeader
windowSize={windowSize}
colorMode={colorMode}
logoUrl={props.logoUrl}
isSettingsOpen={isSettingsOpen}
toggleSettings={() => {
setIsSettingsOpen((prev) => !prev);
}}
collapse={() => {
setIsExpanded(false);
}}
reset={() => {
handler.reset({ clearResponses: true });
handler.sendWelcomeIntent();
}}
/>
{isSettingsOpen ? (
<ChatSettings
className={
windowSize === "full"
? "w-full md:max-w-content md:mx-auto"
: ""
}
onClose={() => {
setSettingsOpen(false);
setIsSettingsOpen(false);
}}
colorMode={colorMode}
windowSize={windowSize}
Expand All @@ -192,42 +215,37 @@ const App = forwardRef<AppRef, Props>((props, ref) => {
/>
) : (
<>
<ChatHeader
windowSize={windowSize}
colorMode={colorMode}
logoUrl={props.logoUrl}
openSettings={() => {
setSettingsOpen(true);
}}
collapse={() => {
setIsExpanded(false);
}}
reset={() => {
handler.reset({ clearResponses: true });
handler.sendWelcomeIntent();
}}
/>
<ChatMessages responses={responses} handler={handler} />
{choiceMessage != null ? (
<MessageChoices {...choiceMessage} handler={handler} />
) : null}
<ChatInput
<ChatMessages
responses={responses}
handler={handler}
uploadedFiles={uploadedFiles}
className={
choiceMessage?.message.selectedChoiceId != null
? "hidden"
windowSize === "full"
? "w-full md:max-w-content md:mx-auto"
: ""
}
/>
<ChatInput
className={clsx(
windowSize === "full"
? "w-full md:max-w-content md:mx-auto"
: "",
)}
choiceMessage={choiceMessage}
handler={handler}
uploadUrl={
lastBotResponse?.response.payload.metadata?.uploadUrls?.[0]
}
onFileUpload={({ uploadId, file }) => {
setUploadedFiles((prev) => ({ ...prev, [uploadId]: file }));
}}
/>
</>
)}
</div>
</div>
) : (
<div data-theme={colorMode}>
<div data-theme={colorMode} className="font-sans">
<LaunchButton
className="fixed z-100 bottom-2 right-2 backdrop-blur z-launchButton"
onClick={() => {
Expand Down
23 changes: 12 additions & 11 deletions packages/touchpoint-ui/src/components/ChatHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@ interface ChatHeaderProps {
logoUrl?: LogoUrl;
collapse: () => void;
reset: () => void;
openSettings?: () => void;
toggleSettings?: () => void;
isSettingsOpen: boolean;
}

export const ChatHeader: FC<ChatHeaderProps> = ({
windowSize,
colorMode,
collapse,
logoUrl,
openSettings,
toggleSettings,
isSettingsOpen,
reset,
}) => {
const isHalf = windowSize === "half";
Expand All @@ -31,7 +33,7 @@ export const ChatHeader: FC<ChatHeaderProps> = ({
<div
className={clsx(
"flex",
"p-2 items-center justify-between gap-2",
"p-2 md:p-3 items-center justify-between gap-2",
isHalf
? "md:absolute md:w-fit md:flex-col md:left-0 md:-translate-x-full"
: "md:absolute md:left-0 md:right-0 md:top-0",
Expand All @@ -52,21 +54,22 @@ export const ChatHeader: FC<ChatHeaderProps> = ({
}}
Icon={Undo}
/>
{openSettings != null ? (
{toggleSettings != null ? (
<IconButton
className={logoUrl != null ? "" : "ml-auto"}
Icon={Settings}
label="Settings"
type={iconButtonType}
onClick={() => {
openSettings();
}}
type={isSettingsOpen ? "activated" : iconButtonType}
onClick={toggleSettings}
/>
) : null}
<IconButton
label="Collapse"
type={iconButtonType}
className={openSettings == null ? "ml-auto" : ""}
className={clsx(
toggleSettings == null ? "ml-auto" : "",
isHalf ? "md:-order-1" : "",
)}
onClick={() => {
collapse();
}}
Expand All @@ -75,5 +78,3 @@ export const ChatHeader: FC<ChatHeaderProps> = ({
</div>
);
};

export default ChatHeader;
Loading

0 comments on commit debf0b2

Please sign in to comment.