| ... | @@ -1,8 +1,9 @@ | ... | @@ -1,8 +1,9 @@ |
| 1 | import * as Haptics from "expo-haptics"; | 1 | import * as Haptics from "expo-haptics"; |
| | 2 | import { isLiquidGlassSupported, LiquidGlassView } from "@callstack/liquid-glass"; |
| 2 | import { SymbolView } from "../../components/AppSymbol"; | 3 | import { SymbolView } from "../../components/AppSymbol"; |
| 3 | import { useCallback, useEffect, useRef } from "react"; | 4 | import { useCallback, useEffect, useRef } from "react"; |
| 4 | import { ActivityIndicator, Pressable, View } from "react-native"; | 5 | import { ActivityIndicator, Pressable, StyleSheet, useColorScheme, View } from "react-native"; |
| 5 | import Animated, { FadeIn, FadeOut } from "react-native-reanimated"; | 6 | import Animated, { FadeIn, FadeOut, LinearTransition } from "react-native-reanimated"; |
| 6 | import { useSafeAreaInsets } from "react-native-safe-area-context"; | 7 | import { useSafeAreaInsets } from "react-native-safe-area-context"; |
| 7 | | 8 | |
| 8 | import { AppText as Text } from "../../components/AppText"; | 9 | import { AppText as Text } from "../../components/AppText"; |
| ... | @@ -10,6 +11,9 @@ import { tryOpenExternalUrl } from "../../lib/openExternalUrl"; | ... | @@ -10,6 +11,9 @@ import { tryOpenExternalUrl } from "../../lib/openExternalUrl"; |
| 10 | import { useThemeColor } from "../../lib/useThemeColor"; | 11 | import { useThemeColor } from "../../lib/useThemeColor"; |
| 11 | import type { GitActionProgress } from "../../state/use-vcs-action-state"; | 12 | import type { GitActionProgress } from "../../state/use-vcs-action-state"; |
| 12 | | 13 | |
| | 14 | const OVERLAY_LAYOUT_TRANSITION = LinearTransition.duration(220); |
| | 15 | const AnimatedLiquidGlassView = Animated.createAnimatedComponent(LiquidGlassView); |
| | 16 | |
| 13 | export function GitActionProgressOverlay(props: { | 17 | export function GitActionProgressOverlay(props: { |
| 14 | readonly progress: GitActionProgress; | 18 | readonly progress: GitActionProgress; |
| 15 | readonly onDismiss: () => void; | 19 | readonly onDismiss: () => void; |
| ... | @@ -45,7 +49,7 @@ export function GitActionProgressOverlay(props: { | ... | @@ -45,7 +49,7 @@ export function GitActionProgressOverlay(props: { |
| 45 | | 49 | |
| 46 | return ( | 50 | return ( |
| 47 | <Animated.View | 51 | <Animated.View |
| 48 | entering={FadeIn.duration(200)} | 52 | entering={isLiquidGlassSupported ? undefined : FadeIn.duration(200)} |
| 49 | exiting={FadeOut.duration(150)} | 53 | exiting={FadeOut.duration(150)} |
| 50 | className="absolute inset-x-3 z-[100]" | 54 | className="absolute inset-x-3 z-[100]" |
| 51 | style={{ top: insets.top + 48 }} | 55 | style={{ top: insets.top + 48 }} |
| ... | @@ -61,16 +65,11 @@ export function GitActionProgressOverlay(props: { | ... | @@ -61,16 +65,11 @@ export function GitActionProgressOverlay(props: { |
| 61 | function OverlayContent(props: { readonly progress: GitActionProgress }) { | 65 | function OverlayContent(props: { readonly progress: GitActionProgress }) { |
| 62 | const { progress } = props; | 66 | const { progress } = props; |
| 63 | const iconColor = useThemeColor("--color-icon"); | 67 | const iconColor = useThemeColor("--color-icon"); |
| 64 | | 68 | const glassBorder = useThemeColor("--color-header-border"); |
| 65 | const bgClass = | 69 | const glassTint = useThemeColor("--color-glass-tint"); |
| 66 | progress.phase === "error" | 70 | const isDarkMode = useColorScheme() === "dark"; |
| 67 | ? "bg-red-50 dark:bg-red-950/80 border-red-200 dark:border-red-800" | 71 | const content = ( |
| 68 | : "bg-card border-border"; | 72 | <> |
| 69 | | | |
| 70 | return ( | | |
| 71 | <View | | |
| 72 | className={`flex-row items-center gap-2.5 rounded-2xl border px-3.5 py-3 shadow-lg shadow-black/10 ${bgClass}`} | | |
| 73 | > | | |
| 74 | <OverlayIcon phase={progress.phase} iconColor={iconColor} /> | 73 | <OverlayIcon phase={progress.phase} iconColor={iconColor} /> |
| 75 | | 74 | |
| 76 | <View className="flex-1 gap-0.5"> | 75 | <View className="flex-1 gap-0.5"> |
| ... | @@ -89,7 +88,56 @@ function OverlayContent(props: { readonly progress: GitActionProgress }) { | ... | @@ -89,7 +88,56 @@ function OverlayContent(props: { readonly progress: GitActionProgress }) { |
| 89 | {progress.prUrl ? ( | 88 | {progress.prUrl ? ( |
| 90 | <SymbolView name="arrow.up.right" size={13} tintColor={iconColor} type="monochrome" /> | 89 | <SymbolView name="arrow.up.right" size={13} tintColor={iconColor} type="monochrome" /> |
| 91 | ) : null} | 90 | ) : null} |
| 92 | </View> | 91 | </> |
| | 92 | ); |
| | 93 | |
| | 94 | if (isLiquidGlassSupported) { |
| | 95 | return ( |
| | 96 | <Animated.View |
| | 97 | layout={OVERLAY_LAYOUT_TRANSITION} |
| | 98 | style={{ |
| | 99 | backgroundColor: glassTint, |
| | 100 | borderColor: glassBorder, |
| | 101 | borderCurve: "continuous", |
| | 102 | borderRadius: 26, |
| | 103 | borderWidth: StyleSheet.hairlineWidth, |
| | 104 | overflow: "hidden", |
| | 105 | }} |
| | 106 | > |
| | 107 | <AnimatedLiquidGlassView |
| | 108 | colorScheme={isDarkMode ? "dark" : "light"} |
| | 109 | effect="regular" |
| | 110 | interactive |
| | 111 | layout={OVERLAY_LAYOUT_TRANSITION} |
| | 112 | style={{ |
| | 113 | borderCurve: "continuous", |
| | 114 | borderRadius: 26, |
| | 115 | overflow: "hidden", |
| | 116 | }} |
| | 117 | > |
| | 118 | <Animated.View |
| | 119 | entering={FadeIn.delay(60).duration(140)} |
| | 120 | className="flex-row items-center gap-2.5 px-3.5 py-3" |
| | 121 | > |
| | 122 | {content} |
| | 123 | </Animated.View> |
| | 124 | </AnimatedLiquidGlassView> |
| | 125 | </Animated.View> |
| | 126 | ); |
| | 127 | } |
| | 128 | |
| | 129 | const bgClass = |
| | 130 | progress.phase === "error" |
| | 131 | ? "bg-red-50 dark:bg-red-950/80 border-red-200 dark:border-red-800" |
| | 132 | : "bg-card border-border"; |
| | 133 | |
| | 134 | return ( |
| | 135 | <Animated.View |
| | 136 | layout={OVERLAY_LAYOUT_TRANSITION} |
| | 137 | className={`flex-row items-center gap-2.5 rounded-[26px] border border-continuous px-3.5 py-3 shadow-lg shadow-black/10 ${bgClass}`} |
| | 138 | > |
| | 139 | {content} |
| | 140 | </Animated.View> |
| 93 | ); | 141 | ); |
| 94 | } | 142 | } |
| 95 | | 143 | |