Skip to content
This repository was archived by the owner on Sep 30, 2024. It is now read-only.

Commit 1cd36d2

Browse files
authored
app/cody: small window UI for cody chat page (#53384)
Closes https://github.com/sourcegraph/sourcegraph/issues/53112 Significantly improves the small window/mobile UI in the Cody chat page, perfect for docking the App on the side of the screen. ## Test plan https://github.com/sourcegraph/sourcegraph/assets/206864/406589c6-a73b-41a8-8f97-86e6f7c34021
1 parent 2f1faff commit 1cd36d2

File tree

2 files changed

+160
-10
lines changed

2 files changed

+160
-10
lines changed

client/web/src/cody/chat/CodyChatPage.module.scss

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,55 @@
1+
@import 'wildcard/src/global-styles/breakpoints';
2+
3+
.page-header {
4+
display: flex;
5+
margin-bottom: 1rem;
6+
7+
@media (--sm-breakpoint-down) {
8+
display: none;
9+
}
10+
}
11+
112
.chat-main-wrapper {
13+
display: flex;
14+
flex-direction: column;
215
filter: none;
316
border: 1px solid var(--border-color-2);
417
border-radius: var(--border-radius);
518
padding: 0;
19+
20+
@media (--sm-breakpoint-down) {
21+
&-with-mobile-history {
22+
display: none;
23+
}
24+
}
25+
}
26+
27+
.page {
28+
@media (--sm-breakpoint-down) {
29+
// These need to be !important to override the `py-4` default padding on the page
30+
padding-top: 0 !important;
31+
padding-bottom: 0 !important;
32+
}
633
}
734

835
.page-wrapper {
936
padding-top: 0.625rem;
1037
height: 93%;
38+
39+
@media (--sm-breakpoint-down) {
40+
padding-top: 0;
41+
height: 100%;
42+
}
43+
}
44+
45+
.sidebar-wrapper {
46+
display: flex;
47+
flex-direction: column;
48+
height: 100%;
49+
50+
@media (--sm-breakpoint-down) {
51+
display: none;
52+
}
1153
}
1254

1355
.sidebar {
@@ -53,3 +95,44 @@
5395
cursor: pointer;
5496
}
5597
}
98+
99+
.mobile-top-bar {
100+
display: none;
101+
102+
@media (--sm-breakpoint-down) {
103+
display: flex;
104+
justify-content: space-around;
105+
align-items: center;
106+
padding: 0.25rem 0.5rem;
107+
border-bottom: 1px solid var(--border-color-2);
108+
}
109+
}
110+
111+
.mobile-top-bar-button {
112+
color: var(--text-muted);
113+
padding: 0.5rem 2rem;
114+
justify-content: center;
115+
116+
&:active {
117+
background-color: var(--color-bg-1);
118+
}
119+
}
120+
121+
.mobile-top-bar-divider {
122+
height: 1.25rem;
123+
}
124+
125+
.mobile-history-wrapper {
126+
display: none;
127+
128+
@media (--sm-breakpoint-down) {
129+
display: flex;
130+
flex-direction: column;
131+
height: 100%;
132+
width: 100%;
133+
}
134+
}
135+
136+
.mobile-history {
137+
overflow-y: auto;
138+
}

client/web/src/cody/chat/CodyChatPage.tsx

Lines changed: 77 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
import React, { useEffect, useState } from 'react'
22

3-
import { mdiClose, mdiCogOutline, mdiDelete, mdiDotsVertical, mdiOpenInNew, mdiPlus, mdiChevronRight } from '@mdi/js'
3+
import {
4+
mdiClose,
5+
mdiCogOutline,
6+
mdiDelete,
7+
mdiDotsVertical,
8+
mdiOpenInNew,
9+
mdiPlus,
10+
mdiChevronRight,
11+
mdiViewList,
12+
} from '@mdi/js'
413
import classNames from 'classnames'
514
import { useLocation, useNavigate } from 'react-router-dom'
615

@@ -41,6 +50,7 @@ import styles from './CodyChatPage.module.scss'
4150

4251
interface CodyChatPageProps {
4352
authenticatedUser: AuthenticatedUser | null
53+
isSourcegraphApp: boolean
4454
context: Pick<SourcegraphContext, 'authProviders'>
4555
}
4656

@@ -78,7 +88,11 @@ const onTranscriptHistoryLoad = (
7888
}
7989
}
8090

