Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 8 additions & 11 deletions apps/mobile/src/components/GlassSurface.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { GlassView, isGlassEffectAPIAvailable } from "expo-glass-effect";
import type { ReactNode } from "react";
import { forwardRef, type ReactNode } from "react";
import {
Platform,
useColorScheme,
Expand All @@ -17,14 +17,10 @@ export interface GlassSurfaceProps extends Omit<ViewProps, "className"> {
readonly chrome?: "default" | "none";
}

export function GlassSurface({
children,
glassEffectStyle = "regular",
chrome = "default",
tintColor,
style,
...props
}: GlassSurfaceProps) {
export const GlassSurface = forwardRef<View, GlassSurfaceProps>(function GlassSurface(
{ children, glassEffectStyle = "regular", chrome = "default", tintColor, style, ...props },
ref,
) {
const isDarkMode = useColorScheme() === "dark";
const borderColor = useThemeColor("--color-border");
const glassSurface = useThemeColor("--color-glass-surface");
Expand Down Expand Up @@ -56,6 +52,7 @@ export function GlassSurface({
return (
<GlassView
{...props}
ref={ref}
glassEffectStyle={glassEffectStyle}
tintColor={String(tintColor ?? glassTint)}
colorScheme={isDarkMode ? "dark" : "light"}
Expand All @@ -67,8 +64,8 @@ export function GlassSurface({
}

return (
<View {...props} style={[surfaceStyle, style]}>
<View {...props} ref={ref} style={[surfaceStyle, style]}>
{children}
</View>
);
}
});
54 changes: 41 additions & 13 deletions apps/mobile/src/features/threads/GitActionProgressOverlay.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import * as Haptics from "expo-haptics";
import { SymbolView } from "../../components/AppSymbol";
import { useCallback, useEffect, useRef } from "react";
import { ActivityIndicator, Pressable, View } from "react-native";
import Animated, { FadeIn, FadeOut } from "react-native-reanimated";
import { ActivityIndicator, Platform, Pressable, View } from "react-native";
import Animated, { FadeIn, FadeOut, LinearTransition } from "react-native-reanimated";
import { useSafeAreaInsets } from "react-native-safe-area-context";
import { isGlassEffectAPIAvailable } from "expo-glass-effect";

import { AppText as Text } from "../../components/AppText";
import { GlassSurface } from "../../components/GlassSurface";
import { tryOpenExternalUrl } from "../../lib/openExternalUrl";
import { useThemeColor } from "../../lib/useThemeColor";
import type { GitActionProgress } from "../../state/use-vcs-action-state";

const OVERLAY_LAYOUT_TRANSITION = LinearTransition.duration(220);
const AnimatedGlassSurface = Animated.createAnimatedComponent(GlassSurface);

export function GitActionProgressOverlay(props: {
readonly progress: GitActionProgress;
readonly onDismiss: () => void;
Expand Down Expand Up @@ -61,16 +66,9 @@ export function GitActionProgressOverlay(props: {
function OverlayContent(props: { readonly progress: GitActionProgress }) {
const { progress } = props;
const iconColor = useThemeColor("--color-icon");

const bgClass =
progress.phase === "error"
? "bg-red-50 dark:bg-red-950/80 border-red-200 dark:border-red-800"
: "bg-card border-border";

return (
<View
className={`flex-row items-center gap-2.5 rounded-2xl border px-3.5 py-3 shadow-lg shadow-black/10 ${bgClass}`}
>
const supportsGlass = Platform.OS === "ios" && isGlassEffectAPIAvailable();
const content = (
<>
<OverlayIcon phase={progress.phase} iconColor={iconColor} />

<View className="flex-1 gap-0.5">
Expand All @@ -89,7 +87,37 @@ function OverlayContent(props: { readonly progress: GitActionProgress }) {
{progress.prUrl ? (
<SymbolView name="arrow.up.right" size={13} tintColor={iconColor} type="monochrome" />
) : null}
</View>
</>
);

if (supportsGlass) {
return (
<AnimatedGlassSurface
chrome="none"
glassEffectStyle="regular"
layout={OVERLAY_LAYOUT_TRANSITION}
style={{
borderCurve: "continuous",
borderRadius: 26,
}}
>
<View className="flex-row items-center gap-2.5 px-3.5 py-3">{content}</View>
</AnimatedGlassSurface>
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Error chrome missing on glass path

Medium Severity

After the glass branch was added, progress.phase === "error" no longer affects the overlay shell on iOS when the glass API is available. The red background and border from bgClass apply only on the fallback Animated.View, so failed git actions on that path lose the full-card error treatment they had before this change.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit faf65cb. Configure here.

}

const bgClass =
progress.phase === "error"
? "bg-red-50 dark:bg-red-950/80 border-red-200 dark:border-red-800"
: "bg-card border-border";

return (
<Animated.View
layout={OVERLAY_LAYOUT_TRANSITION}
className={`flex-row items-center gap-2.5 rounded-[26px] border border-continuous px-3.5 py-3 shadow-lg shadow-black/10 ${bgClass}`}
>
{content}
</Animated.View>
);
}

Expand Down
Loading