Skip to content
Source
Sign inSign up

PullRequestOverviewLoading.tsx

112 lines4.0 KB

1import { Chip } from "../../components/ui/Chip";
2import { PullRequestSectionHeading } from "./PullRequestSectionHeading";
3import type { PullRequestListEntry, PullRequestSummary } from "@t3tools/contracts";
4import { View } from "react-native";
5import { PullRequestCardGroup, PullRequestCardRow } from "./PullRequestControls";
6import { PullRequestStackCard } from "./PullRequestStackCard";
7import type { PullRequestParams } from "./usePullRequestDiff";
8import type { PullRequestStackState } from "./usePullRequestStack";
9import { pullRequestListReviewStatus } from "./pullRequestList";
10import { PullRequestGlyph } from "./pullRequestGlyphs";
11​
12export function PullRequestOverviewLoading({
13 summary,
14 params,
15 stack,
16}: {
17 readonly summary: PullRequestListEntry | PullRequestSummary;
18 readonly params: PullRequestParams;
19 readonly stack: PullRequestStackState;
20}) {
21 const review = pullRequestListReviewStatus({
22 reviewDecision: summary.reviewDecision ?? undefined,
23 viewerReviewRequested: "viewerReviewRequested" in summary && summary.viewerReviewRequested,
24 });
25 const conflicting = summary.mergeability === "conflicting";
26 const clean = summary.mergeability === "mergeable";
27 return (
28 <View
29 className="gap-5"
30 accessibilityLabel="Loading pull request details"
31 accessibilityState={{ busy: true }}
32 >
33 <PullRequestStackCard params={params} state={stack} />
34 <PullRequestCardGroup>
35 <PullRequestCardRow
36 compact
37 title={
38 summary.checksState === "passing"
39 ? "Checks completed"
40 : summary.checksState === "failing"
41 ? "Checks failing"
42 : summary.checksState === "pending"
43 ? "Checks running"
44 : "Checks"
45 }
46 icon={
47 summary.checksState === "passing"
48 ? "checkmark.circle"
49 : summary.checksState === "failing"
50 ? "exclamationmark.circle"
51 : "clock"
52 }
53 tint={
54 summary.checksState === "passing"
55 ? "accent-adaptive-emerald-600-400"
56 : summary.checksState === "failing"
57 ? "accent-danger-foreground"
58 : "accent-icon-muted"
59 }
60 >
61 <View className="h-3 w-16 rounded bg-subtle-strong" />
62 </PullRequestCardRow>
63 <PullRequestCardRow
64 compact
65 title={review?.accessibleLabel ?? "Reviews"}
66 icon={review?.icon ?? "bubble.left"}
67 tint={review?.tint}
68 >
69 <View className="h-3 w-20 rounded bg-subtle-strong" />
70 </PullRequestCardRow>
71 <PullRequestCardRow
72 compact
73 title={
74 conflicting
75 ? `Conflicts with ${summary.baseBranch}`
76 : clean
77 ? `No conflicts with ${summary.baseBranch}`
78 : "Branch"
79 }
80 icon={
81 conflicting ? PullRequestGlyph.conflicting : clean ? "checkmark.circle" : "arrow.branch"
82 }
83 tint={
84 conflicting
85 ? "accent-danger-foreground"
86 : clean
87 ? "accent-adaptive-emerald-600-400"
88 : undefined
89 }
90 />
91 <View className="border-t border-border-subtle p-3">
92 <View className="h-11 rounded-xl bg-subtle-strong" />
93 </View>
94 </PullRequestCardGroup>
95 {"labels" in summary && summary.labels.length ? (
96 <View className="flex-row flex-wrap gap-2">
97 {summary.labels.map((label) => (
98 <Chip key={label.name} label={label.name} size="small" />
99 ))}
100 </View>
101 ) : null}
102 <View className="gap-3">
103 <PullRequestSectionHeading>Description</PullRequestSectionHeading>
104 <View className="gap-3 py-1">
105 <View className="h-4 w-full rounded bg-subtle-strong" />
106 <View className="h-4 w-full rounded bg-subtle-strong" />
107 <View className="h-4 w-3/4 rounded bg-subtle-strong" />
108 </View>
109 </View>
110 </View>
111 );