mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-02 18:39:05 +01:00
Make textAtom and showTocAtom in Markdown element optional (#331)
Fix backwards-compatibility for the Markdown element by adding back the option to pass text directly to the element and make atom parameters optional.
This commit is contained in:
parent
fc5e53e476
commit
015ebf5dd5
@ -8,7 +8,8 @@ import ReactMarkdown from "react-markdown";
|
||||
import rehypeRaw from "rehype-raw";
|
||||
import remarkGfm from "remark-gfm";
|
||||
|
||||
import { Atom, useAtomValue } from "jotai";
|
||||
import { useAtomValueSafe } from "@/util/util";
|
||||
import { Atom } from "jotai";
|
||||
import { OverlayScrollbarsComponent } from "overlayscrollbars-react";
|
||||
import RemarkFlexibleToc, { TocItem } from "remark-flexible-toc";
|
||||
import { useHeight } from "../hook/useHeight";
|
||||
@ -75,17 +76,18 @@ const CodeBlock = ({ children, onClickExecute }: CodeBlockProps) => {
|
||||
};
|
||||
|
||||
type MarkdownProps = {
|
||||
textAtom: Atom<string> | Atom<Promise<string>>;
|
||||
showTocAtom: Atom<boolean>;
|
||||
text?: string;
|
||||
textAtom?: Atom<string> | Atom<Promise<string>>;
|
||||
showTocAtom?: Atom<boolean>;
|
||||
style?: React.CSSProperties;
|
||||
className?: string;
|
||||
onClickExecute?: (cmd: string) => void;
|
||||
};
|
||||
|
||||
const Markdown = ({ textAtom, showTocAtom, style, className, onClickExecute }: MarkdownProps) => {
|
||||
const text = useAtomValue(textAtom);
|
||||
const Markdown = ({ text, textAtom, showTocAtom, style, className, onClickExecute }: MarkdownProps) => {
|
||||
const textAtomValue = useAtomValueSafe(textAtom);
|
||||
const tocRef = useRef<TocItem[]>([]);
|
||||
const showToc = useAtomValue(showTocAtom);
|
||||
const showToc = useAtomValueSafe(showTocAtom) ?? false;
|
||||
const contentsRef = useRef<HTMLDivElement>(null);
|
||||
const contentsHeight = useHeight(contentsRef, 200);
|
||||
|
||||
@ -133,6 +135,8 @@ const Markdown = ({ textAtom, showTocAtom, style, className, onClickExecute }: M
|
||||
}
|
||||
}, [showToc, tocRef]);
|
||||
|
||||
text = textAtomValue ?? text;
|
||||
|
||||
return (
|
||||
<div className={clsx("markdown", className)} style={style} ref={contentsRef}>
|
||||
<OverlayScrollbarsComponent
|
||||
|
@ -5,17 +5,18 @@ import { Modal } from "@/app/modals/modal";
|
||||
import { Markdown } from "@/element/markdown";
|
||||
import { modalsModel } from "@/store/modalmodel";
|
||||
import * as keyutil from "@/util/keyutil";
|
||||
import * as React from "react";
|
||||
import { UserInputService } from "../store/services";
|
||||
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import "./userinputmodal.less";
|
||||
|
||||
const UserInputModal = (userInputRequest: UserInputRequest) => {
|
||||
const [responseText, setResponseText] = React.useState("");
|
||||
const [countdown, setCountdown] = React.useState(Math.floor(userInputRequest.timeoutms / 1000));
|
||||
const checkboxStatus = React.useRef(false);
|
||||
const [responseText, setResponseText] = useState("");
|
||||
const [countdown, setCountdown] = useState(Math.floor(userInputRequest.timeoutms / 1000));
|
||||
const checkboxStatus = useRef(false);
|
||||
const queryTextAtom = useState;
|
||||
|
||||
const handleSendCancel = React.useCallback(() => {
|
||||
const handleSendCancel = useCallback(() => {
|
||||
UserInputService.SendUserInputResponse({
|
||||
type: "userinputresp",
|
||||
requestid: userInputRequest.requestid,
|
||||
@ -24,7 +25,7 @@ const UserInputModal = (userInputRequest: UserInputRequest) => {
|
||||
modalsModel.popModal();
|
||||
}, [responseText, userInputRequest]);
|
||||
|
||||
const handleSendText = React.useCallback(() => {
|
||||
const handleSendText = useCallback(() => {
|
||||
UserInputService.SendUserInputResponse({
|
||||
type: "userinputresp",
|
||||
requestid: userInputRequest.requestid,
|
||||
@ -34,7 +35,7 @@ const UserInputModal = (userInputRequest: UserInputRequest) => {
|
||||
modalsModel.popModal();
|
||||
}, [responseText, userInputRequest]);
|
||||
|
||||
const handleSendConfirm = React.useCallback(() => {
|
||||
const handleSendConfirm = useCallback(() => {
|
||||
UserInputService.SendUserInputResponse({
|
||||
type: "userinputresp",
|
||||
requestid: userInputRequest.requestid,
|
||||
@ -44,7 +45,7 @@ const UserInputModal = (userInputRequest: UserInputRequest) => {
|
||||
modalsModel.popModal();
|
||||
}, [userInputRequest]);
|
||||
|
||||
const handleSubmit = React.useCallback(() => {
|
||||
const handleSubmit = useCallback(() => {
|
||||
switch (userInputRequest.responsetype) {
|
||||
case "text":
|
||||
handleSendText();
|
||||
@ -55,7 +56,7 @@ const UserInputModal = (userInputRequest: UserInputRequest) => {
|
||||
}
|
||||
}, [handleSendConfirm, handleSendText, userInputRequest.responsetype]);
|
||||
|
||||
const handleKeyDown = React.useCallback(
|
||||
const handleKeyDown = useCallback(
|
||||
(waveEvent: WaveKeyboardEvent): boolean => {
|
||||
if (keyutil.checkKeyPressed(waveEvent, "Escape")) {
|
||||
handleSendCancel();
|
||||
@ -69,14 +70,14 @@ const UserInputModal = (userInputRequest: UserInputRequest) => {
|
||||
[handleSendCancel, handleSubmit]
|
||||
);
|
||||
|
||||
const queryText = React.useMemo(() => {
|
||||
const queryText = useMemo(() => {
|
||||
if (userInputRequest.markdown) {
|
||||
return <Markdown text={userInputRequest.querytext} className="userinput-markdown" />;
|
||||
}
|
||||
return <span className="userinput-text">{userInputRequest.querytext}</span>;
|
||||
}, [userInputRequest.markdown, userInputRequest.querytext]);
|
||||
|
||||
const inputBox = React.useMemo(() => {
|
||||
const inputBox = useMemo(() => {
|
||||
if (userInputRequest.responsetype === "confirm") {
|
||||
return <></>;
|
||||
}
|
||||
@ -93,7 +94,7 @@ const UserInputModal = (userInputRequest: UserInputRequest) => {
|
||||
);
|
||||
}, [userInputRequest.responsetype, userInputRequest.publictext, responseText, handleKeyDown, setResponseText]);
|
||||
|
||||
React.useEffect(() => {
|
||||
useEffect(() => {
|
||||
let timeout: ReturnType<typeof setTimeout>;
|
||||
if (countdown == 0) {
|
||||
timeout = setTimeout(() => {
|
||||
|
@ -180,8 +180,6 @@ Other useful metadata values to override block titles, icons, colors, themes, et
|
||||
|
||||
`;
|
||||
|
||||
const helpTextAtom = atom(helpText);
|
||||
|
||||
class HelpViewModel implements ViewModel {
|
||||
viewType: string;
|
||||
showTocAtom: PrimitiveAtom<boolean>;
|
||||
@ -210,7 +208,7 @@ function makeHelpViewModel() {
|
||||
}
|
||||
|
||||
function HelpView({ model }: { model: HelpViewModel }) {
|
||||
return <Markdown textAtom={helpTextAtom} showTocAtom={model.showTocAtom} className="help-view" />;
|
||||
return <Markdown text={helpText} showTocAtom={model.showTocAtom} className="help-view" />;
|
||||
}
|
||||
|
||||
export { HelpView, HelpViewModel, makeHelpViewModel };
|
||||
|
@ -11,7 +11,7 @@ import { isBlank } from "@/util/util";
|
||||
import { atom, Atom, PrimitiveAtom, useAtomValue, useSetAtom, WritableAtom } from "jotai";
|
||||
import type { OverlayScrollbars } from "overlayscrollbars";
|
||||
import { OverlayScrollbarsComponent, OverlayScrollbarsComponentRef } from "overlayscrollbars-react";
|
||||
import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from "react";
|
||||
import { forwardRef, memo, useCallback, useEffect, useImperativeHandle, useRef, useState } from "react";
|
||||
import tinycolor from "tinycolor2";
|
||||
import "./waveai.less";
|
||||
|
||||
@ -217,11 +217,8 @@ function makeWaveAiViewModel(blockId): WaveAiModel {
|
||||
return waveAiModel;
|
||||
}
|
||||
|
||||
const showTocAtomDummy = atom(false);
|
||||
|
||||
const ChatItem = ({ chatItem, itemCount }: ChatItemProps) => {
|
||||
const { isAssistant, text, isError } = chatItem;
|
||||
const textAtom = useMemo(() => atom(text), [text]);
|
||||
const senderClassName = isAssistant ? "chat-msg-assistant" : "chat-msg-user";
|
||||
const msgClassName = `chat-msg ${senderClassName}`;
|
||||
const cssVar = "--panel-bg-color";
|
||||
@ -242,7 +239,7 @@ const ChatItem = ({ chatItem, itemCount }: ChatItemProps) => {
|
||||
<div className="chat-msg-header">
|
||||
<i className="fa-sharp fa-solid fa-sparkles"></i>
|
||||
</div>
|
||||
<Markdown textAtom={textAtom} showTocAtom={showTocAtomDummy} />
|
||||
<Markdown text={text} />
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
@ -258,7 +255,7 @@ const ChatItem = ({ chatItem, itemCount }: ChatItemProps) => {
|
||||
<div className="chat-msg-header">
|
||||
<i className="fa-sharp fa-solid fa-user"></i>
|
||||
</div>
|
||||
<Markdown className="msg-text" textAtom={textAtom} showTocAtom={showTocAtomDummy} />
|
||||
<Markdown className="msg-text" text={text} />
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -163,7 +163,7 @@ function jotaiLoadableValue<T>(value: Loadable<T>, def: T): T {
|
||||
|
||||
const NullAtom = atom(null);
|
||||
|
||||
function useAtomValueSafe<T>(atom: Atom<T>): T {
|
||||
function useAtomValueSafe<T>(atom: Atom<T> | Atom<Promise<T>>): T {
|
||||
if (atom == null) {
|
||||
return useAtomValue(NullAtom) as T;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user