Various commenting improvements (#4938)

* fix: New threads attached to previous as replies

* fix: Cannot use floating toolbar properly in comments

* perf: Avoid re-writing history on click in editor

* fix: Comment on text selection

* fix: 'Copy link' on comments uses wrong hostname

* Show comment buttons on input focus rather than non-empty input
Increase maximum sidebar size

* Allow opening comments from document menu

* fix: Clicking comment menu should not focus thread
This commit is contained in:
Tom Moor
2023-02-26 14:19:12 -05:00
committed by GitHub
parent b813f20f8f
commit 08df14618c
16 changed files with 219 additions and 141 deletions

View File

@@ -3,7 +3,6 @@ import { findDomRefAtPos, findParentNode } from "prosemirror-utils";
import { EditorView } from "prosemirror-view";
import * as React from "react";
import { Trans } from "react-i18next";
import { Portal } from "react-portal";
import { VisuallyHidden } from "reakit/VisuallyHidden";
import styled from "styled-components";
import insertFiles from "@shared/editor/commands/insertFiles";
@@ -14,6 +13,7 @@ import { MenuItem } from "@shared/editor/types";
import { depths } from "@shared/styles";
import { getEventFiles } from "@shared/utils/files";
import { AttachmentValidation } from "@shared/validations";
import { Portal } from "~/components/Portal";
import Scrollable from "~/components/Scrollable";
import { Dictionary } from "~/hooks/useDictionary";
import Input from "./Input";
@@ -406,7 +406,16 @@ class CommandMenu<T extends MenuItem> extends React.Component<Props<T>, State> {
const { top, bottom, right } = paragraph.node.getBoundingClientRect();
const margin = 24;
let leftPos = left + window.scrollX;
const offsetParent = ref?.offsetParent
? ref.offsetParent.getBoundingClientRect()
: ({
width: 0,
height: 0,
top: 0,
left: 0,
} as DOMRect);
let leftPos = left - offsetParent.left;
if (props.rtl && ref) {
leftPos = right - ref.scrollWidth;
}
@@ -414,14 +423,14 @@ class CommandMenu<T extends MenuItem> extends React.Component<Props<T>, State> {
if (startPos.top - offsetHeight > margin) {
return {
left: leftPos,
top: undefined,
bottom: window.innerHeight - top - window.scrollY,
top: top - offsetParent.top - offsetHeight,
bottom: undefined,
isAbove: false,
};
} else {
return {
left: leftPos,
top: bottom + window.scrollY,
top: bottom - offsetParent.top,
bottom: undefined,
isAbove: true,
};

View File

@@ -1,9 +1,9 @@
import { NodeSelection } from "prosemirror-state";
import { CellSelection } from "prosemirror-tables";
import * as React from "react";
import { Portal } from "react-portal";
import styled from "styled-components";
import { depths } from "@shared/styles";
import { Portal } from "~/components/Portal";
import useComponentSize from "~/hooks/useComponentSize";
import useEventListener from "~/hooks/useEventListener";
import useMediaQuery from "~/hooks/useMediaQuery";
@@ -80,6 +80,15 @@ function usePosition({
right: Math.max(fromPos.right, toPos.right),
};
const offsetParent = menuRef.current.offsetParent
? menuRef.current.offsetParent.getBoundingClientRect()
: ({
width: 0,
height: 0,
top: 0,
left: 0,
} as DOMRect);
// tables are an oddity, and need their own positioning logic
const isColSelection =
selection instanceof CellSelection &&
@@ -116,8 +125,8 @@ function usePosition({
const { left, top, width } = imageElement.getBoundingClientRect();
return {
left: Math.round(left + width / 2 + window.scrollX - menuWidth / 2),
top: Math.round(top + window.scrollY - menuHeight),
left: Math.round(left + width / 2 - menuWidth / 2 - offsetParent.left),
top: Math.round(top - menuHeight - offsetParent.top),
offset: 0,
visible: true,
};
@@ -145,8 +154,8 @@ function usePosition({
// of the selection still
const offset = left - (centerOfSelection - menuWidth / 2);
return {
left: Math.round(left + window.scrollX),
top: Math.round(top + window.scrollY),
left: Math.round(left - offsetParent.left),
top: Math.round(top - offsetParent.top),
offset: Math.round(offset),
visible: true,
};

View File

@@ -2,7 +2,9 @@ import styled from "styled-components";
type Props = { active?: boolean; disabled?: boolean };
export default styled.button<Props>`
export default styled.button.attrs((props) => ({
type: props.type || "button",
}))<Props>`
display: inline-block;
flex: 0;
width: 24px;