fix: Improve scroll to comment logic, closes #7435

This commit is contained in:
Tom Moor
2024-09-20 23:31:46 -04:00
parent c4fa63df3d
commit c54fcc3536
11 changed files with 45 additions and 42 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ import * as React from "react";
import { useTranslation } from "react-i18next";
import AutoSizer from "react-virtualized-auto-sizer";
import { FixedSizeList as List } from "react-window";
import scrollIntoView from "smooth-scroll-into-view-if-needed";
import scrollIntoView from "scroll-into-view-if-needed";
import styled, { useTheme } from "styled-components";
import breakpoint from "styled-components-breakpoint";
import { NavigationNode } from "@shared/types";
@@ -1,7 +1,7 @@
import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import scrollIntoView from "smooth-scroll-into-view-if-needed";
import scrollIntoView from "scroll-into-view-if-needed";
import styled from "styled-components";
import { ellipsis } from "@shared/styles";
import { Node as SearchResult } from "~/components/DocumentExplorerNode";
+1 -1
View File
@@ -4,7 +4,7 @@ import {
} from "@getoutline/react-roving-tabindex";
import { LocationDescriptor } from "history";
import * as React from "react";
import scrollIntoView from "smooth-scroll-into-view-if-needed";
import scrollIntoView from "scroll-into-view-if-needed";
import styled, { useTheme } from "styled-components";
import { s, ellipsis } from "@shared/styles";
import Flex from "~/components/Flex";
@@ -10,7 +10,7 @@ import {
match,
} from "react-router";
import { Link } from "react-router-dom";
import scrollIntoView from "smooth-scroll-into-view-if-needed";
import scrollIntoView from "scroll-into-view-if-needed";
import history from "~/utils/history";
const resolveToLocation = (
+1 -1
View File
@@ -1,7 +1,7 @@
import { observer } from "mobx-react";
import * as React from "react";
import { useHistory, useLocation } from "react-router-dom";
import scrollIntoView from "smooth-scroll-into-view-if-needed";
import scrollIntoView from "scroll-into-view-if-needed";
import useQuery from "~/hooks/useQuery";
import lazyWithRetry from "~/utils/lazyWithRetry";
import type { Props } from "./Table";
+2 -2
View File
@@ -1,5 +1,5 @@
import * as React from "react";
import scrollIntoView from "smooth-scroll-into-view-if-needed";
import scrollIntoView from "scroll-into-view-if-needed";
import styled, { css } from "styled-components";
import { s, ellipsis } from "@shared/styles";
@@ -22,7 +22,7 @@ function LinkSearchResult({
const ref = React.useCallback(
(node: HTMLElement | null) => {
if (selected && node) {
void scrollIntoView(node, {
scrollIntoView(node, {
scrollMode: "if-needed",
block: "center",
boundary: (parent) =>
@@ -1,5 +1,5 @@
import * as React from "react";
import scrollIntoView from "smooth-scroll-into-view-if-needed";
import scrollIntoView from "scroll-into-view-if-needed";
import styled from "styled-components";
import MenuItem from "~/components/ContextMenu/MenuItem";
import { usePortalContext } from "~/components/Portal";
@@ -31,7 +31,7 @@ function SuggestionsMenuItem({
const ref = React.useCallback(
(node) => {
if (selected && node) {
void scrollIntoView(node, {
scrollIntoView(node, {
scrollMode: "if-needed",
block: "nearest",
boundary: (parent) =>
+2 -2
View File
@@ -4,7 +4,7 @@ import { Node } from "prosemirror-model";
import { Command, Plugin, PluginKey } from "prosemirror-state";
import { Decoration, DecorationSet } from "prosemirror-view";
import * as React from "react";
import scrollIntoView from "smooth-scroll-into-view-if-needed";
import scrollIntoView from "scroll-into-view-if-needed";
import Extension, { WidgetProps } from "@shared/editor/lib/Extension";
import FindAndReplace from "../components/FindAndReplace";
@@ -184,7 +184,7 @@ export default class FindAndReplaceExtension extends Extension {
`.${this.options.resultCurrentClassName}`
);
if (element) {
void scrollIntoView(element, {
scrollIntoView(element, {
scrollMode: "if-needed",
block: "center",
});
@@ -3,7 +3,7 @@ import { observer } from "mobx-react";
import * as React from "react";
import { useTranslation } from "react-i18next";
import { useHistory, useLocation } from "react-router-dom";
import scrollIntoView from "smooth-scroll-into-view-if-needed";
import scrollIntoView from "scroll-into-view-if-needed";
import styled, { css } from "styled-components";
import breakpoint from "styled-components-breakpoint";
import { s } from "@shared/styles";
@@ -64,6 +64,7 @@ function CommentThread({
recessed,
focused,
}: Props) {
const [focusedOnMount] = React.useState(focused);
const { editor } = useDocumentContext();
const { comments } = useStores();
const topRef = React.useRef<HTMLDivElement>(null);
@@ -103,7 +104,8 @@ function CommentThread({
const handleClickThread = () => {
history.replace({
search: location.search,
// Clear any commentId from the URL when explicitly focusing a thread
search: "",
pathname: location.pathname.replace(/\/history$/, ""),
state: { commentId: thread.id },
});
@@ -117,17 +119,26 @@ function CommentThread({
React.useEffect(() => {
if (focused) {
// If the thread is already visible, scroll it into view immediately,
// otherwise wait for the sidebar to appear.
const isThreadVisible =
(topRef.current?.getBoundingClientRect().left ?? 0) < window.innerWidth;
setTimeout(
() => {
if (focusedOnMount) {
setTimeout(() => {
if (!topRef.current) {
return;
}
scrollIntoView(topRef.current, {
scrollMode: "if-needed",
behavior: "auto",
block: "nearest",
boundary: (parent) =>
// Prevents body and other parent elements from being scrolled
parent.id !== "comments",
});
}, sidebarAppearDuration);
} else {
setTimeout(() => {
if (!replyRef.current) {
return;
}
return scrollIntoView(replyRef.current, {
scrollIntoView(replyRef.current, {
scrollMode: "if-needed",
behavior: "smooth",
block: "center",
@@ -135,9 +146,8 @@ function CommentThread({
// Prevents body and other parent elements from being scrolled
parent.id !== "comments",
});
},
isThreadVisible ? 0 : sidebarAppearDuration
);
}, 0);
}
const getCommentMarkElement = () =>
window.document?.getElementById(`comment-${thread.id}`);
@@ -153,7 +163,7 @@ function CommentThread({
isMarkVisible ? 0 : sidebarAppearDuration
);
}
}, [focused, thread.id]);
}, [focused, focusedOnMount, thread.id]);
const [draft, onSaveDraft] = usePersistedState<ProsemirrorData | undefined>(
`draft-${document.id}-${thread.id}`,
+1 -1
View File
@@ -220,7 +220,7 @@
"sequelize-typescript": "^2.1.6",
"slug": "^5.3.0",
"slugify": "^1.6.6",
"smooth-scroll-into-view-if-needed": "^1.1.33",
"scroll-into-view-if-needed": "^3.1.0",
"socket.io": "^4.7.5",
"socket.io-client": "^4.7.5",
"socket.io-redis": "^6.1.1",
+9 -16
View File
@@ -6617,10 +6617,10 @@ compute-scroll-into-view@1.0.14:
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.14.tgz#80e3ebb25d6aa89f42e533956cb4b16a04cfe759"
integrity "sha1-gOPrsl1qqJ9C5TOVbLSxagTP51k= sha512-mKDjINe3tc6hGelUMNDzuhorIUZ7kS7BwyY0r2wQd2HOH2tRuJykiC06iSEX8y1TuhNzvz4GcJnK16mM2J1NMQ=="
compute-scroll-into-view@^1.0.17:
version "1.0.17"
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-1.0.17.tgz#6a88f18acd9d42e9cf4baa6bec7e0522607ab7ab"
integrity "sha1-aojxis2dQunPS6pr7H4FImB6t6s= sha512-j4dx+Fb0URmzbwwMUrhqWM2BEWHdFGx+qZ9qqASHRPqvTYdqvWnHg0H1hIbcyLnvgnoNAVMlwkepyqM3DaIFUg=="
compute-scroll-into-view@^3.0.2:
version "3.1.0"
resolved "https://registry.yarnpkg.com/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz#753f11d972596558d8fe7c6bcbc8497690ab4c87"
integrity sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==
concat-map@0.0.1:
version "0.0.1"
@@ -13608,12 +13608,12 @@ scheduler@^0.20.2:
loose-envify "^1.1.0"
object-assign "^4.1.1"
scroll-into-view-if-needed@^2.2.28:
version "2.2.28"
resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-2.2.28.tgz#5a15b2f58a52642c88c8eca584644e01703d645a"
integrity "sha1-WhWy9YpSZCyIyOylhGROAXA9ZFo= sha512-8LuxJSuFVc92+0AdNv4QOxRL4Abeo1DgLnGNkn1XlaujPH/3cCFz3QI60r2VNu4obJJROzgnIUw5TKQkZvZI1w=="
scroll-into-view-if-needed@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz#fa9524518c799b45a2ef6bbffb92bcad0296d01f"
integrity sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==
dependencies:
compute-scroll-into-view "^1.0.17"
compute-scroll-into-view "^3.0.2"
selderee@^0.11.0:
version "0.11.0"
@@ -13832,13 +13832,6 @@ smob@^1.0.0:
resolved "https://registry.yarnpkg.com/smob/-/smob-1.5.0.tgz#85d79a1403abf128d24d3ebc1cdc5e1a9548d3ab"
integrity sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==
smooth-scroll-into-view-if-needed@^1.1.33:
version "1.1.33"
resolved "https://registry.yarnpkg.com/smooth-scroll-into-view-if-needed/-/smooth-scroll-into-view-if-needed-1.1.33.tgz#2c7b88c82784c69030cb0489b9df584e94e01533"
integrity "sha1-LHuIyCeExpAwywSJud9YTpTgFTM= sha512-crS8NfAaoPrtVYOCMSAnO2vHRgUp22NiiDgEQ7YiaAy5xe2jmR19Jm+QdL8+97gO8ENd7PUyQIAQojJyIiyRHw=="
dependencies:
scroll-into-view-if-needed "^2.2.28"
socket.io-adapter@~2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.2.0.tgz#43af9157c4609e74b8addc6867873ac7eb48fda2"