mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
fix: Undo/redo events duplicated (#12525)
* fix: Undo/redo events duplicated * fix: Guard history use Prevent cross polination of editors * Remove unused check
This commit is contained in:
@@ -2,6 +2,7 @@ import { useCallback, useMemo, useState } from "react";
|
||||
import styled from "styled-components";
|
||||
import breakpoint from "styled-components-breakpoint";
|
||||
import * as Toolbar from "@radix-ui/react-toolbar";
|
||||
import { closeHistory } from "@shared/editor/lib/closeHistory";
|
||||
import type { MenuItem } from "@shared/editor/types";
|
||||
import { hideScrollbars, s } from "@shared/styles";
|
||||
import { TooltipProvider } from "~/components/TooltipContext";
|
||||
@@ -54,11 +55,13 @@ function ToolbarDropdown(props: ToolbarDropdownProps) {
|
||||
}
|
||||
|
||||
if (commands[menuItem.name]) {
|
||||
closeHistory(view);
|
||||
commands[menuItem.name](
|
||||
typeof menuItem.attrs === "function"
|
||||
? menuItem.attrs(state)
|
||||
: menuItem.attrs
|
||||
);
|
||||
closeHistory(view);
|
||||
} else if (menuItem.onClick) {
|
||||
menuItem.onClick();
|
||||
}
|
||||
@@ -158,9 +161,11 @@ function ToolbarMenu(props: Props) {
|
||||
}
|
||||
|
||||
// otherwise, run the associated editor command
|
||||
closeHistory(view);
|
||||
commands[item.name](
|
||||
typeof item.attrs === "function" ? item.attrs(state) : item.attrs
|
||||
);
|
||||
closeHistory(view);
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -7,6 +7,8 @@ import {
|
||||
yUndoPlugin,
|
||||
undo,
|
||||
redo,
|
||||
undoCommand,
|
||||
redoCommand,
|
||||
} from "y-prosemirror";
|
||||
import * as Y from "yjs";
|
||||
import Extension from "@shared/editor/lib/Extension";
|
||||
@@ -136,4 +138,12 @@ export default class Multiplayer extends Extension<MultiplayerOptions> {
|
||||
redo: () => redo,
|
||||
};
|
||||
}
|
||||
|
||||
keys() {
|
||||
return {
|
||||
"Mod-z": undoCommand,
|
||||
"Mod-y": redoCommand,
|
||||
"Shift-Mod-z": redoCommand,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import type { Editor as TEditor } from "~/editor";
|
||||
import type { Properties } from "~/types";
|
||||
import { useLocationSidebarContext } from "~/hooks/useLocationSidebarContext";
|
||||
import useStores from "~/hooks/useStores";
|
||||
import isTextInput from "~/utils/isTextInput";
|
||||
import { client } from "~/utils/ApiClient";
|
||||
import { emojiToUrl } from "~/utils/emoji";
|
||||
import { documentHistoryPath, documentEditPath } from "~/utils/routeHelpers";
|
||||
@@ -151,6 +152,17 @@ function DocumentScene({
|
||||
const onUndoRedo = useCallback(
|
||||
(event: KeyboardEvent) => {
|
||||
if (isModKey(event)) {
|
||||
const target =
|
||||
event.target instanceof Element ? event.target : undefined;
|
||||
|
||||
// The editor handles undo/redo through its own keymap when focused
|
||||
if (
|
||||
editorRef.current?.view?.hasFocus() ||
|
||||
(target && (isTextInput(target) || !!target.closest(".ProseMirror")))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if (event.shiftKey) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import { toast } from "sonner";
|
||||
import { IndexeddbPersistence } from "y-indexeddb";
|
||||
import * as Y from "yjs";
|
||||
import { EditorUpdateError } from "@shared/collaboration/CloseEvents";
|
||||
import History from "@shared/editor/extensions/History";
|
||||
import EDITOR_VERSION from "@shared/editor/version";
|
||||
import { supportsPassiveListener } from "@shared/utils/browser";
|
||||
import type { Props as EditorProps } from "~/components/Editor";
|
||||
@@ -256,8 +257,12 @@ function MultiplayerEditor(
|
||||
return props.extensions;
|
||||
}
|
||||
|
||||
// The Yjs undo manager (added by the Multiplayer extension below) is the
|
||||
// sole source of undo/redo history when collaborating.
|
||||
return [
|
||||
...(props.extensions || []),
|
||||
...(props.extensions || []).filter(
|
||||
(extension) => extension !== History && !(extension instanceof History)
|
||||
),
|
||||
new MultiplayerExtension({
|
||||
user,
|
||||
provider: remoteProvider,
|
||||
|
||||
Reference in New Issue
Block a user