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

Commit

Permalink
markdown and lighlight syntax
Browse files Browse the repository at this point in the history
  • Loading branch information
clement2026 committed Oct 4, 2023
1 parent a5c365b commit d0f181c
Show file tree
Hide file tree
Showing 11 changed files with 1,086 additions and 36 deletions.
4 changes: 4 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"@headlessui/react": "^1.7.17",
"@microsoft/fetch-event-source": "^2.0.1",
"@tanstack/react-virtual": "^3.0.0-beta.60",
"@types/react-syntax-highlighter": "^15.5.7",
"axios": "^1.5.0",
"crypto-js": "^4.1.1",
"date-fns": "^2.30.0",
Expand All @@ -29,9 +30,12 @@
"react-dom": "^18.2.0",
"react-helmet-async": "^1.3.0",
"react-icons": "^4.10.1",
"react-markdown": "^9.0.0",
"react-nice-avatar": "^1.4.1",
"react-router": "^6.15.0",
"react-router-dom": "^6.15.0",
"react-syntax-highlighter": "^15.5.0",
"remark-gfm": "^4.0.0",
"valtio": "^1.11.2",
"wavesurfer.js": "^7.3.0"
},
Expand Down
10 changes: 5 additions & 5 deletions src/home/chat-window/attached/attached-item.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, {useEffect, useState} from "react"
import {LLMMessage} from "../../../shared-types.ts";
import {cx} from "../../../util/util.tsx";
import {blueColor, neutralColor} from "../compnent/theme.ts";
import {userColor, assistantColor} from "../compnent/theme.ts";
import {LiaEllipsisHSolid} from "react-icons/lia";
import {useSnapshot} from "valtio/react";
import {layoutState} from "../../../state/layout-state.ts";
Expand Down Expand Up @@ -53,14 +53,14 @@ export const AttachedItem: React.FC<Props> = ({message}) => {
}

const userTheme = {
bg: blueColor.bg,
text: blueColor.text,
bg: userColor.bg,
text: userColor.text,
other: "max-w-[80%] self-end",
}

const assistantTheme = {
bg: neutralColor.bg,
text: neutralColor.text,
bg: assistantColor.bg,
text: assistantColor.text,
other: "max-w-[80%] self-start",
}

Expand Down
41 changes: 39 additions & 2 deletions src/home/chat-window/compnent/my-text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import {MySpin} from "./widget/icon.tsx"
import {BsCheck2Circle} from "react-icons/bs"
import {CgDanger} from "react-icons/cg"
import {Theme} from "./theme.ts"
import ReactMarkdown from "react-markdown";
import remarkGfm from 'remark-gfm'
import SyntaxHighlighter from 'react-syntax-highlighter';