81-
export const CodyChatPage: React.FunctionComponent<CodyChatPageProps> = ({ authenticatedUser, context }) => {
91+
export const CodyChatPage: React.FunctionComponent<CodyChatPageProps> = ({
92+
authenticatedUser,
93+
context,
94+
isSourcegraphApp,
95+
}) => {
8296
const { pathname } = useLocation()
8397
const navigate = useNavigate()
8498

@@ -119,6 +133,12 @@ export const CodyChatPage: React.FunctionComponent<CodyChatPageProps> = ({ authe
119133
}
120134
}, [transcriptId, loaded, pathname, navigate])
121135

136+
const [showMobileHistory, setShowMobileHistory] = useState<boolean>(false)
137+
// Close mobile history list when transcript changes
138+
useEffect(() => {
139+
setShowMobileHistory(false)
140+
}, [transcript])
141+
122142
if (!loaded) {
123143
return null
124144
}
@@ -137,7 +157,7 @@ export const CodyChatPage: React.FunctionComponent<CodyChatPageProps> = ({ authe
137157
}
138158

139159
return (
140-
<Page className="overflow-hidden">
160+
<Page className={classNames('d-flex flex-column', styles.page)}>
141161
<PageTitle title="Cody AI Chat" />
142162
<PageHeader
143163
actions={
@@ -154,23 +174,25 @@ export const CodyChatPage: React.FunctionComponent<CodyChatPageProps> = ({ authe
154174
graph.
155175
</>
156176
}
157-
className="mb-3"
177+
className={styles.pageHeader}
158178
>
159179
<PageHeader.Heading as="h2" styleAs="h1">
160180
<PageHeader.Breadcrumb icon={CodyColorIcon}>
161181
<div className="d-inline-flex align-items-center">
162182
Cody Chat
163-
<Badge variant="info" className="ml-2">
164-
Beta
165-
</Badge>
183+
{!isSourcegraphApp && (
184+
<Badge variant="info" className="ml-2">
185+
Beta
186+
</Badge>
187+
)}
166188
</div>
167189
</PageHeader.Breadcrumb>
168190
</PageHeader.Heading>
169191
</PageHeader>
170192

171193
{/* Page content */}
172-
<div className={classNames('row mb-5', styles.pageWrapper)}>
173-
<div className="d-flex flex-column col-sm-3 h-100">
194+
<div className={classNames('row flex-1 overflow-hidden', styles.pageWrapper)}>
195+
<div className={classNames('col-md-3', styles.sidebarWrapper)}>
174196
<div className={styles.sidebarHeader}>
175197
<H4>
176198
<b>Chats</b>
@@ -285,9 +307,54 @@ export const CodyChatPage: React.FunctionComponent<CodyChatPageProps> = ({ authe
285307
))}
286308
</div>
287309

288-
<div className={classNames('d-flex flex-column col-sm-9 h-100', styles.chatMainWrapper)}>
310+
<div
311+
className={classNames(
312+
'col-md-9 h-100',
313+
styles.chatMainWrapper,
314+
showMobileHistory && styles.chatMainWrapperWithMobileHistory
315+
)}
316+
>
317+
<div className={styles.mobileTopBar}>
318+
<Button
319+
variant="icon"
320+
className={styles.mobileTopBarButton}
321+
onClick={() => setShowMobileHistory(true)}
322+
>
323+
<Icon aria-hidden={true} svgPath={mdiViewList} className="mr-2" />
324+
All chats
325+
</Button>
326+
<div className={classNames('border-right', styles.mobileTopBarDivider)} />
327+
<Button variant="icon" className={styles.mobileTopBarButton} onClick={initializeNewChat}>
328+
<Icon aria-hidden={true} svgPath={mdiPlus} className="mr-2" />
329+
New chat
330+
</Button>
331+
</div>
289332
<ChatUI codyChatStore={codyChatStore} />
290333
</div>
334+
335+
{showMobileHistory && (
336+
<div className={styles.mobileHistoryWrapper}>
337+
<div className={styles.mobileTopBar}>
338+
<Button
339+
variant="icon"
340+
className={classNames('w-100', styles.mobileTopBarButton)}
341+
onClick={() => setShowMobileHistory(false)}
342+
>
343+
<Icon aria-hidden={true} svgPath={mdiClose} className="mr-2" />
344+
Close
345+
</Button>
346+
</div>
347+
<div className={styles.mobileHistory}>
348+
<HistoryList
349+
currentTranscript={transcript}
350+
transcriptHistory={transcriptHistory}
351+
truncateMessageLength={60}
352+
loadTranscriptFromHistory={loadTranscriptFromHistory}
353+
deleteHistoryItem={deleteHistoryItem}
354+
/>
355+
</div>
356+
</div>
357+
)}
291358
</div>
292359
</Page>
293360
)

0 commit comments

Comments
 (0)