+
{completion}
diff --git a/web/src/components/editor/index.tsx b/web/src/components/editor/index.tsx
index ac26c6f..1896dab 100644
--- a/web/src/components/editor/index.tsx
+++ b/web/src/components/editor/index.tsx
@@ -38,12 +38,12 @@ const extensions = [...defaultExtensions, slashCommand];
export interface ReportEditorProps {
content: Content;
+ onMarkdownChange?: (markdown: string) => void;
}
-const ReportEditor = ({ content }: ReportEditorProps) => {
+const ReportEditor = ({ content, onMarkdownChange }: ReportEditorProps) => {
const [initialContent, setInitialContent] = useState
(() => content);
const [saveStatus, setSaveStatus] = useState("Saved");
- const [charsCount, setCharsCount] = useState();
const [openNode, setOpenNode] = useState(false);
const [openColor, setOpenColor] = useState(false);
@@ -63,17 +63,21 @@ const ReportEditor = ({ content }: ReportEditorProps) => {
const debouncedUpdates = useDebouncedCallback(
async (editor: EditorInstance) => {
- const json = editor.getJSON();
- setCharsCount(editor.storage.characterCount.words());
- window.localStorage.setItem(
- "html-content",
- highlightCodeblocks(editor.getHTML()),
- );
- window.localStorage.setItem("novel-content", JSON.stringify(json));
- window.localStorage.setItem(
- "markdown",
- editor.storage.markdown.getMarkdown(),
- );
+ // const json = editor.getJSON();
+ // // setCharsCount(editor.storage.characterCount.words());
+ // window.localStorage.setItem(
+ // "html-content",
+ // highlightCodeblocks(editor.getHTML()),
+ // );
+ // window.localStorage.setItem("novel-content", JSON.stringify(json));
+ // window.localStorage.setItem(
+ // "markdown",
+ // editor.storage.markdown.getMarkdown(),
+ // );
+ if (onMarkdownChange) {
+ const markdown = editor.storage.markdown.getMarkdown();
+ onMarkdownChange(markdown);
+ }
setSaveStatus("Saved");
},
500,
@@ -89,26 +93,12 @@ const ReportEditor = ({ content }: ReportEditorProps) => {
return (
-
-
- {saveStatus}
-
-
- {charsCount} Words
-
-
handleCommandNavigation(event),
diff --git a/web/src/components/editor/slash-command.tsx b/web/src/components/editor/slash-command.tsx
index 4a69435..f24c5ff 100644
--- a/web/src/components/editor/slash-command.tsx
+++ b/web/src/components/editor/slash-command.tsx
@@ -1,32 +1,18 @@
import {
- Brain,
CheckSquare,
Code,
Heading1,
Heading2,
Heading3,
- ImageIcon,
List,
ListOrdered,
- MessageSquarePlus,
Text,
TextQuote,
- Twitter,
- Youtube,
} from "lucide-react";
import { Command, createSuggestionItems, renderItems } from "novel";
-import { uploadFn } from "./image-upload";
+// import { uploadFn } from "./image-upload";
export const suggestionItems = createSuggestionItems([
- {
- title: "Send Feedback",
- description: "Let us know how we can improve.",
- icon: ,
- command: ({ editor, range }) => {
- editor.chain().focus().deleteRange(range).run();
- window.open("/feedback", "_blank");
- },
- },
{
title: "Text",
description: "Just start typing with plain text.",
@@ -132,83 +118,83 @@ export const suggestionItems = createSuggestionItems([
command: ({ editor, range }) =>
editor.chain().focus().deleteRange(range).toggleCodeBlock().run(),
},
- {
- title: "Image",
- description: "Upload an image from your computer.",
- searchTerms: ["photo", "picture", "media"],
- icon: ,
- command: ({ editor, range }) => {
- editor.chain().focus().deleteRange(range).run();
- // upload image
- const input = document.createElement("input");
- input.type = "file";
- input.accept = "image/*";
- input.onchange = async () => {
- if (input.files?.length) {
- const file = input.files[0];
- if (!file) return;
- const pos = editor.view.state.selection.from;
- uploadFn(file, editor.view, pos);
- }
- };
- input.click();
- },
- },
- {
- title: "Youtube",
- description: "Embed a Youtube video.",
- searchTerms: ["video", "youtube", "embed"],
- icon: ,
- command: ({ editor, range }) => {
- const videoLink = prompt("Please enter Youtube Video Link");
- //From https://regexr.com/3dj5t
- const ytRegex = new RegExp(
- /^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|v\/)?)([\w\-]+)(\S+)?$/,
- );
+ // {
+ // title: "Image",
+ // description: "Upload an image from your computer.",
+ // searchTerms: ["photo", "picture", "media"],
+ // icon: ,
+ // command: ({ editor, range }) => {
+ // editor.chain().focus().deleteRange(range).run();
+ // // upload image
+ // const input = document.createElement("input");
+ // input.type = "file";
+ // input.accept = "image/*";
+ // input.onchange = async () => {
+ // if (input.files?.length) {
+ // const file = input.files[0];
+ // if (!file) return;
+ // const pos = editor.view.state.selection.from;
+ // uploadFn(file, editor.view, pos);
+ // }
+ // };
+ // input.click();
+ // },
+ // },
+ // {
+ // title: "Youtube",
+ // description: "Embed a Youtube video.",
+ // searchTerms: ["video", "youtube", "embed"],
+ // icon: ,
+ // command: ({ editor, range }) => {
+ // const videoLink = prompt("Please enter Youtube Video Link");
+ // //From https://regexr.com/3dj5t
+ // const ytRegex = new RegExp(
+ // /^((?:https?:)?\/\/)?((?:www|m)\.)?((?:youtube\.com|youtu.be))(\/(?:[\w\-]+\?v=|embed\/|v\/)?)([\w\-]+)(\S+)?$/,
+ // );
- if (videoLink && ytRegex.test(videoLink)) {
- editor
- .chain()
- .focus()
- .deleteRange(range)
- .setYoutubeVideo({
- src: videoLink,
- })
- .run();
- } else {
- if (videoLink !== null) {
- alert("Please enter a correct Youtube Video Link");
- }
- }
- },
- },
- {
- title: "Twitter",
- description: "Embed a Tweet.",
- searchTerms: ["twitter", "embed"],
- icon: ,
- command: ({ editor, range }) => {
- const tweetLink = prompt("Please enter Twitter Link");
- const tweetRegex = new RegExp(
- /^https?:\/\/(www\.)?x\.com\/([a-zA-Z0-9_]{1,15})(\/status\/(\d+))?(\/\S*)?$/,
- );
+ // if (videoLink && ytRegex.test(videoLink)) {
+ // editor
+ // .chain()
+ // .focus()
+ // .deleteRange(range)
+ // .setYoutubeVideo({
+ // src: videoLink,
+ // })
+ // .run();
+ // } else {
+ // if (videoLink !== null) {
+ // alert("Please enter a correct Youtube Video Link");
+ // }
+ // }
+ // },
+ // },
+ // {
+ // title: "Twitter",
+ // description: "Embed a Tweet.",
+ // searchTerms: ["twitter", "embed"],
+ // icon: ,
+ // command: ({ editor, range }) => {
+ // const tweetLink = prompt("Please enter Twitter Link");
+ // const tweetRegex = new RegExp(
+ // /^https?:\/\/(www\.)?x\.com\/([a-zA-Z0-9_]{1,15})(\/status\/(\d+))?(\/\S*)?$/,
+ // );
- if (tweetLink && tweetRegex.test(tweetLink)) {
- editor
- .chain()
- .focus()
- .deleteRange(range)
- .setTweet({
- src: tweetLink,
- })
- .run();
- } else {
- if (tweetLink !== null) {
- alert("Please enter a correct Twitter Link");
- }
- }
- },
- },
+ // if (tweetLink && tweetRegex.test(tweetLink)) {
+ // editor
+ // .chain()
+ // .focus()
+ // .deleteRange(range)
+ // .setTweet({
+ // src: tweetLink,
+ // })
+ // .run();
+ // } else {
+ // if (tweetLink !== null) {
+ // alert("Please enter a correct Twitter Link");
+ // }
+ // }
+ // },
+ // },
]);
export const slashCommand = Command.configure({
diff --git a/web/src/core/api/chat.ts b/web/src/core/api/chat.ts
index 6e04483..3f25edc 100644
--- a/web/src/core/api/chat.ts
+++ b/web/src/core/api/chat.ts
@@ -30,7 +30,7 @@ export async function* chatStream(
options: { abortSignal?: AbortSignal } = {},
) {
if (location.search.includes("mock") || location.search.includes("replay=")) {
- return chatReplayStream(userMessage, params, options);
+ return yield* chatReplayStream(userMessage, params, options);
}
const stream = fetchStream(resolveServiceURL("chat/stream"), {
body: JSON.stringify({
diff --git a/web/src/styles/globals.css b/web/src/styles/globals.css
index c4b0047..8390da8 100644
--- a/web/src/styles/globals.css
+++ b/web/src/styles/globals.css
@@ -201,94 +201,6 @@ textarea {
outline: none;
}
-.markdown {
- line-height: 1.75;
-
- a {
- text-decoration: underline;
- text-decoration-style: dotted;
- text-underline-position: from-font;
- text-decoration-color: var(--muted-foreground);
-
- &:hover {
- text-decoration: underline;
- }
- }
-
- h1 {
- @apply text-2xl font-bold;
- margin-top: 0.5rem;
- margin-bottom: 0.5rem;
- }
-
- h2 {
- @apply text-xl font-bold;
- margin-top: 0.5rem;
- margin-bottom: 0.5rem;
- }
-
- h3 {
- @apply text-lg font-bold;
- margin-top: 0.5rem;
- margin-bottom: 0.5rem;
- }
-
- h4 {
- @apply text-base font-bold;
- margin-bottom: 0.5rem;
- }
-
- h5 {
- @apply text-sm font-bold;
- }
-
- h6 {
- @apply text-xs font-bold;
- }
-
- ul {
- @apply list-disc pl-4;
- }
-
- ol {
- @apply list-decimal pl-4;
- }
-
- img {
- display: block;
- max-width: 100%;
- margin: 0 auto;
- }
-
- table {
- @apply w-full;
- table-layout: fixed;
- border-collapse: collapse;
-
- th,
- td {
- padding: 4px 8px;
- border: 1px solid var(--border);
- }
-
- th {
- @apply bg-muted;
- }
- }
-
- code:not([class*="language-"]) {
- @apply bg-muted;
- @apply rounded-md;
- @apply px-1;
- @apply py-0.5;
- @apply border;
- }
-
- blockquote {
- @apply border-muted-foreground text-muted-foreground border-l-2 pl-2;
- }
-}
-
@layer base {
* {
@apply border-border outline-ring/50;
diff --git a/web/src/styles/prosemirror.css b/web/src/styles/prosemirror.css
index 1f3b40e..53ed927 100644
--- a/web/src/styles/prosemirror.css
+++ b/web/src/styles/prosemirror.css
@@ -1,7 +1,6 @@
@import "./globals.css";
.ProseMirror {
- @apply p-12 px-8 sm:px-12;
}
.ProseMirror .is-editor-empty:first-child::before {