Skip to content

Commit d816664

Browse files
committed
fix: Mobile ux issues (cant close settings side panel, feedback button covering settings button)
1 parent 075c30e commit d816664

File tree

4 files changed

+62
-23
lines changed

4 files changed

+62
-23
lines changed

src/client/components/ChatV2/ChatV2.tsx

Lines changed: 59 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import RestartAltIcon from '@mui/icons-material/RestartAlt'
22
import HelpIcon from '@mui/icons-material/Help'
3-
import { Alert, Box, Drawer, Fab, FormControlLabel, Paper, Switch, Typography, useMediaQuery, useTheme } from '@mui/material'
4-
import { useEffect, useRef, useState } from 'react'
3+
import { Alert, Box, Drawer, Fab, FormControlLabel, Paper, Switch, SxProps, Typography, useMediaQuery, useTheme } from '@mui/material'
4+
import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react'
55
import { useTranslation } from 'react-i18next'
66
import { useParams, useSearchParams } from 'react-router-dom'
77
import { DEFAULT_ASSISTANT_INSTRUCTIONS, DEFAULT_MODEL, DEFAULT_MODEL_TEMPERATURE, FREE_MODEL, inProduction, validModels } from '../../../config'
@@ -12,7 +12,7 @@ import useLocalStorageState from '../../hooks/useLocalStorageState'
1212
import { useCourseRagIndices } from '../../hooks/useRagIndices'
1313
import useRetryTimeout from '../../hooks/useRetryTimeout'
1414
import useUserStatus from '../../hooks/useUserStatus'
15-
import type { Message, Prompt } from '../../types'
15+
import type { Course, Message, Prompt } from '../../types'
1616
import { ChatBox } from './ChatBox'
1717
import { Conversation } from './Conversation'
1818
import { DisclaimerModal } from './Disclaimer'
@@ -29,11 +29,14 @@ import { useIsEmbedded } from '../../contexts/EmbeddedContext'
2929
import { enqueueSnackbar } from 'notistack'
3030
import { useAnalyticsDispatch } from '../../stores/analytics'
3131
import EmailButton from './EmailButton'
32-
import { ArrowDownward, MenuBookTwoTone, Tune } from '@mui/icons-material'
32+
import { ArrowDownward, ChevronLeft, Close, MenuBookTwoTone, Tune } from '@mui/icons-material'
3333
import { useChatScroll } from '../../hooks/useChatScroll'
3434
import { TestUseInfoV2 } from './TestUseInfo'
3535
import Footer from '../Footer'
3636
import type { ToolCallResultEvent } from '../../../shared/chat'
37+
import { ChatToolResult } from '../../../shared/tools'
38+
import { TFunction } from 'i18next'
39+
import { RagIndexAttributes } from '../../../shared/types'
3740

3841
function useLocalStorageStateWithURLDefault(key: string, defaultValue: string, urlKey: string) {
3942
const [value, setValue] = useLocalStorageState(key, defaultValue)
@@ -91,7 +94,7 @@ export const ChatV2 = () => {
9194
const [chatLeftSidePanelOpen, setChatLeftSidePanelOpen] = useState<boolean>(false)
9295
// RAG states
9396
const [ragIndexId, setRagIndexId] = useState<number | undefined>()
94-
const [activeToolResult, setActiveToolResult] = useState<ToolCallResultEvent | undefined>()
97+
const [activeToolResult, setActiveToolResult0] = useState<ToolCallResultEvent | undefined>()
9598
const ragIndex = ragIndices?.find((index) => index.id === ragIndexId)
9699

97100
// Analytics
@@ -286,6 +289,33 @@ export const ChatV2 = () => {
286289
}
287290
}, [userStatus, course])
288291

