Fixes hover preview going out of window bounds (#6776)

* fix: hover preview out of bounds

* fix: pop

* fix: check for both element and data

* fix: show loading indicator

* fix: width
This commit is contained in:
Apoorv Mishra
2024-04-13 18:31:40 +05:30
committed by GitHub
parent 054bddb666
commit 90ed6a5366
4 changed files with 137 additions and 124 deletions

View File

@@ -4,6 +4,8 @@ import { EditorView } from "prosemirror-view";
import * as React from "react";
import Extension from "@shared/editor/lib/Extension";
import HoverPreview from "~/components/HoverPreview";
import env from "~/env";
import { client } from "~/utils/ApiClient";
interface HoverPreviewsOptions {
/** Delay before the target is considered "hovered" and callback is triggered. */
@@ -13,13 +15,17 @@ interface HoverPreviewsOptions {
export default class HoverPreviews extends Extension {
state: {
activeLinkElement: HTMLElement | null;
data: Record<string, any> | null;
dataLoading: boolean;
} = observable({
activeLinkElement: null,
data: null,
dataLoading: false,
});
get defaultOptions(): HoverPreviewsOptions {
return {
delay: 500,
delay: 600,
};
}
@@ -45,8 +51,30 @@ export default class HoverPreviews extends Extension {
);
if (isHoverTarget(target, view)) {
hoveringTimeout = setTimeout(
action(() => {
this.state.activeLinkElement = target as HTMLElement;
action(async () => {
const element = target as HTMLElement;
const url =
element?.getAttribute("href") || element?.dataset.url;
const documentId = window.location.pathname
.split("/")
.pop();
if (url) {
this.state.dataLoading = true;
try {
const data = await client.post("/urls.unfurl", {
url: url.startsWith("/") ? env.URL + url : url,
documentId,
});
this.state.activeLinkElement = element;
this.state.data = data;
} catch (err) {
this.state.activeLinkElement = null;
} finally {
this.state.dataLoading = false;
}
}
}),
this.options.delay
);
@@ -72,6 +100,8 @@ export default class HoverPreviews extends Extension {
widget = () => (
<HoverPreview
element={this.state.activeLinkElement}
data={this.state.data}
dataLoading={this.state.dataLoading}
onClose={action(() => {
this.state.activeLinkElement = null;
})}