-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
## Motivation - overall code section improvement - adds dark/light syntax highlighter theme - warp lines in code blocks - automatic chat titles - prepare the code for further extractions - improved markdown images -
- Loading branch information
Showing
17 changed files
with
1,057 additions
and
751 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
import { useSDK } from "@captn/react/use-sdk"; | ||
import DeleteForeverIcon from "@mui/icons-material/DeleteForever"; | ||
import MoreVertIcon from "@mui/icons-material/MoreVert"; | ||
import PushPinIcon from "@mui/icons-material/PushPin"; | ||
import StarIcon from "@mui/icons-material/Star"; | ||
import Dropdown from "@mui/joy/Dropdown"; | ||
import IconButton from "@mui/joy/IconButton"; | ||
import List from "@mui/joy/List"; | ||
import ListItem from "@mui/joy/ListItem"; | ||
import ListItemButton from "@mui/joy/ListItemButton"; | ||
import ListItemDecorator from "@mui/joy/ListItemDecorator"; | ||
import Menu from "@mui/joy/Menu"; | ||
import MenuButton from "@mui/joy/MenuButton"; | ||
import MenuItem from "@mui/joy/MenuItem"; | ||
import type { ColorPaletteProp } from "@mui/joy/styles"; | ||
import Typography from "@mui/joy/Typography"; | ||
import { useTranslation } from "next-i18next"; | ||
import type { Except } from "type-fest"; | ||
|
||
import { APP_ID } from "@/client/apps/assistant/constants"; | ||
import type { ChatModel } from "@/shared/types/assistant"; | ||
|
||
export function ChatList({ | ||
chats, | ||
chatId, | ||
color, | ||
onDelete, | ||
onChatSelect, | ||
}: { | ||
chatId: string; | ||
chats: (Except<ChatModel, "messages"> & { id: string })[]; | ||
color: ColorPaletteProp; | ||
onDelete?(chatId: string): void; | ||
onChatSelect(chatId: string): void; | ||
}) { | ||
const { t } = useTranslation(["labels", "common"]); | ||
const { send } = useSDK<unknown, object>(APP_ID, {}); | ||
return ( | ||
<List | ||
sx={{ | ||
flex: 1, | ||
width: "100%", | ||
overflowY: "auto", | ||
overflowX: "hidden", | ||
flexShrink: 0, | ||
}} | ||
> | ||
{chats | ||
.sort((a, b) => { | ||
if (a.pinned && b.pinned) { | ||
return 0; | ||
} | ||
|
||
return a.pinned ? -1 : 1; | ||
}) | ||
.map(chat => ( | ||
<ListItem | ||
key={chat.id} | ||
sx={{ | ||
"& .MuiListItem-endAction": { | ||
mr: -0.75, | ||
}, | ||
}} | ||
endAction={ | ||
<Dropdown> | ||
<MenuButton | ||
aria-label={t("common:menu")} | ||
slots={{ root: IconButton }} | ||
slotProps={{ | ||
root: { | ||
variant: "plain", | ||
color: "neutral", | ||
sx: { | ||
"&:focus-visible": { | ||
zIndex: "unset", | ||
outlineOffset: -2, | ||
}, | ||
}, | ||
}, | ||
}} | ||
> | ||
<MoreVertIcon /> | ||
</MenuButton> | ||
<Menu color="neutral" variant="plain"> | ||
<MenuItem | ||
onClick={() => { | ||
send({ | ||
action: "assistant:update", | ||
payload: { | ||
id: chat.id, | ||
update: { pinned: !chat.pinned }, | ||
}, | ||
}); | ||
}} | ||
> | ||
<ListItemDecorator | ||
sx={theme => ({ | ||
"--Icon-color": chat.pinned | ||
? theme.vars.palette.primary["500"] | ||
: "currentColor", | ||
})} | ||
> | ||
<PushPinIcon /> | ||
</ListItemDecorator>{" "} | ||
{t("labels:pin")} | ||
</MenuItem> | ||
<MenuItem | ||
onClick={() => { | ||
send({ | ||
action: "assistant:update", | ||
payload: { | ||
id: chat.id, | ||
update: { | ||
favorite: !chat.favorite, | ||
}, | ||
}, | ||
}); | ||
}} | ||
> | ||
<ListItemDecorator | ||
sx={theme => ({ | ||
"--Icon-color": chat.favorite | ||
? theme.vars.palette.primary["500"] | ||
: "currentColor", | ||
})} | ||
> | ||
<StarIcon /> | ||
</ListItemDecorator>{" "} | ||
{t("labels:favorite")} | ||
</MenuItem> | ||
<MenuItem | ||
onClick={() => { | ||
if (onDelete) { | ||
onDelete(chat.id); | ||
} | ||
}} | ||
> | ||
<ListItemDecorator | ||
sx={theme => ({ | ||
"--Icon-color": theme.vars.palette.red["500"], | ||
})} | ||
> | ||
<DeleteForeverIcon /> | ||
</ListItemDecorator>{" "} | ||
{t("labels:delete")} | ||
</MenuItem> | ||
</Menu> | ||
</Dropdown> | ||
} | ||
> | ||
<ListItemButton | ||
selected={chatId === chat.id} | ||
color={color} | ||
sx={{ | ||
"&.Mui-focusVisible": { | ||
zIndex: "unset", | ||
outlineOffset: -2, | ||
}, | ||
}} | ||
onClick={() => { | ||
if (onChatSelect) { | ||
onChatSelect(chat.id); | ||
} | ||
}} | ||
> | ||
<Typography noWrap>{chat.label}</Typography> | ||
</ListItemButton> | ||
</ListItem> | ||
))} | ||
</List> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import Box from "@mui/joy/Box"; | ||
import Input from "@mui/joy/Input"; | ||
import type { ColorPaletteProp } from "@mui/joy/styles"; | ||
import { useEffect, useState } from "react"; | ||
|
||
export function ChatName({ | ||
name, | ||
onUpdate, | ||
color, | ||
}: { | ||
name: string; | ||
onUpdate(_label: string): void; | ||
color: ColorPaletteProp; | ||
}) { | ||
const [currentName, setCurrentName] = useState(name); | ||
useEffect(() => { | ||
setCurrentName(name); | ||
}, [name]); | ||
return ( | ||
<Box sx={{ flex: 1, display: "flex", alignItems: "center" }}> | ||
<Input | ||
fullWidth | ||
color={color} | ||
variant="soft" | ||
value={currentName} | ||
onChange={event => { | ||
setCurrentName(event.target.value); | ||
}} | ||
onBlur={() => { | ||
if (onUpdate && currentName !== name) { | ||
onUpdate(currentName); | ||
} | ||
}} | ||
/> | ||
</Box> | ||
); | ||
} |
43 changes: 43 additions & 0 deletions
43
src/client/apps/assistant/components/data-type-selector.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import FindInPageIcon from "@mui/icons-material/FindInPage"; | ||
import List from "@mui/joy/List"; | ||
import ListItem from "@mui/joy/ListItem"; | ||
import ListItemButton from "@mui/joy/ListItemButton"; | ||
import ListItemContent from "@mui/joy/ListItemContent"; | ||
import ListItemDecorator from "@mui/joy/ListItemDecorator"; | ||
import Switch from "@mui/joy/Switch"; | ||
import { useTranslation } from "next-i18next"; | ||
import type { ChangeEvent as ReactChangeEvent } from "react"; | ||
|
||
import { PopupButton } from "@/client/apps/shared/components"; | ||
import type { DataTypeItem } from "@/shared/types/assistant"; | ||
|
||
export function DataTypeSelector({ | ||
dataTypes, | ||
onChange, | ||
}: { | ||
dataTypes: DataTypeItem[]; | ||
onChange(id: string, checked?: boolean): void; | ||
}) { | ||
const { t } = useTranslation(["labels"]); | ||
return ( | ||
<PopupButton label={t("labels:dataUsage")} icon={<FindInPageIcon />}> | ||
<List sx={{ minWidth: 200 }}> | ||
{dataTypes.map(dataType => ( | ||
<ListItem key={dataType.id}> | ||
<ListItemButton tabIndex={-1} component="label" selected={dataType.active}> | ||
<ListItemDecorator> | ||
<Switch | ||
checked={Boolean(dataType.active)} | ||
onChange={(event: ReactChangeEvent<HTMLInputElement>) => { | ||
onChange(dataType.id, event.target.checked); | ||
}} | ||
/> | ||
</ListItemDecorator> | ||
<ListItemContent>{t(`labels:${dataType.type}`)}</ListItemContent> | ||
</ListItemButton> | ||
</ListItem> | ||
))} | ||
</List> | ||
</PopupButton> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import CloseIcon from "@mui/icons-material/Close"; | ||
import Box from "@mui/joy/Box"; | ||
import IconButton from "@mui/joy/IconButton"; | ||
import Snackbar from "@mui/joy/Snackbar"; | ||
import Typography from "@mui/joy/Typography"; | ||
import { useTranslation } from "next-i18next"; | ||
|
||
export function MessageStack({ | ||
provider, | ||
isWarningOpen, | ||
error, | ||
onClose, | ||
}: { | ||
provider: string; | ||
isWarningOpen: boolean; | ||
error: string; | ||
onClose(): void; | ||
}) { | ||
const { t } = useTranslation(["labels", "texts"]); | ||
return ( | ||
<Box | ||
sx={{ | ||
position: "absolute", | ||
bottom: 0, | ||
right: 0, | ||
m: 1, | ||
maxHeight: 500, | ||
overflow: "auto", | ||
}} | ||
> | ||
<Box sx={{ overflow: "hidden", display: "flex", flexDirection: "column", gap: 1 }}> | ||
<Snackbar | ||
color="danger" | ||
variant="soft" | ||
open={Boolean(error)} | ||
sx={{ position: "relative", bottom: "unset", right: "unset" }} | ||
endDecorator={ | ||
<IconButton aria-label={t("labels:close")} onClick={onClose}> | ||
<CloseIcon /> | ||
</IconButton> | ||
} | ||
> | ||
<Typography>{error}</Typography> | ||
</Snackbar> | ||
<Snackbar | ||
color="warning" | ||
variant="soft" | ||
open={isWarningOpen} | ||
sx={{ position: "relative", bottom: "unset", right: "unset" }} | ||
> | ||
<Typography>{t("texts:enterCommonAPIKey", { provider })}</Typography> | ||
</Snackbar> | ||
</Box> | ||
</Box> | ||
); | ||
} |
Oops, something went wrong.