292+
const showRagSelector = (ragIndices?.length ?? 0) > 0
293+
const rightMenuOpen = !!activeToolResult
294+
const rightMenuWidth = rightMenuOpen ? '300px' : '0px'
295+
296+
// Handle layout shift when right menu opens (tool result becomes visible)
297+
const prevScrollYProportional = useRef(0)
298+
const handleLayoutShift = useCallback(() => {
299+
// Save the current proportional scroll position
300+
prevScrollYProportional.current = window.scrollY / document.body.scrollHeight
301+
302+
console.log('New scroll position:', window.scrollY, document.body.scrollHeight)
303+
304+
// Set timeout to restore after layout change
305+
setTimeout(() => {
306+
const scrollY = prevScrollYProportional.current * document.body.scrollHeight
307+
window.scrollTo(0, scrollY)
308+
console.log('Restored scroll position:', scrollY, document.body.scrollHeight)
309+
}, 0)
310+
}, [])
311+
const setActiveToolResult = useCallback(
312+
(toolResult: ToolCallResultEvent | undefined) => {
313+
handleLayoutShift()
314+
setActiveToolResult0(toolResult)
315+
},
316+
[handleLayoutShift],
317+
)
318+
289319
if (course && course.usageLimit === 0) {
290320
return (
291321
<Box>
@@ -326,10 +356,6 @@ export const ChatV2 = () => {
326356
}
327357
}
328358

329-
const showRagSelector = (ragIndices?.length ?? 0) > 0
330-
const rightMenuOpen = !!activeToolResult
331-
const rightMenuWidth = rightMenuOpen ? '300px' : '0px'
332-
333359
if (statusLoading) return null
334360

335361
return (
@@ -352,10 +378,11 @@ export const ChatV2 = () => {
352378
}}
353379
>
354380
<LeftMenu
355-
sx={{}}
356381
course={course}
357382
handleReset={handleReset}
358-
user={user}
383+
onClose={() => {
384+
setChatLeftSidePanelOpen(false)
385+
}}
359386
t={t}
360387
setSettingsModalOpen={setSettingsModalOpen}
361388
setDisclaimerStatus={setDisclaimerStatus}
@@ -371,7 +398,6 @@ export const ChatV2 = () => {
371398
sx={{ display: { sm: 'none', md: 'flex' }, position: 'fixed', top: 0 }}
372399
course={course}
373400
handleReset={handleReset}
374-
user={user}
375401
t={t}
376402
setSettingsModalOpen={setSettingsModalOpen}
377403
setDisclaimerStatus={setDisclaimerStatus}
@@ -550,10 +576,10 @@ export const ChatV2 = () => {
550576
}
551577

552578
const LeftMenu = ({
553-
sx,
579+
sx = {},
554580
course,
555581
handleReset,
556-
user,
582+
onClose,
557583
t,
558584
setSettingsModalOpen,
559585
setDisclaimerStatus,
@@ -562,6 +588,19 @@ const LeftMenu = ({
562588
setRagIndexId,
563589
ragIndices,
564590
messages,
591+
}: {
592+
sx?: object
593+
course?: Course
594+
handleReset: () => void
595+
onClose?: () => void
596+
t: TFunction
597+
setSettingsModalOpen: React.Dispatch<React.SetStateAction<boolean>>
598+
setDisclaimerStatus: React.Dispatch<React.SetStateAction<boolean>>
599+
showRagSelector: boolean
600+
ragIndex?: RagIndexAttributes
601+
setRagIndexId: React.Dispatch<React.SetStateAction<number | undefined>>
602+
ragIndices?: RagIndexAttributes[]
603+
messages: Message[]
565604
}) => {
566605
return (
567606
<Box
@@ -580,7 +619,7 @@ const LeftMenu = ({
580619
>
581620
<Box p="1rem">
582621
{course && <ChatInfo course={course} />}
583-
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '0.6rem', mb: '2rem' }}>
622+
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '0.6rem' }}>
584623
<OutlineButtonBlack startIcon={<RestartAltIcon />} onClick={handleReset} id="empty-conversation-button">
585624
{t('chat:emptyConversation')}
586625
</OutlineButtonBlack>
@@ -606,6 +645,11 @@ const LeftMenu = ({
606645
)}
607646
</Box>
608647
</Box>
648+
{onClose && (
649+
<OutlineButtonBlack sx={{ m: '1rem', mt: 'auto' }} onClick={onClose} startIcon={<ChevronLeft />}>
650+
{t('common:close')}
651+
</OutlineButtonBlack>
652+
)}
609653
<Footer />
610654
</Box>
611655
)

src/client/components/ChatV2/util.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ export const getCompletionStream = async ({
4747
},
4848
}
4949

50-
console.log(prevResponseId)
51-
5250
formData.set('data', JSON.stringify(data))
5351

5452
return postAbortableStream('/ai/v2/stream', formData, abortController)
@@ -94,8 +92,6 @@ export const getCompletionStreamV3 = async ({
9492
},
9593
}
9694

97-
console.log('getCompletionStreamV3', data)
98-
9995
formData.set('data', JSON.stringify(data))
10096

10197
return postAbortableStream('/ai/v3/stream', formData, abortController)

src/client/components/Feedback.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ export const Feedback: React.FC = () => {
5454
aria-label="feedback"
5555
sx={(theme) => ({
5656
position: 'fixed',
57-
bottom: { xs: 12, sm: 18 },
58-
right: { xs: 12, sm: 18 },
57+
bottom: '0.5rem',
58+
right: { xs: '6rem', sm: '6rem', md: '1rem' },
5959
zIndex: theme.zIndex.modal + 1,
6060
opacity: 0.9,
61-
6261
transition: 'opacity 0.2s',
6362
})}
63+
size="small"
6464
onClick={() => setModalOpen(true)}
6565
>
6666
<FeedbackIcon />

src/client/components/Footer/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ const Footer = () => {
3636
<Box
3737
component="footer"
3838
sx={{
39-
mt: 'auto',
4039
width: '100%',
4140
}}
4241
>

0 commit comments

Comments
 (0)