1import { scopeProjectRef } from "@t3tools/client-runtime/environment";
2import {
3 EnvironmentId,
4 ProjectId,
5 mergebotPullRequestUrl,
6 type ScopedThreadRef,
7} from "@t3tools/contracts";
8import { useMemo } from "react";
9
10import {
11 readPullRequestDetailSnapshot,
12 resolveDisplayedPullRequestDetail,
13 resolvePullRequestReferenceHost,
14} from "../components/pullRequest/pullRequestDetail.logic";
15import { gitHubPullRequestBrowserUrl } from "../lib/openPullRequestLink";
16import { selectActiveRightPanelSurface, useRightPanelStore } from "../rightPanelStore";
17import { useProject, useServerConfigs } from "../state/entities";
18import { pullRequestEnvironment } from "../state/pullRequests";
19import { useEnvironmentQuery } from "../state/query";
20import { useSupportsMultiplePullRequests } from "./useSupportsMultiplePullRequests";
21
22export function useOpenPanelPullRequestUrl(threadRef: ScopedThreadRef | null) {
23 const surface = useRightPanelStore((state) =>
24 selectActiveRightPanelSurface(state.byThreadKey, threadRef),
25 );
26 const requestedReference = surface?.kind === "pull-request" ? surface : null;
27 const environmentId = requestedReference?.environmentId
28 ? EnvironmentId.make(requestedReference.environmentId)
29 : threadRef?.environmentId;
30 const supportsMultiplePullRequests = useSupportsMultiplePullRequests(environmentId ?? null);
31 const project = useProject(
32 requestedReference && environmentId
33 ? scopeProjectRef(environmentId, ProjectId.make(requestedReference.projectId))
34 : null,
35 );
36 const reference = useMemo(() => {
37 if (requestedReference === null) return null;
38 const input = {
39 projectId: ProjectId.make(requestedReference.projectId),
40 repository: requestedReference.repository,
41 number: requestedReference.number,
42 };
43 return supportsMultiplePullRequests
44 ? resolvePullRequestReferenceHost(
45 {
46 ...input,
47 ...(requestedReference.host === undefined ? {} : { host: requestedReference.host }),
48 },
49 project?.repositoryIdentity,
50 )
51 : input;
52 }, [requestedReference, supportsMultiplePullRequests, project?.repositoryIdentity]);
53 const configurations = useServerConfigs();
54 const mergebotUrl =
55 reference && environmentId
56 ? mergebotPullRequestUrl(configurations.get(environmentId)?.mergebot, reference)
57 : null;
58 const detail = useEnvironmentQuery(
59 reference && environmentId && !mergebotUrl
60 ? pullRequestEnvironment.detail({
61 environmentId,
62 input: reference,
63 })
64 : null,
65 ).data;
66 const cachedDetail = useMemo(
67 () =>
68 reference && environmentId
69 ? readPullRequestDetailSnapshot(
70 typeof window === "undefined" ? undefined : window.localStorage,
71 environmentId,
72 reference,
73 )
74 : null,
75 [environmentId, reference],
76 );
77 return (
78 mergebotUrl ??
79 (reference
80 ? (resolveDisplayedPullRequestDetail({ live: detail, cached: cachedDetail, reference })
81 ?.url ??
82 requestedReference?.url ??
83 gitHubPullRequestBrowserUrl(
84 project?.repositoryIdentity,
85 reference.repository,
86 reference.number,
87 ))
88 : undefined)
89 );
90}