interface TextProps {
messageSnap: Message
Expand All @@ -13,11 +16,45 @@ interface TextProps {

export const MyText: React.FC<TextProps> = ({messageSnap, theme}) => {
// console.info("Row rendered, messageSnap.id:", messageSnap.id, new Date().toLocaleString())
// console.info("messageSnap.text", messageSnap.text)
return <div
className={cx("flex flex-col rounded-2xl whitespace-pre-wrap px-3 pt-1.5 pb-0.5",
className={cx("flex flex-col rounded-2xl px-3 pt-1.5 pb-0.5",
theme.text, theme.bg
)}>
<p className="leading-snug">{messageSnap.text}</p>

<div className={cx("leading-snug prose")}>
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
// eslint-disable-next-line @typescript-eslint/no-unused-vars
a: ({node, children, ...props}) => {
if (props.href?.includes('http')) {
props.target = '_blank'
props.rel = 'noopener noreferrer'
}
return <a {...props}>{children}</a>
},
code: ({className, children, ...props}) => {
const match = /language-(\w+)/.exec(className || '')
return String(children).includes("\n") ? (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
<SyntaxHighlighter
{...props}
children={String(children).replace(/\n$/, '')}
style={{...theme.code}}
language={match?.[1]??"javascript"}
PreTag="div"
/>
) : (
<code {...props} className={className} >
{children}
</code>
)
}
}}
>{messageSnap.text}</ReactMarkdown>
</div>
<div className="flex justify-end gap-1 pointer-events-none">
<p className="text-xs inline whitespace-nowrap" data-pseudo-content={formatAgo(messageSnap.createdAt)}></p>
{['sent', 'received'].includes(messageSnap.status) &&
Expand Down
16 changes: 12 additions & 4 deletions src/home/chat-window/compnent/theme.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import {atelierDuneDark as userCode} from 'react-syntax-highlighter/dist/esm/styles/hljs'
import {atelierDuneLight as assistantCode} from 'react-syntax-highlighter/dist/esm/styles/hljs'
import React from "react";

export type Theme = {
bg: string
text: string
normalIcon: string
warningIcon: string
attachIcon: string
code: { [key: string]: React.CSSProperties }

playBg: string
play: string
pause: string
Expand All @@ -14,12 +20,13 @@ export type Theme = {
label: string
}

export const blueColor: Theme = {
export const userColor: Theme = {
bg: 'bg-blue-700',
text: 'text-violet-100',
text: 'text-violet-100 user-prose',
normalIcon: 'fill-violet-100',
warningIcon: 'text-yellow-500',
attachIcon: 'fill-violet-100 -left-2 -top-1.5 rotate-45',
code: {...userCode},

playBg: 'bg-blue-grey',
play: 'white',
Expand All @@ -31,12 +38,13 @@ export const blueColor: Theme = {
label: 'white',
}

export const neutralColor: Theme = {
export const assistantColor: Theme = {
bg: 'bg-neutral-100 bg-opacity-80',
text: 'text-neutral-800',
text: 'text-neutral-800 assistant-prose',
normalIcon: 'fill-neutral-800',
warningIcon: 'text-yellow-500',
attachIcon: '-right-2 -top-2 fill-neutral-800 -rotate-45',
code: assistantCode,

playBg: 'bg-white',
play: '#5e5e5e',
Expand Down
14 changes: 0 additions & 14 deletions src/home/chat-window/compnent/widget/icon.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,5 @@
import React, {CSSProperties} from "react";

export const ThinkingIcon = () => {
return (
<div>
<svg className="animate-spin h-5 w-5 text-neutral-500" xmlns="http://www.w3.org/2000/svg"
fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor"
strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
</div>
)
}

type Props = {
className?: string
onClick?: (event: React.MouseEvent<SVGElement>) => void
Expand Down
6 changes: 3 additions & 3 deletions src/home/chat-window/message-list/row.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Message} from "../../../data-structure/message.tsx"
import React, {useCallback, useEffect, useState} from "react"
import {markMessageAsDeleted} from "../../../state/app-state.ts"
import {blueColor, neutralColor} from "../compnent/theme.ts"
import {userColor, assistantColor} from "../compnent/theme.ts"
import {cx} from "../../../util/util.tsx"
import {MySpin} from "../compnent/widget/icon.tsx"
import {Audio} from "../compnent/audio.tsx"
Expand All @@ -24,7 +24,7 @@ export const Row: React.FC<Props> = ({
}) => {
// console.info("Row rendered, messageId:", messageProxy.id, new Date().toLocaleString())
const messageSnap = useSnapshot(messageProxy)
const [theme, setTheme] = useState(neutralColor)
const [theme, setTheme] = useState(assistantColor)
const [hoveringOnRow, setHoveringOnRow] = useState(false)
const [isAttached, setIsAttached] = useState(false)

Expand All @@ -41,7 +41,7 @@ export const Row: React.FC<Props> = ({
}, [chatId, messageSnap.id])

useEffect(() => {
setTheme(messageSnap.role === "user" ? blueColor : neutralColor)
setTheme(messageSnap.role === "user" ? userColor : assistantColor)
}, [messageSnap.role])

return (
Expand Down
10 changes: 5 additions & 5 deletions src/home/chat-window/prompt/prompt-editor-item.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {useCallback, useEffect, useRef, useState} from "react"
import {cx} from "../../../util/util.tsx";
import {blueColor, neutralColor} from "../compnent/theme.ts";
import {userColor, assistantColor} from "../compnent/theme.ts";
import {LLMMessage, Role} from "../../../shared-types.ts";
import {useSnapshot} from "valtio/react";
import _ from "lodash";
Expand Down Expand Up @@ -165,13 +165,13 @@ const ActionDot: React.FC<ActionDotProps> = ({actionType, clickAction}) => {


const userTheme = {
bg: blueColor.bg,
text: blueColor.text,
bg: userColor.bg,
text: userColor.text,
}

const assistantTheme = {
bg: neutralColor.bg,
text: neutralColor.text,
bg: assistantColor.bg,
text: assistantColor.text,
}

const systemTheme = {
Expand Down
75 changes: 73 additions & 2 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ https://benborgers.com/posts/tailwind-h-screen
background-color: #d4d4d4;
transition: background-color 1000ms linear;
}

/*for Firefox*/
.scrollbar-visible-neutral-300 {
scrollbar-color: #d4d4d4 transparent;
Expand All @@ -54,6 +55,7 @@ https://benborgers.com/posts/tailwind-h-screen
background-color: #71717a;
transition: background-color 1000ms linear;
}

/*for Firefox*/
.scrollbar-visible-neutral-500 {
scrollbar-color: #71717a transparent;
Expand All @@ -74,9 +76,11 @@ https://benborgers.com/posts/tailwind-h-screen
background-color: transparent;
transition: background-color 1000ms linear;
}

.scrollbar-hidden-instant::-webkit-scrollbar-thumb {
background-color: transparent;
}

/*for Firefox*/
.scrollbar-hidden {
scrollbar-color: transparent transparent;
Expand Down Expand Up @@ -113,5 +117,72 @@ https://benborgers.com/posts/tailwind-h-screen

/*Prevent an element from being selected and copied with CSS. see https://danoc.me/blog/css-prevent-copy*/
[data-pseudo-content]::before {
content: attr(data-pseudo-content);
}
content: attr(data-pseudo-content);
}

.user-prose h1,
.user-prose h2,
.user-prose h3,
.user-prose h4,
.user-prose p,
.user-prose a,
.user-prose blockquote,
.user-prose figure,
.user-prose figcaption,
.user-prose strong,
.user-prose em,
.user-prose code,
.user-prose pre,
.user-prose ol,
.user-prose ul,
.user-prose li,
.user-prose table,
.user-prose thead,
.user-prose tr,
.user-prose th,
.user-prose td,
.user-prose img,
.user-prose video,
.user-prose hr {
@apply text-violet-100 !important;
}
.user-prose a{
@apply visited:text-purple-400 !important;
}

.assistant-prose h1,
.assistant-prose h2,
.assistant-prose h3,
.assistant-prose h4,
.assistant-prose p,
.assistant-prose a,
.assistant-prose blockquote,
.assistant-prose figure,
.assistant-prose figcaption,
.assistant-prose strong,
.assistant-prose em,
.assistant-prose code,
.assistant-prose pre,
.assistant-prose ol,
.assistant-prose ul,
.assistant-prose li,
.assistant-prose table,
.assistant-prose thead,
.assistant-prose tr,
.assistant-prose th,
.assistant-prose td,
.assistant-prose img,
.assistant-prose video,
.assistant-prose hr {
@apply text-neutral-800 leading-snug !important;
}
.assistant-prose a{
@apply visited:text-purple-600 !important;
}

h1,
h2,
h3,
h4{
@apply my-0.5 !important;
}
1 change: 1 addition & 0 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import './index.css'
import './prose.css'

import {createBrowserRouter, RouterProvider,} from "react-router-dom"
import Auth from "./auth/auth.tsx"
Expand Down
Loading

0 comments on commit d0f181c

Please sign in to comment.