Skip to content
Source
Sign inSign up

threadReference.ts

69 lines2.6 KB

1import type {
2 ComposerContextClipboardFragment,
3 ScopedThreadRef,
4 ThreadPullRequestLink,
5} from "@t3tools/contracts";
6import { threadContextRecord } from "@t3tools/shared/composerContextReferences";
7import { hostedThreadLink } from "@t3tools/shared/threadLinks";
8​
9import { resolveThreadCurrentPullRequestLink } from "./threadPullRequests.ts";
10​
11export interface ThreadReferenceCopyTarget {
12 readonly kind: "pull-request" | "thread";
13 /** The plain text: a PR URL, or a link that opens the thread from anywhere. */
14 readonly value: string;
15 /** What a toast or palette row shows for the copy. */
16 readonly description: string;
17 /** T3's clipboard format, which pastes a thread back into a composer as a chip. */
18 readonly fragment?: ComposerContextClipboardFragment;
19 readonly clipboardTarget: string;
20 readonly successTitle: string;
21 readonly failureTitle: string;
23​
24/**
25 * A link that opens the thread from anywhere, through `hostedAppUrl`, this build's hosted app. It
26 * pastes back as a chip into any composer whose agent reads that thread's machine.
27 */
28export function threadChipCopyTarget(
29 threadRef: ScopedThreadRef,
30 title: string,
31 hostedAppUrl?: string,
32): ThreadReferenceCopyTarget {
33 const record = threadContextRecord(threadRef, title);
34 return {
35 kind: "thread",
36 value: hostedThreadLink(threadRef, hostedAppUrl),
37 description: record.title,
38 fragment: { version: 1, source: { environmentId: threadRef.environmentId }, records: [record] },
39 clipboardTarget: "thread",
40 successTitle: "Thread copied",
41 failureTitle: "Failed to copy thread",
42 };
44​
45export function resolveThreadReferenceCopyTarget(input: {
46 readonly threadRef: ScopedThreadRef;
47 readonly title: string;
48 /** Undefined means no PR panel; null means its URL is not available yet. */
49 readonly openPanelPullRequestUrl?: string | null | undefined;
50 readonly pullRequests?: ReadonlyArray<ThreadPullRequestLink> | undefined;
51 readonly linkedPullRequestUrl?: string | null;
52 readonly hostedAppUrl?: string;
53}): ThreadReferenceCopyTarget | null {
54 if (input.openPanelPullRequestUrl === null) return null;
55 const pullRequestUrl =
56 input.openPanelPullRequestUrl ??
57 resolveThreadCurrentPullRequestLink(input.pullRequests ?? [])?.url ??
58 input.linkedPullRequestUrl;
59 return pullRequestUrl
60 ? {
61 kind: "pull-request",
62 value: pullRequestUrl,
63 description: pullRequestUrl,
64 clipboardTarget: "pull request link",
65 successTitle: "PR link copied",
66 failureTitle: "Failed to copy PR link",
67 }
68 : threadChipCopyTarget(input.threadRef, input.title, input.hostedAppUrl);