Skip to content
Source
Sign inSign up
Open History to see the last commit

GitActionProgressOverlay.tsx

54 lines1.8 KB

1import { tryOpenExternalUrl } from "../../lib/openExternalUrl";
2import Animated, { FadeIn, FadeOut, ReduceMotion } from "react-native-reanimated";
3import { Toast } from "../../components/ui/Toast";
4import { useBarInset } from "../../components/ui/useBarInset";
5import { MOBILE_MOTION } from "../../lib/designTokens";
6import type { GitActionProgress } from "../../state/use-vcs-action-state";
7​
8export function GitActionProgressOverlay(props: {
9 readonly progress: GitActionProgress;
10 readonly onDismiss: () => void;
11 readonly onOpenPullRequest?: (url: string) => Promise<boolean>;
12}) {
13 const { progress, onDismiss } = props;
14 const openPullRequest = props.onOpenPullRequest;
15 const top = useBarInset() + 8;
16 const handlePress = () => {
17 if (progress.prUrl) {
18 void (openPullRequest
19 ? openPullRequest(progress.prUrl)
20 : tryOpenExternalUrl(progress.prUrl, "pull-request"));
21 return;
22 }
23 };
24​
25 if (progress.phase === "idle") {
26 return null;
27 }
28​
29 return (
30 <Animated.View
31 entering={FadeIn.duration(MOBILE_MOTION.enter).reduceMotion(ReduceMotion.System)}
32 exiting={FadeOut.duration(MOBILE_MOTION.exit).reduceMotion(ReduceMotion.System)}
33 className="absolute inset-x-3 z-[100]"
34 style={{ top }}
35 pointerEvents="box-none"
36 onAccessibilityEscape={onDismiss}
37 >
38 <Toast
39 singleLine
40 message={progress.label ?? "Source control"}
41 description={progress.description ?? undefined}
42 tone={
43 progress.phase === "error"
44 ? "danger"
45 : progress.phase === "success"
46 ? "success"
47 : "default"
48 }
49 busy={progress.phase === "running"}
50 action={progress.prUrl ? { label: "View", onPress: handlePress } : undefined}
51 />
52 </Animated.View>
53 );