Extra Font Size Controls (#1537)

This adds:
- "editor:fontsize" to modify the code editor's font size
- "ai:fontsize" to modify the ai widget's font size (for general text)
- "ai:fixedfontsize" to modify the ai widget's fixed font size (for code
fragments)
This commit is contained in:
Sylvie Crowe 2024-12-16 18:23:42 -08:00 committed by GitHub
parent 8a5ef4cb3e
commit 71961b373f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 61 additions and 25 deletions

View File

@ -122,6 +122,7 @@ export function CodeEditor({ blockId, text, language, filename, meta, onChange,
const minimapEnabled = useOverrideConfigAtom(blockId, "editor:minimapenabled") ?? false; const minimapEnabled = useOverrideConfigAtom(blockId, "editor:minimapenabled") ?? false;
const stickyScrollEnabled = useOverrideConfigAtom(blockId, "editor:stickyscrollenabled") ?? false; const stickyScrollEnabled = useOverrideConfigAtom(blockId, "editor:stickyscrollenabled") ?? false;
const wordWrap = useOverrideConfigAtom(blockId, "editor:wordwrap") ?? false; const wordWrap = useOverrideConfigAtom(blockId, "editor:wordwrap") ?? false;
const fontSize = useOverrideConfigAtom(blockId, "editor:fontsize");
const theme = "wave-theme-dark"; const theme = "wave-theme-dark";
React.useEffect(() => { React.useEffect(() => {
@ -150,8 +151,9 @@ export function CodeEditor({ blockId, text, language, filename, meta, onChange,
opts.minimap.enabled = minimapEnabled; opts.minimap.enabled = minimapEnabled;
opts.stickyScroll.enabled = stickyScrollEnabled; opts.stickyScroll.enabled = stickyScrollEnabled;
opts.wordWrap = wordWrap ? "on" : "off"; opts.wordWrap = wordWrap ? "on" : "off";
opts.fontSize = fontSize;
return opts; return opts;
}, [minimapEnabled, stickyScrollEnabled, wordWrap]); }, [minimapEnabled, stickyScrollEnabled, wordWrap, fontSize]);
return ( return (
<div className="code-editor-wrapper"> <div className="code-editor-wrapper">

View File

@ -8,7 +8,7 @@ import { RpcResponseHelper, WshClient } from "@/app/store/wshclient";
import { RpcApi } from "@/app/store/wshclientapi"; import { RpcApi } from "@/app/store/wshclientapi";
import { makeFeBlockRouteId } from "@/app/store/wshrouter"; import { makeFeBlockRouteId } from "@/app/store/wshrouter";
import { DefaultRouter, TabRpcClient } from "@/app/store/wshrpcutil"; import { DefaultRouter, TabRpcClient } from "@/app/store/wshrpcutil";
import { atoms, createBlock, fetchWaveFile, getApi, globalStore, WOS } from "@/store/global"; import { atoms, createBlock, fetchWaveFile, getApi, globalStore, useOverrideConfigAtom, WOS } from "@/store/global";
import { BlockService, ObjectService } from "@/store/services"; import { BlockService, ObjectService } from "@/store/services";
import { adaptFromReactOrNativeKeyEvent, checkKeyPressed } from "@/util/keyutil"; import { adaptFromReactOrNativeKeyEvent, checkKeyPressed } from "@/util/keyutil";
import { fireAndForget, isBlank, makeIconClass } from "@/util/util"; import { fireAndForget, isBlank, makeIconClass } from "@/util/util";
@ -30,6 +30,7 @@ const slidingWindowSize = 30;
interface ChatItemProps { interface ChatItemProps {
chatItem: ChatMessageType; chatItem: ChatMessageType;
model: WaveAiModel;
} }
function promptToMsg(prompt: OpenAIPromptMessageType): ChatMessageType { function promptToMsg(prompt: OpenAIPromptMessageType): ChatMessageType {
@ -430,11 +431,12 @@ function makeWaveAiViewModel(blockId: string): WaveAiModel {
return waveAiModel; return waveAiModel;
} }
const ChatItem = ({ chatItem }: ChatItemProps) => { const ChatItem = ({ chatItem, model }: ChatItemProps) => {
const { user, text } = chatItem; const { user, text } = chatItem;
const cssVar = "--panel-bg-color"; const cssVar = "--panel-bg-color";
const panelBgColor = getComputedStyle(document.documentElement).getPropertyValue(cssVar).trim(); const panelBgColor = getComputedStyle(document.documentElement).getPropertyValue(cssVar).trim();
const fontSize = useOverrideConfigAtom(model.blockId, "ai:fontsize");
const fixedFontSize = useOverrideConfigAtom(model.blockId, "ai:fixedfontsize");
const renderContent = useMemo(() => { const renderContent = useMemo(() => {
if (user == "error") { if (user == "error") {
return ( return (
@ -445,7 +447,12 @@ const ChatItem = ({ chatItem }: ChatItemProps) => {
</div> </div>
</div> </div>
<div className="chat-msg chat-msg-error"> <div className="chat-msg chat-msg-error">
<Markdown text={text} scrollable={false} /> <Markdown
text={text}
scrollable={false}
fontSizeOverride={fontSize}
fixedFontSizeOverride={fixedFontSize}
/>
</div> </div>
</> </>
); );
@ -459,7 +466,12 @@ const ChatItem = ({ chatItem }: ChatItemProps) => {
</div> </div>
</div> </div>
<div className="chat-msg chat-msg-assistant"> <div className="chat-msg chat-msg-assistant">
<Markdown text={text} scrollable={false} /> <Markdown
text={text}
scrollable={false}
fontSizeOverride={fontSize}
fixedFontSizeOverride={fixedFontSize}
/>
</div> </div>
</> </>
) : ( ) : (
@ -474,11 +486,17 @@ const ChatItem = ({ chatItem }: ChatItemProps) => {
return ( return (
<> <>
<div className="chat-msg chat-msg-user"> <div className="chat-msg chat-msg-user">
<Markdown className="msg-text" text={text} scrollable={false} /> <Markdown
className="msg-text"
text={text}
scrollable={false}
fontSizeOverride={fontSize}
fixedFontSizeOverride={fixedFontSize}
/>
</div> </div>
</> </>
); );
}, [text, user]); }, [text, user, fontSize, fixedFontSize]);
return <div className={"chat-msg-container"}>{renderContent}</div>; return <div className={"chat-msg-container"}>{renderContent}</div>;
}; };
@ -487,10 +505,11 @@ interface ChatWindowProps {
chatWindowRef: React.RefObject<HTMLDivElement>; chatWindowRef: React.RefObject<HTMLDivElement>;
messages: ChatMessageType[]; messages: ChatMessageType[];
msgWidths: Object; msgWidths: Object;
model: WaveAiModel;
} }
const ChatWindow = memo( const ChatWindow = memo(
forwardRef<OverlayScrollbarsComponentRef, ChatWindowProps>(({ chatWindowRef, messages, msgWidths }, ref) => { forwardRef<OverlayScrollbarsComponentRef, ChatWindowProps>(({ chatWindowRef, messages, msgWidths, model }, ref) => {
const [isUserScrolling, setIsUserScrolling] = useState(false); const [isUserScrolling, setIsUserScrolling] = useState(false);
const osRef = useRef<OverlayScrollbarsComponentRef>(null); const osRef = useRef<OverlayScrollbarsComponentRef>(null);
@ -559,7 +578,7 @@ const ChatWindow = memo(
<div ref={chatWindowRef} className="chat-window" style={msgWidths}> <div ref={chatWindowRef} className="chat-window" style={msgWidths}>
<div className="filler"></div> <div className="filler"></div>
{messages.map((chitem, idx) => ( {messages.map((chitem, idx) => (
<ChatItem key={idx} chatItem={chitem} /> <ChatItem key={idx} chatItem={chitem} model={model} />
))} ))}
</div> </div>
</OverlayScrollbarsComponent> </OverlayScrollbarsComponent>
@ -804,7 +823,13 @@ const WaveAi = ({ model }: { model: WaveAiModel; blockId: string }) => {
return ( return (
<div ref={waveaiRef} className="waveai"> <div ref={waveaiRef} className="waveai">
<div className="waveai-chat"> <div className="waveai-chat">
<ChatWindow ref={osRef} chatWindowRef={chatWindowRef} messages={messages} msgWidths={msgWidths} /> <ChatWindow
ref={osRef}
chatWindowRef={chatWindowRef}
messages={messages}
msgWidths={msgWidths}
model={model}
/>
</div> </div>
<div className="waveai-controls"> <div className="waveai-controls">
<div className="waveai-input-wrapper"> <div className="waveai-input-wrapper">

View File

@ -617,6 +617,8 @@ declare global {
"ai:apiversion"?: string; "ai:apiversion"?: string;
"ai:maxtokens"?: number; "ai:maxtokens"?: number;
"ai:timeoutms"?: number; "ai:timeoutms"?: number;
"ai:fontsize"?: number;
"ai:fixedfontsize"?: number;
"term:*"?: boolean; "term:*"?: boolean;
"term:fontsize"?: number; "term:fontsize"?: number;
"term:fontfamily"?: string; "term:fontfamily"?: string;
@ -629,6 +631,7 @@ declare global {
"editor:minimapenabled"?: boolean; "editor:minimapenabled"?: boolean;
"editor:stickyscrollenabled"?: boolean; "editor:stickyscrollenabled"?: boolean;
"editor:wordwrap"?: boolean; "editor:wordwrap"?: boolean;
"editor:fontsize"?: number;
"web:*"?: boolean; "web:*"?: boolean;
"web:openlinksinternally"?: boolean; "web:openlinksinternally"?: boolean;
"web:defaulturl"?: string; "web:defaulturl"?: string;

View File

@ -17,6 +17,8 @@ const (
ConfigKey_AIApiVersion = "ai:apiversion" ConfigKey_AIApiVersion = "ai:apiversion"
ConfigKey_AiMaxTokens = "ai:maxtokens" ConfigKey_AiMaxTokens = "ai:maxtokens"
ConfigKey_AiTimeoutMs = "ai:timeoutms" ConfigKey_AiTimeoutMs = "ai:timeoutms"
ConfigKey_AiFontSize = "ai:fontsize"
ConfigKey_AiFixedFontSize = "ai:fixedfontsize"
ConfigKey_TermClear = "term:*" ConfigKey_TermClear = "term:*"
ConfigKey_TermFontSize = "term:fontsize" ConfigKey_TermFontSize = "term:fontsize"
@ -31,6 +33,7 @@ const (
ConfigKey_EditorMinimapEnabled = "editor:minimapenabled" ConfigKey_EditorMinimapEnabled = "editor:minimapenabled"
ConfigKey_EditorStickyScrollEnabled = "editor:stickyscrollenabled" ConfigKey_EditorStickyScrollEnabled = "editor:stickyscrollenabled"
ConfigKey_EditorWordWrap = "editor:wordwrap" ConfigKey_EditorWordWrap = "editor:wordwrap"
ConfigKey_EditorFontSize = "editor:fontsize"
ConfigKey_WebClear = "web:*" ConfigKey_WebClear = "web:*"
ConfigKey_WebOpenLinksInternally = "web:openlinksinternally" ConfigKey_WebOpenLinksInternally = "web:openlinksinternally"

View File

@ -33,17 +33,19 @@ const AnySchema = `
` `
type SettingsType struct { type SettingsType struct {
AiClear bool `json:"ai:*,omitempty"` AiClear bool `json:"ai:*,omitempty"`
AiPreset string `json:"ai:preset,omitempty"` AiPreset string `json:"ai:preset,omitempty"`
AiApiType string `json:"ai:apitype,omitempty"` AiApiType string `json:"ai:apitype,omitempty"`
AiBaseURL string `json:"ai:baseurl,omitempty"` AiBaseURL string `json:"ai:baseurl,omitempty"`
AiApiToken string `json:"ai:apitoken,omitempty"` AiApiToken string `json:"ai:apitoken,omitempty"`
AiName string `json:"ai:name,omitempty"` AiName string `json:"ai:name,omitempty"`
AiModel string `json:"ai:model,omitempty"` AiModel string `json:"ai:model,omitempty"`
AiOrgID string `json:"ai:orgid,omitempty"` AiOrgID string `json:"ai:orgid,omitempty"`
AIApiVersion string `json:"ai:apiversion,omitempty"` AIApiVersion string `json:"ai:apiversion,omitempty"`
AiMaxTokens float64 `json:"ai:maxtokens,omitempty"` AiMaxTokens float64 `json:"ai:maxtokens,omitempty"`
AiTimeoutMs float64 `json:"ai:timeoutms,omitempty"` AiTimeoutMs float64 `json:"ai:timeoutms,omitempty"`
AiFontSize float64 `json:"ai:fontsize,omitempty"`
AiFixedFontSize float64 `json:"ai:fixedfontsize,omitempty"`
TermClear bool `json:"term:*,omitempty"` TermClear bool `json:"term:*,omitempty"`
TermFontSize float64 `json:"term:fontsize,omitempty"` TermFontSize float64 `json:"term:fontsize,omitempty"`
@ -55,9 +57,10 @@ type SettingsType struct {
TermScrollback *int64 `json:"term:scrollback,omitempty"` TermScrollback *int64 `json:"term:scrollback,omitempty"`
TermCopyOnSelect *bool `json:"term:copyonselect,omitempty"` TermCopyOnSelect *bool `json:"term:copyonselect,omitempty"`
EditorMinimapEnabled bool `json:"editor:minimapenabled,omitempty"` EditorMinimapEnabled bool `json:"editor:minimapenabled,omitempty"`
EditorStickyScrollEnabled bool `json:"editor:stickyscrollenabled,omitempty"` EditorStickyScrollEnabled bool `json:"editor:stickyscrollenabled,omitempty"`
EditorWordWrap bool `json:"editor:wordwrap,omitempty"` EditorWordWrap bool `json:"editor:wordwrap,omitempty"`
EditorFontSize float64 `json:"editor:fontsize,omitempty"`
WebClear bool `json:"web:*,omitempty"` WebClear bool `json:"web:*,omitempty"`
WebOpenLinksInternally bool `json:"web:openlinksinternally,omitempty"` WebOpenLinksInternally bool `json:"web:openlinksinternally,omitempty"`