(fix): mount only when open

This commit is contained in:
ManishMadan2882
2024-11-15 06:25:24 +05:30
parent 811a20f080
commit 7bd0351ee9
3 changed files with 139 additions and 134 deletions

View File

@@ -4860,9 +4860,9 @@
} }
}, },
"node_modules/caniuse-lite": { "node_modules/caniuse-lite": {
"version": "1.0.30001625", "version": "1.0.30001680",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001625.tgz", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001680.tgz",
"integrity": "sha512-4KE9N2gcRH+HQhpeiRZXd+1niLB/XNLAhSy4z7fI8EzcbcPoAqjNInxVHTiTwWfTIV4w096XG8OtCOCQQKPv3w==", "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==",
"funding": [ "funding": [
{ {
"type": "opencollective", "type": "opencollective",
@@ -4876,7 +4876,8 @@
"type": "github", "type": "github",
"url": "https://github.com/sponsors/ai" "url": "https://github.com/sponsors/ai"
} }
] ],
"license": "CC-BY-4.0"
}, },
"node_modules/chalk": { "node_modules/chalk": {
"version": "2.4.2", "version": "2.4.2",

View File

@@ -65,8 +65,11 @@ const WidgetContainer = styled.div<{ modal?: boolean, isOpen?: boolean }>`
position: fixed; position: fixed;
right: ${props => props.modal ? '50%' : '10px'}; right: ${props => props.modal ? '50%' : '10px'};
bottom: ${props => props.modal ? '50%' : '10px'}; bottom: ${props => props.modal ? '50%' : '10px'};
z-index: 1000; z-index: 1001;
transform-origin:100% 100%; transform-origin:100% 100%;
&.modal{
transform : translate(50%,50%);
}
&.open { &.open {
animation: createBox 250ms cubic-bezier(0.25, 0.1, 0.25, 1) forwards; animation: createBox 250ms cubic-bezier(0.25, 0.1, 0.25, 1) forwards;
display: block; display: block;
@@ -75,9 +78,6 @@ const WidgetContainer = styled.div<{ modal?: boolean, isOpen?: boolean }>`
animation: closeBox 250ms cubic-bezier(0.25, 0.1, 0.25, 1) forwards; animation: closeBox 250ms cubic-bezier(0.25, 0.1, 0.25, 1) forwards;
display: none; display: none;
} }
${props => props.modal &&
"transform : translate(50%,50%);"
}
align-items: center; align-items: center;
text-align: left; text-align: left;
@keyframes createBox { @keyframes createBox {
@@ -539,7 +539,9 @@ export const WidgetCore = ({
prefilledQuery = "", prefilledQuery = "",
handleClose handleClose
}: WidgetCoreProps) => { }: WidgetCoreProps) => {
const [prompt, setPrompt] = React.useState(prefilledQuery); const [prompt, setPrompt] = React.useState<string>(prefilledQuery);
console.log("propmpt",prompt);
const [status, setStatus] = React.useState<Status>('idle'); const [status, setStatus] = React.useState<Status>('idle');
const [queries, setQueries] = React.useState<Query[]>([]); const [queries, setQueries] = React.useState<Query[]>([]);
const [conversationId, setConversationId] = React.useState<string | null>(null); const [conversationId, setConversationId] = React.useState<string | null>(null);
@@ -666,106 +668,110 @@ export const WidgetCore = ({
{isOpen && size === 'large' && {isOpen && size === 'large' &&
<Overlay onClick={handleClose} /> <Overlay onClick={handleClose} />
} }
<WidgetContainer ref={widgetRef} className={`${(isOpen ? "open" : "close")}`} modal={size == 'large'}> {
{<StyledContainer isOpen={isOpen}> isOpen && (
<div> <WidgetContainer ref={widgetRef} className={`${size !== 'large' ? (isOpen ? "open" : "close") : "modal"}`} modal={size === 'large'}>
<CancelButton onClick={handleClose}> <StyledContainer isOpen={isOpen}>
<Cross2Icon width={24} height={24} color={theme === 'light' ? 'black' : 'white'} /> <div>
</CancelButton> <CancelButton onClick={handleClose}>
<Header> <Cross2Icon width={24} height={24} color={theme === 'light' ? 'black' : 'white'} />
<img style={{ transform: 'translateY(-5px)', maxWidth: "42px", maxHeight: "42px" }} onError={handleImageError} src={avatar} alt='docs-gpt' /> </CancelButton>
<ContentWrapper> <Header>
<Title>{title}</Title> <img style={{ transform: 'translateY(-5px)', maxWidth: "42px", maxHeight: "42px" }} onError={handleImageError} src={avatar} alt='docs-gpt' />
<Description>{description}</Description> <ContentWrapper>
</ContentWrapper> <Title>{title}</Title>
</Header> <Description>{description}</Description>
</div> </ContentWrapper>
<Conversation onWheel={handleUserInterrupt} onTouchMove={handleUserInterrupt}> </Header>
{ </div>
queries.length > 0 ? queries?.map((query, index) => { <Conversation onWheel={handleUserInterrupt} onTouchMove={handleUserInterrupt}>
return ( {
<React.Fragment key={index}> queries.length > 0 ? queries?.map((query, index) => {
{ return (
query.prompt && <MessageBubble type='QUESTION'> <React.Fragment key={index}>
<Message {
type='QUESTION' query.prompt && <MessageBubble type='QUESTION'>
ref={(!(query.response || query.error) && index === queries.length - 1) ? endMessageRef : null}> <Message
{query.prompt} type='QUESTION'
</Message> ref={(!(query.response || query.error) && index === queries.length - 1) ? endMessageRef : null}>
</MessageBubble> {query.prompt}
} </Message>
{ </MessageBubble>
query.response ? <MessageBubble onMouseOver={() => { isBubbleHovered.current = true }} type='ANSWER'> }
<Message {
type='ANSWER' query.response ? <MessageBubble onMouseOver={() => { isBubbleHovered.current = true }} type='ANSWER'>
ref={(index === queries.length - 1) ? endMessageRef : null} <Message
> type='ANSWER'
<Markdown ref={(index === queries.length - 1) ? endMessageRef : null}
dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(md.render(query.response)) }} >
/> <Markdown
</Message> dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(md.render(query.response)) }}
/>
</Message>
{collectFeedback && {collectFeedback &&
<Feedback> <Feedback>
<Like <Like
style={{ style={{
stroke: query.feedback == 'LIKE' ? '#8860DB' : '#c0c0c0', stroke: query.feedback == 'LIKE' ? '#8860DB' : '#c0c0c0',
visibility: query.feedback == 'LIKE' ? 'visible' : 'hidden' visibility: query.feedback == 'LIKE' ? 'visible' : 'hidden'
}} }}
fill='none' fill='none'
onClick={() => handleFeedback("LIKE", index)} /> onClick={() => handleFeedback("LIKE", index)} />
<Dislike <Dislike
style={{ style={{
stroke: query.feedback == 'DISLIKE' ? '#ed8085' : '#c0c0c0', stroke: query.feedback == 'DISLIKE' ? '#ed8085' : '#c0c0c0',
visibility: query.feedback == 'DISLIKE' ? 'visible' : 'hidden' visibility: query.feedback == 'DISLIKE' ? 'visible' : 'hidden'
}} }}
fill='none' fill='none'
onClick={() => handleFeedback("DISLIKE", index)} /> onClick={() => handleFeedback("DISLIKE", index)} />
</Feedback>} </Feedback>}
</MessageBubble> </MessageBubble>
: <div> : <div>
{ {
query.error ? <ErrorAlert> query.error ? <ErrorAlert>
<ExclamationTriangleIcon width={22} height={22} color='#b91c1c' /> <ExclamationTriangleIcon width={22} height={22} color='#b91c1c' />
<div> <div>
<h5 style={{ margin: 2 }}>Network Error</h5> <h5 style={{ margin: 2 }}>Network Error</h5>
<span style={{ margin: 2, fontSize: '13px' }}>{query.error}</span> <span style={{ margin: 2, fontSize: '13px' }}>{query.error}</span>
</div> </div>
</ErrorAlert> </ErrorAlert>
: <MessageBubble type='ANSWER'> : <MessageBubble type='ANSWER'>
<Message type='ANSWER' style={{ fontWeight: 600 }}> <Message type='ANSWER' style={{ fontWeight: 600 }}>
<DotAnimation>.</DotAnimation> <DotAnimation>.</DotAnimation>
<Delay delay={200}>.</Delay> <Delay delay={200}>.</Delay>
<Delay delay={400}>.</Delay> <Delay delay={400}>.</Delay>
</Message> </Message>
</MessageBubble> </MessageBubble>
} }
</div> </div>
} }
</React.Fragment>) </React.Fragment>)
}) })
: <Hero title={heroTitle} description={heroDescription} theme={theme} /> : <Hero title={heroTitle} description={heroDescription} theme={theme} />
} }
</Conversation> </Conversation>
<div> <div>
<PromptContainer <PromptContainer
onSubmit={handleSubmit}> onSubmit={handleSubmit}>
<StyledInput <StyledInput
value={prompt} onChange={(event) => setPrompt(event.target.value)} value={prompt} onChange={(event) => setPrompt(event.target.value)}
type='text' placeholder="Ask your question" /> type='text' placeholder="Ask your question" />
<StyledButton <StyledButton
disabled={prompt.trim().length == 0 || status !== 'idle'}> disabled={prompt.trim().length == 0 || status !== 'idle'}>
<PaperPlaneIcon width={18} height={18} color='white' /> <PaperPlaneIcon width={18} height={18} color='white' />
</StyledButton> </StyledButton>
</PromptContainer> </PromptContainer>
<Tagline> <Tagline>
Powered by&nbsp; Powered by&nbsp;
<Hyperlink target='_blank' href='https://www.docsgpt.cloud/'>DocsGPT</Hyperlink> <Hyperlink target='_blank' href='https://www.docsgpt.cloud/'>DocsGPT</Hyperlink>
</Tagline> </Tagline>
</div> </div>
</StyledContainer>} </StyledContainer>
</WidgetContainer> </WidgetContainer>
)
}
</ThemeProvider> </ThemeProvider>
) )
} }

