mirror of
https://github.com/outline/outline.git
synced 2026-06-13 11:25:03 +03:00
d3eb3db7ba
* shares.info, collections.info, documents.info * shares.list, shares.create, shares.update * shares.sitemap * parity with existing document shared screen * collection share popover * parent share and table * collection scene * collection link in sidebar * sidebar and breadcrumb collection link click * collection link click in editor * meta * more meta + 404 page * map internal link, remove showLastUpdated option * fix shares.list pagination * show last updated * shareLoader tests * lint * sidebar context for collection link * badge in shares table * fix existing tests * tsc * update failing test snapshot * env * signed url for collection attachments * include collection content in SSR for screen readers * search * drafts can be shared * review * tsc, remove old shared-doc scene * tweaks * DRY * refactor loader * Remove share/collection urls * fix: Collection overview should not be editable when viewing shared link and logged in * Tweak public breadcrumb * fix: Deleted documents should never be exposed through share * empty sharedTree array where includeChildDocuments is false * revert includeChildDocs guard for logical correctness + SSR bug fix * fix: check document is part of share --------- Co-authored-by: Tom Moor <tom@getoutline.com>
89 lines
2.6 KiB
TypeScript
89 lines
2.6 KiB
TypeScript
import { useCallback } from "react";
|
|
import { useHistory } from "react-router-dom";
|
|
import { isModKey } from "@shared/utils/keyboard";
|
|
import { isDocumentUrl, isInternalUrl } from "@shared/utils/urls";
|
|
import { sharedModelPath } from "~/utils/routeHelpers";
|
|
import { isHash } from "~/utils/urls";
|
|
import useStores from "./useStores";
|
|
|
|
type Params = {
|
|
/** The share ID of the document being viewed, if any */
|
|
shareId?: string;
|
|
};
|
|
|
|
export default function useEditorClickHandlers({ shareId }: Params) {
|
|
const history = useHistory();
|
|
const { documents } = useStores();
|
|
const handleClickLink = useCallback(
|
|
(href: string, event?: MouseEvent) => {
|
|
// on page hash
|
|
if (isHash(href)) {
|
|
window.location.href = href;
|
|
return;
|
|
}
|
|
|
|
let navigateTo = href;
|
|
|
|
if (isInternalUrl(href)) {
|
|
// probably absolute
|
|
if (href[0] !== "/") {
|
|
try {
|
|
const url = new URL(href);
|
|
navigateTo = url.pathname + url.hash;
|
|
} catch (_err) {
|
|
navigateTo = href;
|
|
}
|
|
}
|
|
|
|
// Link to our own API should be opened in a new tab, not in the app
|
|
if (navigateTo.startsWith("/api/")) {
|
|
window.open(href, "_blank");
|
|
return;
|
|
}
|
|
|
|
// parse shareId from link
|
|
const linkShareId = navigateTo.match(/\/s\/([^/]+)\/doc\//)?.[1];
|
|
|
|
// If we're navigating to an internal document link then prepend the
|
|
// share route to the URL so that the document is loaded in context
|
|
if (
|
|
shareId &&
|
|
(!linkShareId || linkShareId === shareId) &&
|
|
(navigateTo.includes("/doc/") ||
|
|
navigateTo.includes("/collection/")) &&
|
|
!navigateTo.includes(shareId)
|
|
) {
|
|
navigateTo = sharedModelPath(shareId, navigateTo);
|
|
}
|
|
|
|
if (isDocumentUrl(navigateTo)) {
|
|
const document = documents.getByUrl(navigateTo);
|
|
if (document) {
|
|
navigateTo = document.path;
|
|
}
|
|
}
|
|
|
|
// If we're navigating to a share link from a non-share link then open it in a new tab
|
|
if (!shareId && navigateTo.startsWith("/s/")) {
|
|
window.open(href, "_blank");
|
|
return;
|
|
}
|
|
|
|
if (
|
|
!event ||
|
|
(!isModKey(event) && !event.shiftKey && event.button !== 1)
|
|
) {
|
|
history.push(navigateTo, { sidebarContext: "collections" }); // optimistic preference of "collections"
|
|
} else {
|
|
window.open(navigateTo, "_blank");
|
|
}
|
|
} else {
|
|
window.open(href, "_blank");
|
|
}
|
|
},
|
|
[history, shareId]
|
|
);
|
|
|
|
return { handleClickLink };
|
|
}
|