mirror of
https://github.com/StanGirard/quivr.git
synced 2024-11-26 12:55:01 +03:00
feat(frontend): show icons only on hover except for last message (#2377)
# Description Please include a summary of the changes and the related issue. Please also include relevant motivation and context. ## Checklist before requesting a review Please delete options that are not relevant. - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented hard-to-understand areas - [ ] I have ideally added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged ## Screenshots (if appropriate):
This commit is contained in:
parent
c89d596990
commit
1e92e2a1e0
@ -1,14 +1,26 @@
|
||||
import { ChatNotification } from "./ChatNotification/ChatNotification";
|
||||
import { QADisplay } from "./QADisplay";
|
||||
|
||||
import { ChatItemWithGroupedNotifications } from "../../../../types";
|
||||
import { ChatNotification } from "../ChatNotification/ChatNotification";
|
||||
import { QADisplay } from "../QADisplay";
|
||||
|
||||
type ChatItemProps = {
|
||||
content: ChatItemWithGroupedNotifications;
|
||||
index: number;
|
||||
lastMessage?: boolean;
|
||||
};
|
||||
export const ChatItem = ({ content, index }: ChatItemProps): JSX.Element => {
|
||||
export const ChatItem = ({
|
||||
content,
|
||||
index,
|
||||
lastMessage,
|
||||
}: ChatItemProps): JSX.Element => {
|
||||
if (content.item_type === "MESSAGE") {
|
||||
return <QADisplay content={content.body} index={index} />;
|
||||
return (
|
||||
<QADisplay
|
||||
content={content.body}
|
||||
index={index}
|
||||
lastMessage={lastMessage}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <ChatNotification content={content.body} />;
|
||||
|
@ -6,8 +6,13 @@ import "./styles.css";
|
||||
type QADisplayProps = {
|
||||
content: ChatMessage;
|
||||
index: number;
|
||||
lastMessage?: boolean;
|
||||
};
|
||||
export const QADisplay = ({ content, index }: QADisplayProps): JSX.Element => {
|
||||
export const QADisplay = ({
|
||||
content,
|
||||
index,
|
||||
lastMessage,
|
||||
}: QADisplayProps): JSX.Element => {
|
||||
const {
|
||||
assistant,
|
||||
message_id,
|
||||
@ -39,6 +44,7 @@ export const QADisplay = ({ content, index }: QADisplayProps): JSX.Element => {
|
||||
metadata={metadata} // eslint-disable-line @typescript-eslint/no-unsafe-assignment
|
||||
messageId={message_id}
|
||||
thumbs={thumbs}
|
||||
lastMessage={lastMessage}
|
||||
/>
|
||||
</>
|
||||
);
|
@ -51,6 +51,7 @@
|
||||
position: relative;
|
||||
|
||||
.icons_wrapper {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
display: flex;
|
||||
gap: Spacings.$spacing03;
|
||||
@ -60,6 +61,18 @@
|
||||
.sources_icon_wrapper {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.sticky {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.message_row_content {
|
||||
.icons_wrapper {
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@ type MessageRowProps = {
|
||||
index?: number;
|
||||
messageId?: string;
|
||||
thumbs?: boolean;
|
||||
lastMessage?: boolean;
|
||||
};
|
||||
|
||||
export const MessageRow = React.forwardRef(
|
||||
@ -41,6 +42,7 @@ export const MessageRow = React.forwardRef(
|
||||
index,
|
||||
messageId,
|
||||
thumbs: initialThumbs,
|
||||
lastMessage,
|
||||
}: MessageRowProps,
|
||||
ref: React.Ref<HTMLDivElement>
|
||||
) => {
|
||||
@ -101,7 +103,11 @@ export const MessageRow = React.forwardRef(
|
||||
const renderIcons = () => {
|
||||
if (!isUserSpeaker && messageContent !== "🧠") {
|
||||
return (
|
||||
<div className={styles.icons_wrapper}>
|
||||
<div
|
||||
className={`${styles.icons_wrapper} ${
|
||||
lastMessage ? styles.sticky : ""
|
||||
}`}
|
||||
>
|
||||
<CopyButton handleCopy={handleCopy} size="normal" />
|
||||
{!isMobile && (
|
||||
<div className={styles.sources_icon_wrapper}>
|
@ -1,81 +0,0 @@
|
||||
import Link from "next/link";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { RiDownloadLine } from "react-icons/ri";
|
||||
|
||||
import Button from "@/lib/components/ui/Button";
|
||||
import { useOnboardingTracker } from "@/lib/hooks/useOnboardingTracker";
|
||||
import { useStreamText } from "@/lib/hooks/useStreamText";
|
||||
|
||||
import { stepsContainerStyle } from "./styles";
|
||||
|
||||
import { MessageRow } from "../QADisplay";
|
||||
|
||||
export const Onboarding = (): JSX.Element => {
|
||||
const { t } = useTranslation(["chat"]);
|
||||
const title = t("onboarding.title");
|
||||
const step1 = t("onboarding.step_1_1");
|
||||
const step1Details = t("onboarding.step_1_2");
|
||||
const step2 = t("onboarding.step_2");
|
||||
const step3 = t("onboarding.step_3");
|
||||
|
||||
const { trackOnboardingEvent } = useOnboardingTracker();
|
||||
|
||||
const { streamingText: titleStream, isDone: isTitleDisplayed } =
|
||||
useStreamText({
|
||||
text: title,
|
||||
});
|
||||
const { streamingText: firstStepStream, isDone: isStep1Done } = useStreamText(
|
||||
{
|
||||
text: step1,
|
||||
enabled: isTitleDisplayed,
|
||||
}
|
||||
);
|
||||
const { streamingText: firstStepDetailsStream, isDone: isStep1DetailsDone } =
|
||||
useStreamText({
|
||||
text: step1Details,
|
||||
enabled: isStep1Done,
|
||||
});
|
||||
|
||||
const { streamingText: secondStepStream, isDone: isStep2Done } =
|
||||
useStreamText({
|
||||
text: step2,
|
||||
enabled: isStep1DetailsDone,
|
||||
});
|
||||
const { streamingText: thirdStepStream } = useStreamText({
|
||||
text: step3,
|
||||
enabled: isStep2Done,
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2 mb-3">
|
||||
<MessageRow speaker={"assistant"} brainName={"Quivr"}>
|
||||
<div className={stepsContainerStyle}>
|
||||
<p>{titleStream}</p>
|
||||
<div>
|
||||
<p>{firstStepStream}</p>
|
||||
<div>
|
||||
{firstStepDetailsStream}
|
||||
{isStep1DetailsDone && (
|
||||
<Link
|
||||
href="/documents/quivr_documentation.pdf"
|
||||
download
|
||||
target="_blank"
|
||||
referrerPolicy="no-referrer"
|
||||
onClick={() => {
|
||||
trackOnboardingEvent("QUIVR_DOCUMENTATION_DOWNLOADED");
|
||||
}}
|
||||
>
|
||||
<Button className="bg-black p-2 ml-2 rounded-full inline-flex">
|
||||
<RiDownloadLine />
|
||||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<p>{secondStepStream}</p>
|
||||
<p>{thirdStepStream}</p>
|
||||
</div>
|
||||
</MessageRow>
|
||||
</div>
|
||||
);
|
||||
};
|
@ -1 +0,0 @@
|
||||
export const stepsContainerStyle = "flex flex-col gap-2";
|
@ -1,2 +1,2 @@
|
||||
export * from "./ChatItem";
|
||||
export * from "./QADisplay";
|
||||
export * from "./ChatItem/QADisplay";
|
||||
|
@ -3,7 +3,6 @@ import { useTranslation } from "react-i18next";
|
||||
import { useOnboarding } from "@/lib/hooks/useOnboarding";
|
||||
|
||||
import { ChatItem } from "./components";
|
||||
import { Onboarding } from "./components/Onboarding/Onboarding";
|
||||
import { useChatDialogue } from "./hooks/useChatDialogue";
|
||||
import {
|
||||
chatDialogueContainerClassName,
|
||||
@ -28,7 +27,6 @@ export const ChatDialogue = ({
|
||||
if (shouldDisplayOnboardingAInstructions) {
|
||||
return (
|
||||
<div className={chatDialogueContainerClassName} ref={chatListRef}>
|
||||
<Onboarding />
|
||||
<div className={chatItemContainerClassName}>
|
||||
{chatItems.map((chatItem, index) => (
|
||||
<ChatItem
|
||||
@ -58,6 +56,7 @@ export const ChatDialogue = ({
|
||||
key={getKeyFromChatItem(chatItem)}
|
||||
content={chatItem}
|
||||
index={index}
|
||||
lastMessage={index === chatItems.length - 1}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
Loading…
Reference in New Issue
Block a user