View File

@@ -9,30 +9,30 @@ import DOMPurify from 'dompurify';
const themes = { const themes = {
dark: { dark: {
bg: '#222327', bg: '#222327',
text: '#fff', text: '#fff',
primary: { primary: {
text: "#FAFAFA", text: "#FAFAFA",
bg: '#111111' bg: '#111111'
}, },
secondary: { secondary: {
text: "#A1A1AA", text: "#A1A1AA",
bg: "#38383b" bg: "#38383b"
} }
}, },
light: { light: {
bg: '#fff', bg: '#fff',
text: '#000', text: '#000',
primary: { primary: {
text: "#222327", text: "#222327",
bg: "#fff" bg: "#fff"
}, },
secondary: { secondary: {
text: "#A1A1AA", text: "#A1A1AA",
bg: "#F6F6F6" bg: "#F6F6F6"
} }
} }
} }
const Main = styled.div` const Main = styled.div`
all:initial; all:initial;
@@ -157,9 +157,7 @@ export const SearchBar = ({
: :
setResults([]) setResults([])
}, [input]) }, [input])
React.useEffect(()=>{
console.log(isWidgetOpen, input);
},[isWidgetOpen])
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => { const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') { if (event.key === 'Enter') {
setIsWidgetOpen(true); setIsWidgetOpen(true);
@@ -181,7 +179,7 @@ export const SearchBar = ({
onChange={(e) => setInput(e.target.value)} onChange={(e) => setInput(e.target.value)}
/> />
{ {
input.length>0 && results.length > 0 && ( input.length > 0 && results.length > 0 && (
<SearchResults> <SearchResults>
{results.map((res) => ( {results.map((res) => (
<div> <div>
@@ -198,14 +196,14 @@ export const SearchBar = ({
) )
} }
</Container> </Container>
<WidgetCore {isWidgetOpen && <WidgetCore
theme={theme} theme={theme}
apiHost={apiHost} apiHost={apiHost}
apiKey={apiKey} apiKey={apiKey}
prefilledQuery={input} prefilledQuery={input}
isOpen={isWidgetOpen} isOpen={isWidgetOpen}
handleClose={handleClose} size={'large'} handleClose={handleClose} size={'large'}
/> />}
</Main> </Main>
</ThemeProvider> </ThemeProvider>