From 4ce60537cabc14e16dde3d30899b65a33bb10a65 Mon Sep 17 00:00:00 2001 From: Daniel Avila Date: Sun, 19 Mar 2023 11:25:12 -0400 Subject: [PATCH] search result styling changes --- api/lib/parse/citeText.js | 4 +- client/package-lock.json | 46 +++ client/package.json | 2 + client/src/components/Main/TextChat.jsx | 8 +- client/src/components/Messages/Content.jsx | 28 +- .../components/Messages/ContentRewrite.jsx | 153 +++++++++ client/src/components/Messages/Embed.jsx | 6 +- client/src/components/Messages/Highlight.jsx | 22 +- client/src/components/Messages/Message.jsx | 50 +-- .../src/components/Messages/TextWrapper.jsx | 1 + client/src/components/Messages/Wrapper.jsx | 25 ++ client/src/store/submitSlice.js | 10 +- client/src/style.css | 295 +++--------------- client/src/{style copy.css => style2.css} | 295 +++++++++++++++--- 14 files changed, 608 insertions(+), 337 deletions(-) create mode 100644 client/src/components/Messages/ContentRewrite.jsx create mode 100644 client/src/components/Messages/Wrapper.jsx rename client/src/{style copy.css => style2.css} (90%) diff --git a/api/lib/parse/citeText.js b/api/lib/parse/citeText.js index 536c981d4e..8132446f52 100644 --- a/api/lib/parse/citeText.js +++ b/api/lib/parse/citeText.js @@ -8,6 +8,7 @@ const citeText = (res, noLinks = false) => { if (noLinks) { citations.forEach((citation) => { const digit = citation.match(/\d+?/g)[0]; + // result = result.replaceAll(citation, `[${digit}](#) `); result = result.replaceAll(citation, `[${digit}](#) `); }); @@ -20,7 +21,8 @@ const citeText = (res, noLinks = false) => { citations.forEach((citation) => { const digit = citation.match(/\d+?/g)[0]; - result = result.replaceAll(citation, `[${digit}](${sources[digit - 1]}) `); + result = result.replaceAll(citation, `[${digit}](${sources[digit - 1]}) `); + // result = result.replaceAll(citation, `[${digit}](${sources[digit - 1]}) `); }); return result; diff --git a/client/package-lock.json b/client/package-lock.json index 8cb2e3b2a6..a5be4e97dc 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -25,9 +25,11 @@ "markdown-to-jsx": "^7.1.9", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-highlight": "^0.15.0", "react-lazy-load": "^4.0.1", "react-markdown": "^8.0.5", "react-redux": "^8.0.5", + "react-string-replace": "^1.1.0", "react-textarea-autosize": "^8.4.0", "react-transition-group": "^4.4.5", "rehype-highlight": "^6.0.0", @@ -10490,6 +10492,22 @@ "react": "^18.2.0" } }, + "node_modules/react-highlight": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/react-highlight/-/react-highlight-0.15.0.tgz", + "integrity": "sha512-5uV/b/N4Z421GSVVe05fz+OfTsJtFzx/fJBdafZyw4LS70XjIZwgEx3Lrkfc01W/RzZ2Dtfb0DApoaJFAIKBtA==", + "dependencies": { + "highlight.js": "^10.5.0" + } + }, + "node_modules/react-highlight/node_modules/highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==", + "engines": { + "node": "*" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -10627,6 +10645,14 @@ } } }, + "node_modules/react-string-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-string-replace/-/react-string-replace-1.1.0.tgz", + "integrity": "sha512-N6RalSDFGbOHs0IJi1H611WbZsvk3ZT47Jl2JEXFbiS3kTwsdCYij70Keo/tWtLy7sfhDsYm7CwNM/WmjXIaMw==", + "engines": { + "node": ">=0.12.0" + } + }, "node_modules/react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", @@ -20398,6 +20424,21 @@ "scheduler": "^0.23.0" } }, + "react-highlight": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/react-highlight/-/react-highlight-0.15.0.tgz", + "integrity": "sha512-5uV/b/N4Z421GSVVe05fz+OfTsJtFzx/fJBdafZyw4LS70XjIZwgEx3Lrkfc01W/RzZ2Dtfb0DApoaJFAIKBtA==", + "requires": { + "highlight.js": "^10.5.0" + }, + "dependencies": { + "highlight.js": { + "version": "10.7.3", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz", + "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==" + } + } + }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -20479,6 +20520,11 @@ "tslib": "^2.0.0" } }, + "react-string-replace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/react-string-replace/-/react-string-replace-1.1.0.tgz", + "integrity": "sha512-N6RalSDFGbOHs0IJi1H611WbZsvk3ZT47Jl2JEXFbiS3kTwsdCYij70Keo/tWtLy7sfhDsYm7CwNM/WmjXIaMw==" + }, "react-style-singleton": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", diff --git a/client/package.json b/client/package.json index 9133870639..59db175599 100644 --- a/client/package.json +++ b/client/package.json @@ -35,9 +35,11 @@ "markdown-to-jsx": "^7.1.9", "react": "^18.2.0", "react-dom": "^18.2.0", + "react-highlight": "^0.15.0", "react-lazy-load": "^4.0.1", "react-markdown": "^8.0.5", "react-redux": "^8.0.5", + "react-string-replace": "^1.1.0", "react-textarea-autosize": "^8.4.0", "react-transition-group": "^4.4.5", "rehype-highlight": "^6.0.0", diff --git a/client/src/components/Main/TextChat.jsx b/client/src/components/Main/TextChat.jsx index 56b8e78179..d4f7392266 100644 --- a/client/src/components/Main/TextChat.jsx +++ b/client/src/components/Main/TextChat.jsx @@ -17,7 +17,7 @@ import { refreshConversation } from '~/store/convoSlice'; import { setMessages } from '~/store/messageSlice'; -import { setSubmitState, setSubmission } from '~/store/submitSlice'; +import { setSubmitState, toggleCursor } from '~/store/submitSlice'; import { setText } from '~/store/textSlice'; import { useMessageHandler } from '../../utils/handleSubmit'; @@ -238,6 +238,7 @@ export default function TextChat({ messages }) { if (data.final) { convoHandler(data, currentState, currentMsg); + dispatch(toggleCursor()); console.log('final', data); } if (data.created) { @@ -247,6 +248,7 @@ export default function TextChat({ messages }) { let text = data.text || data.response; if (data.initial) { console.log(data); + dispatch(toggleCursor()); } if (data.message) { latestResponseText = text; @@ -268,6 +270,7 @@ export default function TextChat({ messages }) { events.onmessage = onMessage; events.oncancel = (e) => { + dispatch(toggleCursor(true)); cancelHandler(latestResponseText, currentState, currentMsg); }; @@ -276,7 +279,7 @@ export default function TextChat({ messages }) { events.close(); const data = JSON.parse(e.data); - + dispatch(toggleCursor(true)); errorHandler(data, currentState, currentMsg); }; @@ -284,6 +287,7 @@ export default function TextChat({ messages }) { return () => { events.removeEventListener('message', onMessage); + dispatch(toggleCursor(true)); const isCancelled = events.readyState <= 1; events.close(); if (isCancelled) { diff --git a/client/src/components/Messages/Content.jsx b/client/src/components/Messages/Content.jsx index 09cf373041..7dc016808a 100644 --- a/client/src/components/Messages/Content.jsx +++ b/client/src/components/Messages/Content.jsx @@ -27,10 +27,6 @@ const Content = React.memo(({ content }) => { components={{ code, p, - text: blinker, - // li, - // ul, - // ol }} > {content} @@ -62,10 +58,28 @@ const p = React.memo((props) => { const blinker = ({ node }) => { if (node.type === 'text' && node.value === '█') { - return {node.value} + return {node.value}; } - + return null; -} +}; + +const em = React.memo(({ node, ...props }) => { + if ( + props.children[0] && + typeof props.children[0] === 'string' && + props.children[0].startsWith('^') + ) { + return {props.children[0].substring(1)}; + } + if ( + props.children[0] && + typeof props.children[0] === 'string' && + props.children[0].startsWith('~') + ) { + return {props.children[0].substring(1)}; + } + return ; +}); export default Content; diff --git a/client/src/components/Messages/ContentRewrite.jsx b/client/src/components/Messages/ContentRewrite.jsx new file mode 100644 index 0000000000..36bd510337 --- /dev/null +++ b/client/src/components/Messages/ContentRewrite.jsx @@ -0,0 +1,153 @@ +import React, { useState, useEffect } from 'react'; +import ReactMarkdown from 'react-markdown'; +import rehypeKatex from 'rehype-katex'; +import rehypeHighlight from 'rehype-highlight'; +import remarkMath from 'remark-math'; +import remarkGfm from 'remark-gfm'; +import TabLink from './TabLink'; +import Markdown from 'markdown-to-jsx'; +import Highlight from './Highlight'; +import CodeBlock from './CodeBlock'; +import Embed from './Embed'; +// import { langSubset } from '~/utils/languages'; + +const mdOptions = { + wrapper: React.Fragment, + forceWrapper: true, + overrides: { + a: { + component: TabLink + // props: { + // className: 'foo' + // } + }, + pre: code, + // code: { + // component: code + // }, + // pre: { + // component: PreBlock + // }, + p: { + component: p + } + } +}; + +const Content = ({ content }) => { + return ( + <> + {/* + {content} + */} + + {content} + + + ); +}; + +const PreBlock = ({children, ...rest}) => { + console.log('pre', children); + if ('type' in children && children ['type'] === 'code') { + return code(children['props']); + } + return
{children}
; +}; + +const code = (props) => { + const { inline, className, children, ...rest } = props; + + if ('type' in children && children ['type'] === 'code') { + // return code(children['props']); + const match = /language-(\w+)/.exec(className || ''); + const lang = match && match[1]; + console.log('code', lang, children); + + if (inline) { + return {children}; + } else { + return ( + + + + ); + } + } + return
{children}
; + + const match = /language-(\w+)/.exec(className || ''); + const lang = match && match[1]; + console.log('code', lang, children); + + if (inline) { + return {children}; + } else { + return ( + + + + ); + } +}; + +const p = (props) => { + const regex = /^█$/; + const match = regex.exec(props?.children || ''); + // if (match) { + // return ( + //

+ // {props?.children.slice(0, -1)} + // {'█'} + //

+ // ); + + if (match) { + return ( +

+ {'█'} +

+ ); + } + + return

{props?.children}

; +}; + +export default Content; diff --git a/client/src/components/Messages/Embed.jsx b/client/src/components/Messages/Embed.jsx index 88761d093b..845ad8c576 100644 --- a/client/src/components/Messages/Embed.jsx +++ b/client/src/components/Messages/Embed.jsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import Clipboard from '../svg/Clipboard'; import CheckMark from '../svg/CheckMark'; -export default function Embed({ children, lang = '', code, matched }) { +const Embed = React.memo(({ children, lang = '', code, matched }) => { const [buttonText, setButtonText] = useState('Copy code'); const isClicked = buttonText === 'Copy code'; @@ -32,4 +32,6 @@ export default function Embed({ children, lang = '', code, matched }) { ); -} +}); + +export default Embed; diff --git a/client/src/components/Messages/Highlight.jsx b/client/src/components/Messages/Highlight.jsx index 44ee742096..035b860a3e 100644 --- a/client/src/components/Messages/Highlight.jsx +++ b/client/src/components/Messages/Highlight.jsx @@ -1,10 +1,11 @@ import React, { useState, useEffect } from 'react'; +import Highlighter from 'react-highlight'; import hljs from 'highlight.js'; import { languages } from '~/utils/languages'; -export default function Highlight({language, code}) { +const Highlight = React.memo(({ language, code }) => { const [highlightedCode, setHighlightedCode] = useState(code); - const lang = languages.has(language) ? language : 'shell'; + const lang = language ? language : 'javascript'; useEffect(() => { setHighlightedCode(hljs.highlight(code, { language: lang }).value); @@ -12,7 +13,20 @@ export default function Highlight({language, code}) { return (
-      
+      {!highlightedCode ? (
+        // 
+        
+          {code}
+        
+      ) : (
+        
+      )}
     
); -} \ No newline at end of file +}); + +export default Highlight; + diff --git a/client/src/components/Messages/Message.jsx b/client/src/components/Messages/Message.jsx index dc829c92ef..691f596553 100644 --- a/client/src/components/Messages/Message.jsx +++ b/client/src/components/Messages/Message.jsx @@ -1,12 +1,11 @@ import React, { useState, useEffect, useRef, useCallback } from 'react'; -import TextWrapper from './TextWrapper'; -import Content from './Content'; +import Wrapper from './Wrapper'; import MultiMessage from './MultiMessage'; import { useSelector, useDispatch } from 'react-redux'; import HoverButtons from './HoverButtons'; import SiblingSwitch from './SiblingSwitch'; import { setConversation, setLatestMessage } from '~/store/convoSlice'; -import { setModel, setCustomModel, setCustomGpt, setDisabled } from '~/store/submitSlice'; +import { setModel, setCustomModel, setCustomGpt, toggleCursor, setDisabled } from '~/store/submitSlice'; import { setMessages } from '~/store/messageSlice'; import { fetchById } from '~/utils/fetchers'; import { getIconOfModel } from '~/utils'; @@ -22,7 +21,7 @@ export default function Message({ siblingCount, setSiblingIdx }) { - const { isSubmitting, model, chatGptLabel, promptPrefix } = useSelector( + const { isSubmitting, model, chatGptLabel, cursor, promptPrefix } = useSelector( (state) => state.submit ); const [abortScroll, setAbort] = useState(false); @@ -42,8 +41,12 @@ export default function Message({ return ''; } + if (!cursor) { + return ''; + } + return ; - }, [blinker]); + }, [blinker, cursor]); useEffect(() => { if (blinker && !abortScroll) { @@ -109,7 +112,7 @@ export default function Message({ const clickSearchResult = async () => { if (!searchResult) return; - dispatch(setMessages([])) + dispatch(setMessages([])); const convoResponse = await fetchById('convos', message.conversationId); const convo = convoResponse.data; if (convo?.chatGptLabel) { @@ -122,10 +125,10 @@ export default function Message({ dispatch(setCustomGpt(convo)); dispatch(setConversation(convo)); - const {data} = await fetchById('messages', message.conversationId); - dispatch(setMessages(data)) + const { data } = await fetchById('messages', message.conversationId); + dispatch(setMessages(data)); dispatch(setDisabled(false)); - }; + }; return ( <> @@ -189,15 +192,12 @@ export default function Message({
{/*
*/}
- {/* {!isCreatedByUser && !searchResult ? ( - - ) : ( - text - )} */} - +
)} @@ -219,13 +219,13 @@ export default function Message({
- + ); } diff --git a/client/src/components/Messages/TextWrapper.jsx b/client/src/components/Messages/TextWrapper.jsx index 3cfd0a1b37..ff6f9a1528 100644 --- a/client/src/components/Messages/TextWrapper.jsx +++ b/client/src/components/Messages/TextWrapper.jsx @@ -49,6 +49,7 @@ const inLineWrap = (parts) => { export default function TextWrapper({ text, generateCursor }) { let embedTest = false; let result = null; + console.log('text wrapper', text) // to match unenclosed code blocks if (text.match(/```/g)?.length === 1) { diff --git a/client/src/components/Messages/Wrapper.jsx b/client/src/components/Messages/Wrapper.jsx new file mode 100644 index 0000000000..6caaf0d7fb --- /dev/null +++ b/client/src/components/Messages/Wrapper.jsx @@ -0,0 +1,25 @@ +import React from 'react'; +import TextWrapper from './TextWrapper'; +import Content from './Content'; + +const Wrapper = React.memo(({ text, generateCursor, isCreatedByUser, searchResult }) => { + if (!isCreatedByUser && searchResult) { + return ( + + ); + } else if (!isCreatedByUser && !searchResult) { + return ( + + ); + } else if (isCreatedByUser) { + return <>{text}; + } +}); + +export default Wrapper; diff --git a/client/src/store/submitSlice.js b/client/src/store/submitSlice.js index 9293f7b56b..6efdb85148 100644 --- a/client/src/store/submitSlice.js +++ b/client/src/store/submitSlice.js @@ -9,6 +9,7 @@ const initialState = { promptPrefix: null, chatGptLabel: null, customModel: null, + cursor: true, }; const currentSlice = createSlice({ @@ -33,6 +34,13 @@ const currentSlice = createSlice({ setModel: (state, action) => { state.model = action.payload; }, + toggleCursor: (state, action) => { + if (action.payload) { + state.cursor = action.payload; + } else { + state.cursor = !state.cursor; + } + }, setCustomGpt: (state, action) => { state.promptPrefix = action.payload.promptPrefix; state.chatGptLabel = action.payload.chatGptLabel; @@ -43,7 +51,7 @@ const currentSlice = createSlice({ } }); -export const { setSubmitState, setSubmission, setStopStream, setDisabled, setModel, setCustomGpt, setCustomModel } = +export const { toggleCursor, setSubmitState, setSubmission, setStopStream, setDisabled, setModel, setCustomGpt, setCustomModel } = currentSlice.actions; export default currentSlice.reducer; diff --git a/client/src/style.css b/client/src/style.css index 20e6a739d8..2f43cfe285 100644 --- a/client/src/style.css +++ b/client/src/style.css @@ -118,237 +118,6 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { } } -@layer base { - * { - box-sizing: border-box; - } - - body, - html { - height: 100%; - } - - body { - line-height: inherit; - margin: 0; - } - - .dark body, - .dark html { - --tw-bg-opacity: 1; - background-color: rgba(52, 53, 65, var(--tw-bg-opacity)); - } - - #root { - height: 100%; - } - - img { - @apply inline-block; - } - - input[type='range']::-webkit-slider-thumb { - -webkit-appearance: none; - @apply w-4; - @apply h-4; - @apply rounded-full; - background: rgba(16, 163, 127); - } - - ::-webkit-scrollbar { - height: 1rem; - width: 0.5rem; - } - @media screen and (min-width: 768px) { - .scrollbar-trigger ::-webkit-scrollbar-thumb { - visibility: hidden; - } - } - - @media screen and (max-width: 768px) { - ::-webkit-scrollbar { - display: none; - scrollbar-width: none; /* Firefox */ - } - } - - .hide-scroll-bar::-webkit-scrollbar { - display: none; - scrollbar-width: none; /* Firefox */ - } - - .dark::-webkit-scrollbar-thumb { - --tw-bg-opacity: 1; - background-color: rgba(86, 88, 105, var(--tw-bg-opacity)); - } - - ::-webkit-scrollbar-thumb { - --tw-border-opacity: 1; - background-color: rgba(217, 217, 227, 0.8); - border-color: rgba(255, 255, 255, var(--tw-border-opacity)); - border-radius: 9999px; - border-width: 1px; - } - - ::-webkit-scrollbar-track { - background-color: transparent; - border-radius: 9999px; - } - - pre ::-webkit-scrollbar-thumb { - display: none; - } - pre { - scrollbar-width: 0; - } - - textarea:focus { - outline: none; - } - - a.link { - @apply underline dark:hover:text-white hover:text-black; - } -} - -@layer components { - /* .markdown ol, - .markdown ul { - display: flex; - flex-direction: column; - padding-left: 1rem; - } */ - - .markdown ol li, - .markdown ol li > p, - .markdown ol ol, - .markdown ol ul, - .markdown ul li, - .markdown ul li > p, - .markdown ul ol, - .markdown ul ul { - margin: 0; - } - - .markdown ul li:before { - content: '•'; - font-size: 0.875rem; - line-height: 1.25rem; - margin-left: -1rem; - margin-top: 1.55rem; - /* position: absolute; */ - } -} - -.prose :where(code):not(:where([class~=not-prose] *)) { - color:var(--tw-prose-code); - font-size:.875em; - font-weight:600; - } - .prose :where(code):not(:where([class~=not-prose] *)):before { - content:"`" - } - .prose :where(code):not(:where([class~=not-prose] *)):after { - content:"`" - } - .prose :where(a code):not(:where([class~=not-prose] *)) { - color:inherit - } - .prose :where(h1 code):not(:where([class~=not-prose] *)) { - color:inherit - } - .prose :where(h2 code):not(:where([class~=not-prose] *)) { - color:inherit; - font-size:.875em - } - .prose :where(h3 code):not(:where([class~=not-prose] *)) { - color:inherit; - font-size:.9em - } - .prose :where(h4 code):not(:where([class~=not-prose] *)) { - color:inherit - } - .prose :where(blockquote code):not(:where([class~=not-prose] *)) { - color:inherit - } - .prose :where(thead th code):not(:where([class~=not-prose] *)) { - color:inherit - } - /* .prose :where(pre):not(:where([class~=not-prose] *)) { - background-color:transparent; - border-radius:.375rem; - color:currentColor; - font-size:.875em; - font-weight:400; - line-height:1.7142857; - margin:0; - overflow-x:auto; - padding:0 - } */ - .prose :where(pre code):not(:where([class~=not-prose] *)) { - background-color:transparent; - border-radius:0; - border-width:0; - color:inherit; - font-family:inherit; - font-size:inherit; - font-weight:inherit; - line-height:inherit; - padding:0 - } - .prose :where(pre code):not(:where([class~=not-prose] *)):before { - content:none - } - .prose :where(pre code):not(:where([class~=not-prose] *)):after { - content:none - } - -/* :not(pre) > code.hljs, -:not(pre) > code[class*='language-'] { - border-radius: 0.3em; - white-space: normal; -} -.hljs-comment { - color: hsla(0, 0%, 100%, 0.5); -} -.hljs-meta { - color: hsla(0, 0%, 100%, 0.6); -} -.hljs-built_in, -.hljs-class .hljs-title { - color: #e9950c; -} -.hljs-doctag, -.hljs-formula, -.hljs-keyword, -.hljs-literal { - color: #2e95d3; -} -.hljs-addition, -.hljs-attribute, -.hljs-meta-string, -.hljs-regexp, -.hljs-string { - color: #00a67d; -} -.hljs-attr, -.hljs-number, -.hljs-selector-attr, -.hljs-selector-class, -.hljs-selector-pseudo, -.hljs-template-variable, -.hljs-type, -.hljs-variable { - color: #df3079; -} -.hljs-bullet, -.hljs-link, -.hljs-selector-id, -.hljs-symbol, -.hljs-title { - color: #f22c3d; -} */ - .prose { color:var(--tw-prose-body); max-width:65ch @@ -356,7 +125,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { .prose :where([class~=lead]):not(:where([class~=not-prose] *)) { color:var(--tw-prose-lead); font-size:1.25em; - /* line-height:1.6; */ + line-height:1.6; margin-bottom:1.2em; margin-top:1.2em } @@ -417,13 +186,13 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { margin-top:1.25em; padding-left:1.625em } - /* .prose :where(ol>li):not(:where([class~=not-prose] *))::marker { + .prose :where(ol>li):not(:where([class~=not-prose] *))::marker { color:var(--tw-prose-counters); font-weight:400 } .prose :where(ul>li):not(:where([class~=not-prose] *))::marker { color:var(--tw-prose-bullets) - } */ + } .prose :where(hr):not(:where([class~=not-prose] *)) { border-color:var(--tw-prose-hr); border-top-width:1px; @@ -476,7 +245,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { color:var(--tw-prose-headings); font-size:1.25em; font-weight:600; - /* line-height:1.6; */ + line-height:1.6; margin-bottom:.6em; margin-top:1.6em } @@ -487,7 +256,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { .prose :where(h4):not(:where([class~=not-prose] *)) { color:var(--tw-prose-headings); font-weight:600; - /* line-height:1.5; */ + line-height:1.5; margin-bottom:.5em; margin-top:1.5em } @@ -506,7 +275,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { .prose :where(figcaption):not(:where([class~=not-prose] *)) { color:var(--tw-prose-captions); font-size:.875em; - /* line-height:1.4285714; */ + line-height:1.4285714; margin-top:.8571429em } .prose :where(code):not(:where([class~=not-prose] *)) { @@ -549,7 +318,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { color:currentColor; font-size:.875em; font-weight:400; - /* line-height:1.7142857; */ + line-height:1.7142857; margin:0; overflow-x:auto; padding:0 @@ -573,7 +342,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { } .prose :where(table):not(:where([class~=not-prose] *)) { font-size:.875em; - /* line-height:1.7142857; */ + line-height:1.7142857; margin-bottom:2em; margin-top:2em; table-layout:auto; @@ -609,10 +378,46 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { .prose :where(tfoot td):not(:where([class~=not-prose] *)) { vertical-align:top } - /* .prose :where(p):not(:where([class~=not-prose] *)) { + .prose { + --tw-prose-body:#374151; + --tw-prose-headings:#111827; + --tw-prose-lead:#4b5563; + --tw-prose-links:#111827; + --tw-prose-bold:#111827; + --tw-prose-counters:#6b7280; + --tw-prose-bullets:#d1d5db; + --tw-prose-hr:#e5e7eb; + --tw-prose-quotes:#111827; + --tw-prose-quote-borders:#e5e7eb; + --tw-prose-captions:#6b7280; + --tw-prose-code:#111827; + --tw-prose-pre-code:#e5e7eb; + --tw-prose-pre-bg:#1f2937; + --tw-prose-th-borders:#d1d5db; + --tw-prose-td-borders:#e5e7eb; + --tw-prose-invert-body:#d1d5db; + --tw-prose-invert-headings:#fff; + --tw-prose-invert-lead:#9ca3af; + --tw-prose-invert-links:#fff; + --tw-prose-invert-bold:#fff; + --tw-prose-invert-counters:#9ca3af; + --tw-prose-invert-bullets:#4b5563; + --tw-prose-invert-hr:#374151; + --tw-prose-invert-quotes:#f3f4f6; + --tw-prose-invert-quote-borders:#374151; + --tw-prose-invert-captions:#9ca3af; + --tw-prose-invert-code:#fff; + --tw-prose-invert-pre-code:#d1d5db; + --tw-prose-invert-pre-bg:rgba(0,0,0,.5); + --tw-prose-invert-th-borders:#4b5563; + --tw-prose-invert-td-borders:#374151; + font-size:1rem; + line-height:1.75 + } + .prose :where(p):not(:where([class~=not-prose] *)) { margin-bottom:1.25em; margin-top:1.25em - } */ + } .prose :where(video):not(:where([class~=not-prose] *)) { margin-bottom:2em; margin-top:2em @@ -1136,8 +941,6 @@ html { display: flex; flex-direction: column; padding-left: 1rem; - margin-top: 0; - margin-bottom: 0; } .markdown ol { @@ -1993,11 +1796,7 @@ html { .markdown ul { display:flex; flex-direction:column; - padding-left:1rem; - margin: 0; -} -.markdown ul::marker { - margin-top: 1.55rem; + padding-left:1rem } .markdown ol li, .markdown ol li>p, diff --git a/client/src/style copy.css b/client/src/style2.css similarity index 90% rename from client/src/style copy.css rename to client/src/style2.css index 2f43cfe285..20e6a739d8 100644 --- a/client/src/style copy.css +++ b/client/src/style2.css @@ -118,6 +118,237 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { } } +@layer base { + * { + box-sizing: border-box; + } + + body, + html { + height: 100%; + } + + body { + line-height: inherit; + margin: 0; + } + + .dark body, + .dark html { + --tw-bg-opacity: 1; + background-color: rgba(52, 53, 65, var(--tw-bg-opacity)); + } + + #root { + height: 100%; + } + + img { + @apply inline-block; + } + + input[type='range']::-webkit-slider-thumb { + -webkit-appearance: none; + @apply w-4; + @apply h-4; + @apply rounded-full; + background: rgba(16, 163, 127); + } + + ::-webkit-scrollbar { + height: 1rem; + width: 0.5rem; + } + @media screen and (min-width: 768px) { + .scrollbar-trigger ::-webkit-scrollbar-thumb { + visibility: hidden; + } + } + + @media screen and (max-width: 768px) { + ::-webkit-scrollbar { + display: none; + scrollbar-width: none; /* Firefox */ + } + } + + .hide-scroll-bar::-webkit-scrollbar { + display: none; + scrollbar-width: none; /* Firefox */ + } + + .dark::-webkit-scrollbar-thumb { + --tw-bg-opacity: 1; + background-color: rgba(86, 88, 105, var(--tw-bg-opacity)); + } + + ::-webkit-scrollbar-thumb { + --tw-border-opacity: 1; + background-color: rgba(217, 217, 227, 0.8); + border-color: rgba(255, 255, 255, var(--tw-border-opacity)); + border-radius: 9999px; + border-width: 1px; + } + + ::-webkit-scrollbar-track { + background-color: transparent; + border-radius: 9999px; + } + + pre ::-webkit-scrollbar-thumb { + display: none; + } + pre { + scrollbar-width: 0; + } + + textarea:focus { + outline: none; + } + + a.link { + @apply underline dark:hover:text-white hover:text-black; + } +} + +@layer components { + /* .markdown ol, + .markdown ul { + display: flex; + flex-direction: column; + padding-left: 1rem; + } */ + + .markdown ol li, + .markdown ol li > p, + .markdown ol ol, + .markdown ol ul, + .markdown ul li, + .markdown ul li > p, + .markdown ul ol, + .markdown ul ul { + margin: 0; + } + + .markdown ul li:before { + content: '•'; + font-size: 0.875rem; + line-height: 1.25rem; + margin-left: -1rem; + margin-top: 1.55rem; + /* position: absolute; */ + } +} + +.prose :where(code):not(:where([class~=not-prose] *)) { + color:var(--tw-prose-code); + font-size:.875em; + font-weight:600; + } + .prose :where(code):not(:where([class~=not-prose] *)):before { + content:"`" + } + .prose :where(code):not(:where([class~=not-prose] *)):after { + content:"`" + } + .prose :where(a code):not(:where([class~=not-prose] *)) { + color:inherit + } + .prose :where(h1 code):not(:where([class~=not-prose] *)) { + color:inherit + } + .prose :where(h2 code):not(:where([class~=not-prose] *)) { + color:inherit; + font-size:.875em + } + .prose :where(h3 code):not(:where([class~=not-prose] *)) { + color:inherit; + font-size:.9em + } + .prose :where(h4 code):not(:where([class~=not-prose] *)) { + color:inherit + } + .prose :where(blockquote code):not(:where([class~=not-prose] *)) { + color:inherit + } + .prose :where(thead th code):not(:where([class~=not-prose] *)) { + color:inherit + } + /* .prose :where(pre):not(:where([class~=not-prose] *)) { + background-color:transparent; + border-radius:.375rem; + color:currentColor; + font-size:.875em; + font-weight:400; + line-height:1.7142857; + margin:0; + overflow-x:auto; + padding:0 + } */ + .prose :where(pre code):not(:where([class~=not-prose] *)) { + background-color:transparent; + border-radius:0; + border-width:0; + color:inherit; + font-family:inherit; + font-size:inherit; + font-weight:inherit; + line-height:inherit; + padding:0 + } + .prose :where(pre code):not(:where([class~=not-prose] *)):before { + content:none + } + .prose :where(pre code):not(:where([class~=not-prose] *)):after { + content:none + } + +/* :not(pre) > code.hljs, +:not(pre) > code[class*='language-'] { + border-radius: 0.3em; + white-space: normal; +} +.hljs-comment { + color: hsla(0, 0%, 100%, 0.5); +} +.hljs-meta { + color: hsla(0, 0%, 100%, 0.6); +} +.hljs-built_in, +.hljs-class .hljs-title { + color: #e9950c; +} +.hljs-doctag, +.hljs-formula, +.hljs-keyword, +.hljs-literal { + color: #2e95d3; +} +.hljs-addition, +.hljs-attribute, +.hljs-meta-string, +.hljs-regexp, +.hljs-string { + color: #00a67d; +} +.hljs-attr, +.hljs-number, +.hljs-selector-attr, +.hljs-selector-class, +.hljs-selector-pseudo, +.hljs-template-variable, +.hljs-type, +.hljs-variable { + color: #df3079; +} +.hljs-bullet, +.hljs-link, +.hljs-selector-id, +.hljs-symbol, +.hljs-title { + color: #f22c3d; +} */ + .prose { color:var(--tw-prose-body); max-width:65ch @@ -125,7 +356,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { .prose :where([class~=lead]):not(:where([class~=not-prose] *)) { color:var(--tw-prose-lead); font-size:1.25em; - line-height:1.6; + /* line-height:1.6; */ margin-bottom:1.2em; margin-top:1.2em } @@ -186,13 +417,13 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { margin-top:1.25em; padding-left:1.625em } - .prose :where(ol>li):not(:where([class~=not-prose] *))::marker { + /* .prose :where(ol>li):not(:where([class~=not-prose] *))::marker { color:var(--tw-prose-counters); font-weight:400 } .prose :where(ul>li):not(:where([class~=not-prose] *))::marker { color:var(--tw-prose-bullets) - } + } */ .prose :where(hr):not(:where([class~=not-prose] *)) { border-color:var(--tw-prose-hr); border-top-width:1px; @@ -245,7 +476,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { color:var(--tw-prose-headings); font-size:1.25em; font-weight:600; - line-height:1.6; + /* line-height:1.6; */ margin-bottom:.6em; margin-top:1.6em } @@ -256,7 +487,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { .prose :where(h4):not(:where([class~=not-prose] *)) { color:var(--tw-prose-headings); font-weight:600; - line-height:1.5; + /* line-height:1.5; */ margin-bottom:.5em; margin-top:1.5em } @@ -275,7 +506,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { .prose :where(figcaption):not(:where([class~=not-prose] *)) { color:var(--tw-prose-captions); font-size:.875em; - line-height:1.4285714; + /* line-height:1.4285714; */ margin-top:.8571429em } .prose :where(code):not(:where([class~=not-prose] *)) { @@ -318,7 +549,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { color:currentColor; font-size:.875em; font-weight:400; - line-height:1.7142857; + /* line-height:1.7142857; */ margin:0; overflow-x:auto; padding:0 @@ -342,7 +573,7 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { } .prose :where(table):not(:where([class~=not-prose] *)) { font-size:.875em; - line-height:1.7142857; + /* line-height:1.7142857; */ margin-bottom:2em; margin-top:2em; table-layout:auto; @@ -378,46 +609,10 @@ blockquote, dd, dl, fieldset, figure, h1, h2, h3, h4, h5, h6, hr, p, pre { .prose :where(tfoot td):not(:where([class~=not-prose] *)) { vertical-align:top } - .prose { - --tw-prose-body:#374151; - --tw-prose-headings:#111827; - --tw-prose-lead:#4b5563; - --tw-prose-links:#111827; - --tw-prose-bold:#111827; - --tw-prose-counters:#6b7280; - --tw-prose-bullets:#d1d5db; - --tw-prose-hr:#e5e7eb; - --tw-prose-quotes:#111827; - --tw-prose-quote-borders:#e5e7eb; - --tw-prose-captions:#6b7280; - --tw-prose-code:#111827; - --tw-prose-pre-code:#e5e7eb; - --tw-prose-pre-bg:#1f2937; - --tw-prose-th-borders:#d1d5db; - --tw-prose-td-borders:#e5e7eb; - --tw-prose-invert-body:#d1d5db; - --tw-prose-invert-headings:#fff; - --tw-prose-invert-lead:#9ca3af; - --tw-prose-invert-links:#fff; - --tw-prose-invert-bold:#fff; - --tw-prose-invert-counters:#9ca3af; - --tw-prose-invert-bullets:#4b5563; - --tw-prose-invert-hr:#374151; - --tw-prose-invert-quotes:#f3f4f6; - --tw-prose-invert-quote-borders:#374151; - --tw-prose-invert-captions:#9ca3af; - --tw-prose-invert-code:#fff; - --tw-prose-invert-pre-code:#d1d5db; - --tw-prose-invert-pre-bg:rgba(0,0,0,.5); - --tw-prose-invert-th-borders:#4b5563; - --tw-prose-invert-td-borders:#374151; - font-size:1rem; - line-height:1.75 - } - .prose :where(p):not(:where([class~=not-prose] *)) { + /* .prose :where(p):not(:where([class~=not-prose] *)) { margin-bottom:1.25em; margin-top:1.25em - } + } */ .prose :where(video):not(:where([class~=not-prose] *)) { margin-bottom:2em; margin-top:2em @@ -941,6 +1136,8 @@ html { display: flex; flex-direction: column; padding-left: 1rem; + margin-top: 0; + margin-bottom: 0; } .markdown ol { @@ -1796,7 +1993,11 @@ html { .markdown ul { display:flex; flex-direction:column; - padding-left:1rem + padding-left:1rem; + margin: 0; +} +.markdown ul::marker { + margin-top: 1.55rem; } .markdown ol li, .markdown ol li>p,