authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-07-24 00:39:09+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-07-24 00:39:09+02:00
logce467da9cfae3d7952ce13a9e2450e2908e9f224
tree1d0c05f030ee27ce4f71426cd0aa3b1a90ab0cb6
parent6ef7aa8399640fd2bf10fcb126c0db93fee47ff0
signature Signed by PGP key B5690EEEBB952194

Polish iOS git progress overlay with glass effects (#4387)


1 files changed, 62 insertions(+), 14 deletions(-)

apps/mobile/src/features/threads/GitActionProgressOverlay.tsx+62-14
......@@ -1,8 +1,9 @@
11import * as Haptics from "expo-haptics";
2import { isLiquidGlassSupported, LiquidGlassView } from "@callstack/liquid-glass";
23import { SymbolView } from "../../components/AppSymbol";
34import { useCallback, useEffect, useRef } from "react";
4import { ActivityIndicator, Pressable, View } from "react-native";
5import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
5import { ActivityIndicator, Pressable, StyleSheet, useColorScheme, View } from "react-native";
6import Animated, { FadeIn, FadeOut, LinearTransition } from "react-native-reanimated";
67import { useSafeAreaInsets } from "react-native-safe-area-context";
78
89import { AppText as Text } from "../../components/AppText";
......@@ -10,6 +11,9 @@ import { tryOpenExternalUrl } from "../../lib/openExternalUrl";
1011import { useThemeColor } from "../../lib/useThemeColor";
1112import type { GitActionProgress } from "../../state/use-vcs-action-state";
1213
14const OVERLAY_LAYOUT_TRANSITION = LinearTransition.duration(220);
15const AnimatedLiquidGlassView = Animated.createAnimatedComponent(LiquidGlassView);
16
1317export function GitActionProgressOverlay(props: {
1418 readonly progress: GitActionProgress;
1519 readonly onDismiss: () => void;
......@@ -45,7 +49,7 @@ export function GitActionProgressOverlay(props: {
4549
4650 return (
4751 <Animated.View
48 entering={FadeIn.duration(200)}
52 entering={isLiquidGlassSupported ? undefined : FadeIn.duration(200)}
4953 exiting={FadeOut.duration(150)}
5054 className="absolute inset-x-3 z-[100]"
5155 style={{ top: insets.top + 48 }}
......@@ -61,16 +65,11 @@ export function GitActionProgressOverlay(props: {
6165function OverlayContent(props: { readonly progress: GitActionProgress }) {
6266 const { progress } = props;
6367 const iconColor = useThemeColor("--color-icon");
64
65 const bgClass =
66 progress.phase === "error"
67 ? "bg-red-50 dark:bg-red-950/80 border-red-200 dark:border-red-800"
68 : "bg-card border-border";
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 >
68 const glassBorder = useThemeColor("--color-header-border");
69 const glassTint = useThemeColor("--color-glass-tint");
70 const isDarkMode = useColorScheme() === "dark";
71 const content = (
72 <>
7473 <OverlayIcon phase={progress.phase} iconColor={iconColor} />
7574
7675 <View className="flex-1 gap-0.5">
......@@ -89,7 +88,56 @@ function OverlayContent(props: { readonly progress: GitActionProgress }) {
8988 {progress.prUrl ? (
9089 <SymbolView name="arrow.up.right" size={13} tintColor={iconColor} type="monochrome" />
9190 ) : 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>
93141 );
94142}
95143