web: add editor virtualization toggle in settings

This commit is contained in:
Ammar Ahmed
2026-08-25 11:40:12 +05:00
parent b88a5bdac8
commit 15f5d87717
3 changed files with 39 additions and 3 deletions

View File

@@ -115,6 +115,7 @@ type TipTapProps = {
dayFormat: DayFormat;
markdownShortcuts: boolean;
fontLigatures: boolean;
virtualization: boolean;
};
function countCharacters(text: string) {
@@ -190,7 +191,8 @@ function TipTap(props: TipTapProps) {
timeFormat,
dayFormat,
markdownShortcuts,
fontLigatures
fontLigatures,
virtualization
} = props;
const autoSave = useRef(true);
@@ -268,6 +270,7 @@ function TipTap(props: TipTapProps) {
},
enableInputRules: markdownShortcuts,
enableFontLigatures: fontLigatures,
virtualization,
downloadOptions,
doubleSpacedLines,
dateFormat,
@@ -493,7 +496,8 @@ function TipTap(props: TipTapProps) {
timeFormat,
dayFormat,
markdownShortcuts,
fontLigatures
fontLigatures,
virtualization
]);
const editor = useTiptap(
@@ -600,6 +604,7 @@ function TiptapWrapper(
| "dayFormat"
| "markdownShortcuts"
| "fontLigatures"
| "virtualization"
>
> & {
isHydrating?: boolean;
@@ -619,6 +624,9 @@ function TiptapWrapper(
(store) => store.markdownShortcuts
);
const fontLigatures = useSettingsStore((store) => store.fontLigatures);
const virtualization = useSettingsStore(
(store) => store.editorVirtualization
);
const containerRef = useRef<HTMLDivElement>(null);
const editorContainerRef = useRef<HTMLDivElement>();
const { editorConfig, setEditorConfig } = useEditorConfig();
@@ -706,7 +714,11 @@ function TiptapWrapper(
}}
>
<TipTap
key={`tiptap-${props.id}-${doubleSpacedLines}-${dateFormat}-${timeFormat}-${dayFormat}-${markdownShortcuts}-${fontLigatures}`}
// `virtualization` must stay in this key. useEditor creates the
// Editor instance once and only rebuilds its view afterwards, so
// extension options are frozen at construction — toggling paging only
// takes effect when the whole component remounts.
key={`tiptap-${props.id}-${doubleSpacedLines}-${dateFormat}-${timeFormat}-${dayFormat}-${markdownShortcuts}-${fontLigatures}-${virtualization}`}
{...props}
isMobile={isMobile}
isTablet={isTablet}
@@ -716,6 +728,7 @@ function TiptapWrapper(
dayFormat={dayFormat}
markdownShortcuts={markdownShortcuts}
fontLigatures={fontLigatures}
virtualization={virtualization}
onLoad={(editor) => {
if (!isHydrating) {
onLoad?.(editor);

View File

@@ -156,6 +156,21 @@ export const EditorSettings: SettingsGroup[] = [
toggle: () => useSettingStore.getState().toggleFontLigatures()
}
]
},
{
key: "editor-virtualization",
title: strings.editorVirtualization(),
description: strings.editorVirtualizationDesc(),
onStateChange: (listener) =>
useSettingStore.subscribe((c) => c.editorVirtualization, listener),
components: [
{
type: "toggle",
isToggled: () => useSettingStore.getState().editorVirtualization,
toggle: () =>
useSettingStore.getState().toggleEditorVirtualization()
}
]
}
]
},

View File

@@ -57,6 +57,7 @@ class SettingStore extends BaseStore<SettingStore> {
doubleSpacedParagraphs = Config.get("doubleSpacedLines", true);
markdownShortcuts = Config.get("markdownShortcuts", false);
fontLigatures = Config.get("fontLigatures", false);
editorVirtualization = Config.get("editorVirtualization", false);
notificationsSettings = Config.get("notifications", { reminder: true });
isFullOfflineMode = Config.get("fullOfflineMode", false);
serverUrls: Partial<Record<HostId, string>> = Config.get("serverUrls", {});
@@ -250,6 +251,13 @@ class SettingStore extends BaseStore<SettingStore> {
Config.set("fontLigatures", !fontLigatures);
};
toggleEditorVirtualization = (toggleState?: boolean) => {
const editorVirtualization = this.get().editorVirtualization;
const next = toggleState ?? !editorVirtualization;
this.set((state) => (state.editorVirtualization = next));
Config.set("editorVirtualization", next);
};
togglePrivacyMode = async () => {
const privacyMode = this.get().privacyMode;
this.set({ privacyMode: !privacyMode });