@comergehq/studio 0.1.10 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -36,8 +36,8 @@ __export(index_exports, {
36
36
  module.exports = __toCommonJS(index_exports);
37
37
 
38
38
  // src/studio/ComergeStudio.tsx
39
- var React40 = __toESM(require("react"));
40
- var import_react_native54 = require("react-native");
39
+ var React42 = __toESM(require("react"));
40
+ var import_react_native55 = require("react-native");
41
41
  var import_bottom_sheet6 = require("@gorhom/bottom-sheet");
42
42
 
43
43
  // src/studio/bootstrap/StudioBootstrap.tsx
@@ -1812,25 +1812,76 @@ function RuntimeRenderer({ appKey, bundlePath, forcePreparing, renderToken, styl
1812
1812
  }
1813
1813
 
1814
1814
  // src/studio/ui/StudioOverlay.tsx
1815
- var React39 = __toESM(require("react"));
1816
- var import_react_native53 = require("react-native");
1815
+ var React41 = __toESM(require("react"));
1816
+ var import_react_native54 = require("react-native");
1817
1817
 
1818
1818
  // src/components/studio-sheet/StudioBottomSheet.tsx
1819
- var React9 = __toESM(require("react"));
1820
- var import_react_native8 = require("react-native");
1819
+ var React11 = __toESM(require("react"));
1820
+ var import_react_native9 = require("react-native");
1821
1821
  var import_bottom_sheet = __toESM(require("@gorhom/bottom-sheet"));
1822
1822
  var import_react_native_safe_area_context = require("react-native-safe-area-context");
1823
1823
 
1824
1824
  // src/components/studio-sheet/StudioSheetBackground.tsx
1825
- var import_react_native7 = require("react-native");
1825
+ var import_react_native8 = require("react-native");
1826
+ var import_liquid_glass2 = require("@callstack/liquid-glass");
1827
+
1828
+ // src/components/utils/ResettableLiquidGlassView.tsx
1829
+ var React10 = __toESM(require("react"));
1826
1830
  var import_liquid_glass = require("@callstack/liquid-glass");
1831
+
1832
+ // src/components/utils/liquidGlassReset.tsx
1833
+ var React9 = __toESM(require("react"));
1834
+ var import_react_native7 = require("react-native");
1827
1835
  var import_jsx_runtime4 = require("react/jsx-runtime");
1836
+ var LiquidGlassResetContext = React9.createContext(0);
1837
+ function LiquidGlassResetProvider({
1838
+ children,
1839
+ resetTriggers = []
1840
+ }) {
1841
+ const [token, setToken] = React9.useState(0);
1842
+ React9.useEffect(() => {
1843
+ if (import_react_native7.Platform.OS !== "ios") return;
1844
+ const onChange = (state) => {
1845
+ if (state === "active") setToken((t) => t + 1);
1846
+ };
1847
+ const sub = import_react_native7.AppState.addEventListener("change", onChange);
1848
+ return () => sub.remove();
1849
+ }, []);
1850
+ React9.useEffect(() => {
1851
+ setToken((t) => t + 1);
1852
+ }, resetTriggers);
1853
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(LiquidGlassResetContext.Provider, { value: token, children });
1854
+ }
1855
+ function useLiquidGlassResetToken() {
1856
+ return React9.useContext(LiquidGlassResetContext);
1857
+ }
1858
+
1859
+ // src/components/utils/ResettableLiquidGlassView.tsx
1860
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1861
+ function ResettableLiquidGlassView({ children, ...props }) {
1862
+ const token = useLiquidGlassResetToken();
1863
+ const [layoutBootKey, setLayoutBootKey] = React10.useState(0);
1864
+ const sawNonZeroLayoutRef = React10.useRef(false);
1865
+ const onLayout = (e) => {
1866
+ var _a;
1867
+ (_a = props.onLayout) == null ? void 0 : _a.call(props, e);
1868
+ const { width, height } = e.nativeEvent.layout;
1869
+ if (width > 0 && height > 0 && !sawNonZeroLayoutRef.current) {
1870
+ sawNonZeroLayoutRef.current = true;
1871
+ setLayoutBootKey((k) => k + 1);
1872
+ }
1873
+ };
1874
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_liquid_glass.LiquidGlassView, { ...props, onLayout, children }, `liquid-glass-${token}-${layoutBootKey}`);
1875
+ }
1876
+
1877
+ // src/components/studio-sheet/StudioSheetBackground.tsx
1878
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1828
1879
  function StudioSheetBackground({
1829
1880
  style,
1830
1881
  renderBackground
1831
1882
  }) {
1832
1883
  const theme = useTheme();
1833
- const radius = import_react_native7.Platform.OS === "ios" ? 39 : 16;
1884
+ const radius = import_react_native8.Platform.OS === "ios" ? 39 : 16;
1834
1885
  const fallbackBgColor = theme.scheme === "dark" ? "rgba(11, 8, 15, 0.85)" : "rgba(255, 255, 255, 0.85)";
1835
1886
  const secondaryBgBaseColor = theme.scheme === "dark" ? "rgb(24, 24, 27)" : "rgb(173, 173, 173)";
1836
1887
  const containerStyle = {
@@ -1840,18 +1891,18 @@ function StudioSheetBackground({
1840
1891
  overflow: "hidden"
1841
1892
  };
1842
1893
  if (renderBackground) {
1843
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_jsx_runtime4.Fragment, { children: renderBackground({ style: containerStyle }) });
1894
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_jsx_runtime6.Fragment, { children: renderBackground({ style: containerStyle }) });
1844
1895
  }
1845
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1846
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1847
- import_liquid_glass.LiquidGlassView,
1896
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
1897
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1898
+ ResettableLiquidGlassView,
1848
1899
  {
1849
- style: [containerStyle, !import_liquid_glass.isLiquidGlassSupported && { backgroundColor: fallbackBgColor }],
1900
+ style: [containerStyle, !import_liquid_glass2.isLiquidGlassSupported && { backgroundColor: fallbackBgColor }],
1850
1901
  effect: "regular"
1851
1902
  }
1852
1903
  ),
1853
- import_liquid_glass.isLiquidGlassSupported && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1854
- import_react_native7.View,
1904
+ import_liquid_glass2.isLiquidGlassSupported && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1905
+ import_react_native8.View,
1855
1906
  {
1856
1907
  style: [
1857
1908
  containerStyle,
@@ -1872,7 +1923,7 @@ function StudioSheetBackground({
1872
1923
  }
1873
1924
 
1874
1925
  // src/components/studio-sheet/StudioBottomSheet.tsx
1875
- var import_jsx_runtime5 = require("react/jsx-runtime");
1926
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1876
1927
  function StudioBottomSheet({
1877
1928
  open,
1878
1929
  onOpenChange,
@@ -1884,16 +1935,16 @@ function StudioBottomSheet({
1884
1935
  }) {
1885
1936
  const theme = useTheme();
1886
1937
  const insets = (0, import_react_native_safe_area_context.useSafeAreaInsets)();
1887
- const internalSheetRef = React9.useRef(null);
1938
+ const internalSheetRef = React11.useRef(null);
1888
1939
  const resolvedSheetRef = sheetRef ?? internalSheetRef;
1889
- const currentIndexRef = React9.useRef(open ? snapPoints.length - 1 : -1);
1890
- const lastAppStateRef = React9.useRef(import_react_native8.AppState.currentState);
1891
- React9.useEffect(() => {
1892
- const sub = import_react_native8.AppState.addEventListener("change", (state) => {
1940
+ const currentIndexRef = React11.useRef(open ? snapPoints.length - 1 : -1);
1941
+ const lastAppStateRef = React11.useRef(import_react_native9.AppState.currentState);
1942
+ React11.useEffect(() => {
1943
+ const sub = import_react_native9.AppState.addEventListener("change", (state) => {
1893
1944
  const prev = lastAppStateRef.current;
1894
1945
  lastAppStateRef.current = state;
1895
1946
  if (state === "background" || state === "inactive") {
1896
- import_react_native8.Keyboard.dismiss();
1947
+ import_react_native9.Keyboard.dismiss();
1897
1948
  return;
1898
1949
  }
1899
1950
  if (state !== "active") return;
@@ -1901,14 +1952,14 @@ function StudioBottomSheet({
1901
1952
  if (!sheet) return;
1902
1953
  const idx = currentIndexRef.current;
1903
1954
  if (open && idx >= 0) {
1904
- import_react_native8.Keyboard.dismiss();
1955
+ import_react_native9.Keyboard.dismiss();
1905
1956
  requestAnimationFrame(() => sheet.snapToIndex(idx));
1906
1957
  setTimeout(() => sheet.snapToIndex(idx), 120);
1907
1958
  }
1908
1959
  });
1909
1960
  return () => sub.remove();
1910
1961
  }, [open, resolvedSheetRef]);
1911
- React9.useEffect(() => {
1962
+ React11.useEffect(() => {
1912
1963
  const sheet = resolvedSheetRef.current;
1913
1964
  if (!sheet) return;
1914
1965
  if (open) {
@@ -1917,14 +1968,14 @@ function StudioBottomSheet({
1917
1968
  sheet.close();
1918
1969
  }
1919
1970
  }, [open, resolvedSheetRef, snapPoints.length]);
1920
- const handleChange = React9.useCallback(
1971
+ const handleChange = React11.useCallback(
1921
1972
  (index) => {
1922
1973
  currentIndexRef.current = index;
1923
1974
  onOpenChange == null ? void 0 : onOpenChange(index >= 0);
1924
1975
  },
1925
1976
  [onOpenChange]
1926
1977
  );
1927
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1978
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1928
1979
  import_bottom_sheet.default,
1929
1980
  {
1930
1981
  ref: resolvedSheetRef,
@@ -1934,25 +1985,25 @@ function StudioBottomSheet({
1934
1985
  enablePanDownToClose: true,
1935
1986
  enableContentPanningGesture: false,
1936
1987
  android_keyboardInputMode: "adjustResize",
1937
- backgroundComponent: (props) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(StudioSheetBackground, { ...props, renderBackground: background == null ? void 0 : background.renderBackground }),
1988
+ backgroundComponent: (props) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(StudioSheetBackground, { ...props, renderBackground: background == null ? void 0 : background.renderBackground }),
1938
1989
  topInset: insets.top,
1939
1990
  bottomInset: 0,
1940
1991
  handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
1941
1992
  onChange: handleChange,
1942
1993
  ...bottomSheetProps,
1943
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_native8.View, { style: { flex: 1, overflow: "hidden" }, children })
1994
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native9.View, { style: { flex: 1, overflow: "hidden" }, children })
1944
1995
  }
1945
1996
  );
1946
1997
  }
1947
1998
 
1948
1999
  // src/components/studio-sheet/StudioSheetPager.tsx
1949
- var React10 = __toESM(require("react"));
1950
- var import_react_native9 = require("react-native");
1951
- var import_jsx_runtime6 = require("react/jsx-runtime");
2000
+ var React12 = __toESM(require("react"));
2001
+ var import_react_native10 = require("react-native");
2002
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1952
2003
  function StudioSheetPager({ activePage, width, preview, chat, style }) {
1953
- const anim = React10.useRef(new import_react_native9.Animated.Value(activePage === "chat" ? 1 : 0)).current;
1954
- React10.useEffect(() => {
1955
- import_react_native9.Animated.spring(anim, {
2004
+ const anim = React12.useRef(new import_react_native10.Animated.Value(activePage === "chat" ? 1 : 0)).current;
2005
+ React12.useEffect(() => {
2006
+ import_react_native10.Animated.spring(anim, {
1956
2007
  toValue: activePage === "chat" ? 1 : 0,
1957
2008
  useNativeDriver: true,
1958
2009
  tension: 65,
@@ -1961,9 +2012,9 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
1961
2012
  }, [activePage, anim]);
1962
2013
  const previewTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [0, -width] });
1963
2014
  const chatTranslateX = anim.interpolate({ inputRange: [0, 1], outputRange: [width, 0] });
1964
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_native9.Animated.View, { style: [{ flex: 1 }, style], children: [
1965
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1966
- import_react_native9.Animated.View,
2015
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native10.Animated.View, { style: [{ flex: 1 }, style], children: [
2016
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2017
+ import_react_native10.Animated.View,
1967
2018
  {
1968
2019
  style: [
1969
2020
  {
@@ -1979,8 +2030,8 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
1979
2030
  children: preview
1980
2031
  }
1981
2032
  ),
1982
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1983
- import_react_native9.Animated.View,
2033
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2034
+ import_react_native10.Animated.View,
1984
2035
  {
1985
2036
  style: [
1986
2037
  {
@@ -2001,10 +2052,10 @@ function StudioSheetPager({ activePage, width, preview, chat, style }) {
2001
2052
 
2002
2053
  // src/components/floating-draggable-button/FloatingDraggableButton.tsx
2003
2054
  var import_react = require("react");
2004
- var import_react_native10 = require("react-native");
2055
+ var import_react_native11 = require("react-native");
2005
2056
  var Haptics = __toESM(require("expo-haptics"));
2006
2057
  var import_react_native_reanimated = __toESM(require("react-native-reanimated"));
2007
- var import_liquid_glass2 = require("@callstack/liquid-glass");
2058
+ var import_liquid_glass3 = require("@callstack/liquid-glass");
2008
2059
 
2009
2060
  // src/components/floating-draggable-button/constants.ts
2010
2061
  var DEFAULT_SIZE = 48;
@@ -2015,11 +2066,10 @@ var DEFAULT_OFFSET = {
2015
2066
  };
2016
2067
  var ENTER_SCALE_FROM = 0.3;
2017
2068
  var ENTER_ROTATION_FROM_DEG = -180;
2018
- var HIDDEN_OPACITY = 0.3;
2019
2069
  var PULSE_DURATION_MS = 900;
2020
2070
 
2021
2071
  // src/components/floating-draggable-button/FloatingDraggableButton.tsx
2022
- var import_jsx_runtime7 = require("react/jsx-runtime");
2072
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2023
2073
  var HIDDEN_OFFSET_X = 20;
2024
2074
  var SPRING_POSITION = { damping: 12, stiffness: 100, mass: 0.8 };
2025
2075
  var SPRING_SCALE_IN = { damping: 10, stiffness: 200 };
@@ -2027,8 +2077,6 @@ var SPRING_SCALE_OUT = { damping: 12, stiffness: 150 };
2027
2077
  var SPRING_ROTATION_IN = { damping: 15, stiffness: 80 };
2028
2078
  var SPRING_ROTATION_GRAB = { damping: 20 };
2029
2079
  var SPRING_SCALE_GRAB = { damping: 15, stiffness: 200 };
2030
- var TIMING_OPACITY_IN = { duration: 300, easing: import_react_native_reanimated.Easing.out(import_react_native_reanimated.Easing.ease) };
2031
- var TIMING_OPACITY_OUT = { duration: 250, easing: import_react_native_reanimated.Easing.in(import_react_native_reanimated.Easing.ease) };
2032
2080
  function clamp(value, min, max) {
2033
2081
  "worklet";
2034
2082
  return Math.max(min, Math.min(max, value));
@@ -2060,7 +2108,7 @@ function FloatingDraggableButton({
2060
2108
  backgroundColor
2061
2109
  }) {
2062
2110
  const theme = useTheme();
2063
- const { width, height } = (0, import_react_native10.useWindowDimensions)();
2111
+ const { width, height } = (0, import_react_native11.useWindowDimensions)();
2064
2112
  const isDanger = variant === "danger";
2065
2113
  const onPressRef = (0, import_react.useRef)(onPress);
2066
2114
  (0, import_react.useEffect)(() => {
@@ -2075,30 +2123,20 @@ function FloatingDraggableButton({
2075
2123
  const translateY = (0, import_react_native_reanimated.useSharedValue)(getHiddenTranslateY(height));
2076
2124
  const scale = (0, import_react_native_reanimated.useSharedValue)(ENTER_SCALE_FROM);
2077
2125
  const rotation = (0, import_react_native_reanimated.useSharedValue)(ENTER_ROTATION_FROM_DEG);
2078
- const opacity = (0, import_react_native_reanimated.useSharedValue)(1);
2079
2126
  const borderPulse = (0, import_react_native_reanimated.useSharedValue)(0);
2080
2127
  const startPos = (0, import_react.useRef)({ x: 0, y: 0 });
2081
2128
  const isAnimatingOut = (0, import_react.useRef)(false);
2082
2129
  const animateToHidden = (0, import_react.useCallback)(
2083
2130
  (options) => {
2084
- translateX.value = (0, import_react_native_reanimated.withSpring)(getHiddenTranslateX(size), SPRING_POSITION);
2131
+ const finish = options == null ? void 0 : options.onFinish;
2132
+ translateX.value = (0, import_react_native_reanimated.withSpring)(getHiddenTranslateX(size), SPRING_POSITION, (finished) => {
2133
+ if (finished && finish) (0, import_react_native_reanimated.runOnJS)(finish)();
2134
+ });
2085
2135
  translateY.value = (0, import_react_native_reanimated.withSpring)(getHiddenTranslateY(height), SPRING_POSITION);
2086
2136
  scale.value = (0, import_react_native_reanimated.withSpring)(ENTER_SCALE_FROM, SPRING_SCALE_IN);
2087
2137
  rotation.value = (0, import_react_native_reanimated.withSpring)(ENTER_ROTATION_FROM_DEG, SPRING_ROTATION_IN);
2088
- const finish = options == null ? void 0 : options.onFinish;
2089
- if (!finish) {
2090
- opacity.value = (0, import_react_native_reanimated.withTiming)(HIDDEN_OPACITY, TIMING_OPACITY_OUT);
2091
- return;
2092
- }
2093
- opacity.value = (0, import_react_native_reanimated.withTiming)(
2094
- HIDDEN_OPACITY,
2095
- TIMING_OPACITY_OUT,
2096
- (finished) => {
2097
- if (finished) (0, import_react_native_reanimated.runOnJS)(finish)();
2098
- }
2099
- );
2100
2138
  },
2101
- [height, opacity, rotation, scale, size, translateX, translateY]
2139
+ [height, rotation, scale, size, translateX, translateY]
2102
2140
  );
2103
2141
  const animateOut = (0, import_react.useCallback)(() => {
2104
2142
  if (isAnimatingOut.current) return;
@@ -2138,8 +2176,7 @@ function FloatingDraggableButton({
2138
2176
  (0, import_react_native_reanimated.withSpring)(1, SPRING_SCALE_OUT)
2139
2177
  );
2140
2178
  rotation.value = (0, import_react_native_reanimated.withSpring)(0, SPRING_ROTATION_IN);
2141
- opacity.value = (0, import_react_native_reanimated.withTiming)(1, TIMING_OPACITY_IN);
2142
- }, [height, offset.bottom, offset.left, opacity, rotation, scale, size, translateX, translateY]);
2179
+ }, [height, offset.bottom, offset.left, rotation, scale, size, translateX, translateY]);
2143
2180
  (0, import_react.useEffect)(() => {
2144
2181
  const timer = setTimeout(() => {
2145
2182
  if (visible) {
@@ -2163,7 +2200,7 @@ function FloatingDraggableButton({
2163
2200
  }
2164
2201
  }, [forceShowTrigger, visible, animateIn]);
2165
2202
  const panResponder = (0, import_react.useRef)(
2166
- import_react_native10.PanResponder.create({
2203
+ import_react_native11.PanResponder.create({
2167
2204
  onStartShouldSetPanResponder: () => true,
2168
2205
  onMoveShouldSetPanResponder: () => true,
2169
2206
  onPanResponderGrant: () => {
@@ -2195,8 +2232,7 @@ function FloatingDraggableButton({
2195
2232
  { translateY: translateY.value },
2196
2233
  { scale: scale.value },
2197
2234
  { rotate: `${rotation.value}deg` }
2198
- ],
2199
- opacity: opacity.value
2235
+ ]
2200
2236
  }));
2201
2237
  const borderAnimatedStyle = (0, import_react_native_reanimated.useAnimatedStyle)(() => {
2202
2238
  const borderColor = (0, import_react_native_reanimated.interpolateColor)(
@@ -2210,7 +2246,7 @@ function FloatingDraggableButton({
2210
2246
  borderRadius: size / 2
2211
2247
  };
2212
2248
  });
2213
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
2249
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
2214
2250
  import_react_native_reanimated.default.View,
2215
2251
  {
2216
2252
  ...panResponder.panHandlers,
@@ -2219,31 +2255,31 @@ function FloatingDraggableButton({
2219
2255
  accessibilityRole: "button",
2220
2256
  accessibilityLabel: ariaLabel,
2221
2257
  children: [
2222
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native_reanimated.default.View, { style: [{ width: size, height: size, borderRadius: size / 2 }, borderAnimatedStyle], children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2223
- import_liquid_glass2.LiquidGlassView,
2258
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native_reanimated.default.View, { style: [{ width: size, height: size, borderRadius: size / 2 }, borderAnimatedStyle], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2259
+ ResettableLiquidGlassView,
2224
2260
  {
2225
- style: [{ flex: 1, borderRadius: size / 2 }, !import_liquid_glass2.isLiquidGlassSupported && { backgroundColor: fallbackBgColor }],
2261
+ style: [{ flex: 1, borderRadius: size / 2 }, !import_liquid_glass3.isLiquidGlassSupported && { backgroundColor: fallbackBgColor }],
2226
2262
  interactive: true,
2227
2263
  effect: "clear",
2228
- children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
2229
- import_react_native10.Pressable,
2264
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2265
+ import_react_native11.Pressable,
2230
2266
  {
2231
2267
  onPress: () => {
2232
2268
  if (!disabled) animateOut();
2233
2269
  },
2234
2270
  style: styles.buttonInner,
2235
2271
  android_ripple: { color: "rgba(255, 255, 255, 0.3)", borderless: true },
2236
- children: children ?? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native10.View, {})
2272
+ children: children ?? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native11.View, {})
2237
2273
  }
2238
2274
  )
2239
2275
  }
2240
2276
  ) }),
2241
- badgeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native10.View, { style: [styles.badge, { backgroundColor: theme.colors.danger }], children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_native10.Text, { style: [styles.badgeText, { color: theme.colors.onDanger }], children: badgeCount > 99 ? "99+" : badgeCount }) })
2277
+ badgeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native11.View, { style: [styles.badge, { backgroundColor: theme.colors.danger }], children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native11.Text, { style: [styles.badgeText, { color: theme.colors.onDanger }], children: badgeCount > 99 ? "99+" : badgeCount }) })
2242
2278
  ]
2243
2279
  }
2244
2280
  );
2245
2281
  }
2246
- var styles = import_react_native10.StyleSheet.create({
2282
+ var styles = import_react_native11.StyleSheet.create({
2247
2283
  floatingButton: {
2248
2284
  position: "absolute",
2249
2285
  justifyContent: "center",
@@ -2279,8 +2315,8 @@ var styles = import_react_native10.StyleSheet.create({
2279
2315
  });
2280
2316
 
2281
2317
  // src/components/overlays/EdgeGlowFrame.tsx
2282
- var React11 = __toESM(require("react"));
2283
- var import_react_native11 = require("react-native");
2318
+ var React13 = __toESM(require("react"));
2319
+ var import_react_native12 = require("react-native");
2284
2320
  var import_expo_linear_gradient = require("expo-linear-gradient");
2285
2321
 
2286
2322
  // src/components/utils/color.ts
@@ -2299,7 +2335,7 @@ function withAlpha(color, alpha) {
2299
2335
  }
2300
2336
 
2301
2337
  // src/components/overlays/EdgeGlowFrame.tsx
2302
- var import_jsx_runtime8 = require("react/jsx-runtime");
2338
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2303
2339
  function baseColor(role, theme) {
2304
2340
  switch (role) {
2305
2341
  case "danger":
@@ -2322,9 +2358,9 @@ function EdgeGlowFrame({
2322
2358
  }) {
2323
2359
  const theme = useTheme();
2324
2360
  const alpha = Math.max(0, Math.min(1, intensity));
2325
- const anim = React11.useRef(new import_react_native11.Animated.Value(visible ? 1 : 0)).current;
2326
- React11.useEffect(() => {
2327
- import_react_native11.Animated.timing(anim, {
2361
+ const anim = React13.useRef(new import_react_native12.Animated.Value(visible ? 1 : 0)).current;
2362
+ React13.useEffect(() => {
2363
+ import_react_native12.Animated.timing(anim, {
2328
2364
  toValue: visible ? 1 : 0,
2329
2365
  duration: 300,
2330
2366
  useNativeDriver: true
@@ -2333,8 +2369,8 @@ function EdgeGlowFrame({
2333
2369
  const c = baseColor(role, theme);
2334
2370
  const strong = withAlpha(c, 0.6 * alpha);
2335
2371
  const soft = withAlpha(c, 0.22 * alpha);
2336
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_native11.Animated.View, { pointerEvents: "none", style: [{ position: "absolute", inset: 0, opacity: anim }, style], children: [
2337
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native11.View, { style: { position: "absolute", top: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2372
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_native12.Animated.View, { pointerEvents: "none", style: [{ position: "absolute", inset: 0, opacity: anim }, style], children: [
2373
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: { position: "absolute", top: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2338
2374
  import_expo_linear_gradient.LinearGradient,
2339
2375
  {
2340
2376
  colors: [strong, soft, "transparent"],
@@ -2343,7 +2379,7 @@ function EdgeGlowFrame({
2343
2379
  style: { width: "100%", height: "100%" }
2344
2380
  }
2345
2381
  ) }),
2346
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native11.View, { style: { position: "absolute", bottom: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2382
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: { position: "absolute", bottom: 0, left: 0, right: 0, height: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2347
2383
  import_expo_linear_gradient.LinearGradient,
2348
2384
  {
2349
2385
  colors: ["transparent", soft, strong],
@@ -2352,7 +2388,7 @@ function EdgeGlowFrame({
2352
2388
  style: { width: "100%", height: "100%" }
2353
2389
  }
2354
2390
  ) }),
2355
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native11.View, { style: { position: "absolute", top: 0, bottom: 0, left: 0, width: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2391
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: { position: "absolute", top: 0, bottom: 0, left: 0, width: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2356
2392
  import_expo_linear_gradient.LinearGradient,
2357
2393
  {
2358
2394
  colors: [strong, soft, "transparent"],
@@ -2361,7 +2397,7 @@ function EdgeGlowFrame({
2361
2397
  style: { width: "100%", height: "100%" }
2362
2398
  }
2363
2399
  ) }),
2364
- /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_native11.View, { style: { position: "absolute", top: 0, bottom: 0, right: 0, width: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2400
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native12.View, { style: { position: "absolute", top: 0, bottom: 0, right: 0, width: thickness }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2365
2401
  import_expo_linear_gradient.LinearGradient,
2366
2402
  {
2367
2403
  colors: ["transparent", soft, strong],
@@ -2374,13 +2410,13 @@ function EdgeGlowFrame({
2374
2410
  }
2375
2411
 
2376
2412
  // src/components/draw/DrawModeOverlay.tsx
2377
- var React14 = __toESM(require("react"));
2378
- var import_react_native15 = require("react-native");
2413
+ var React16 = __toESM(require("react"));
2414
+ var import_react_native16 = require("react-native");
2379
2415
  var import_react_native_view_shot = require("react-native-view-shot");
2380
2416
 
2381
2417
  // src/components/draw/DrawSurface.tsx
2382
- var React12 = __toESM(require("react"));
2383
- var import_react_native12 = require("react-native");
2418
+ var React14 = __toESM(require("react"));
2419
+ var import_react_native13 = require("react-native");
2384
2420
  var import_react_native_svg = __toESM(require("react-native-svg"));
2385
2421
 
2386
2422
  // src/components/draw/strokes.ts
@@ -2402,7 +2438,7 @@ function pointsToSmoothPath(points) {
2402
2438
  }
2403
2439
 
2404
2440
  // src/components/draw/DrawSurface.tsx
2405
- var import_jsx_runtime9 = require("react/jsx-runtime");
2441
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2406
2442
  function DrawSurface({
2407
2443
  color,
2408
2444
  strokeWidth,
@@ -2411,25 +2447,25 @@ function DrawSurface({
2411
2447
  style,
2412
2448
  minDistance = 1
2413
2449
  }) {
2414
- const [renderTick, setRenderTick] = React12.useState(0);
2415
- const currentPointsRef = React12.useRef([]);
2416
- const rafRef = React12.useRef(null);
2417
- const triggerRender = React12.useCallback(() => {
2450
+ const [renderTick, setRenderTick] = React14.useState(0);
2451
+ const currentPointsRef = React14.useRef([]);
2452
+ const rafRef = React14.useRef(null);
2453
+ const triggerRender = React14.useCallback(() => {
2418
2454
  if (rafRef.current !== null) return;
2419
2455
  rafRef.current = requestAnimationFrame(() => {
2420
2456
  rafRef.current = null;
2421
2457
  setRenderTick((n) => n + 1);
2422
2458
  });
2423
2459
  }, []);
2424
- React12.useEffect(() => () => {
2460
+ React14.useEffect(() => () => {
2425
2461
  if (rafRef.current !== null) cancelAnimationFrame(rafRef.current);
2426
2462
  }, []);
2427
- const onStart = React12.useCallback((e) => {
2463
+ const onStart = React14.useCallback((e) => {
2428
2464
  const { locationX, locationY } = e.nativeEvent;
2429
2465
  currentPointsRef.current = [{ x: locationX, y: locationY }];
2430
2466
  triggerRender();
2431
2467
  }, [triggerRender]);
2432
- const onMove = React12.useCallback((e, _g) => {
2468
+ const onMove = React14.useCallback((e, _g) => {
2433
2469
  const { locationX, locationY } = e.nativeEvent;
2434
2470
  const pts = currentPointsRef.current;
2435
2471
  if (pts.length > 0) {
@@ -2442,7 +2478,7 @@ function DrawSurface({
2442
2478
  currentPointsRef.current = [...pts, { x: locationX, y: locationY }];
2443
2479
  triggerRender();
2444
2480
  }, [minDistance, triggerRender]);
2445
- const onEnd = React12.useCallback(() => {
2481
+ const onEnd = React14.useCallback(() => {
2446
2482
  const points = currentPointsRef.current;
2447
2483
  if (points.length > 0) {
2448
2484
  onAddStroke({ points, color, width: strokeWidth });
@@ -2450,8 +2486,8 @@ function DrawSurface({
2450
2486
  currentPointsRef.current = [];
2451
2487
  triggerRender();
2452
2488
  }, [color, onAddStroke, strokeWidth, triggerRender]);
2453
- const panResponder = React12.useMemo(
2454
- () => import_react_native12.PanResponder.create({
2489
+ const panResponder = React14.useMemo(
2490
+ () => import_react_native13.PanResponder.create({
2455
2491
  onStartShouldSetPanResponder: () => true,
2456
2492
  onMoveShouldSetPanResponder: () => true,
2457
2493
  onPanResponderGrant: onStart,
@@ -2463,11 +2499,11 @@ function DrawSurface({
2463
2499
  );
2464
2500
  const currentPath = pointsToSmoothPath(currentPointsRef.current);
2465
2501
  void renderTick;
2466
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react_native12.View, { style: [import_react_native12.StyleSheet.absoluteFill, styles2.container, style], ...panResponder.panHandlers, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_react_native_svg.default, { style: import_react_native12.StyleSheet.absoluteFill, width: "100%", height: "100%", children: [
2502
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native13.View, { style: [import_react_native13.StyleSheet.absoluteFill, styles2.container, style], ...panResponder.panHandlers, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native_svg.default, { style: import_react_native13.StyleSheet.absoluteFill, width: "100%", height: "100%", children: [
2467
2503
  strokes.map((s, idx) => {
2468
2504
  const d = pointsToSmoothPath(s.points);
2469
2505
  if (!d) return null;
2470
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2506
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2471
2507
  import_react_native_svg.Path,
2472
2508
  {
2473
2509
  d,
@@ -2480,7 +2516,7 @@ function DrawSurface({
2480
2516
  idx
2481
2517
  );
2482
2518
  }),
2483
- currentPath ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2519
+ currentPath ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2484
2520
  import_react_native_svg.Path,
2485
2521
  {
2486
2522
  d: currentPath,
@@ -2493,15 +2529,15 @@ function DrawSurface({
2493
2529
  ) : null
2494
2530
  ] }) });
2495
2531
  }
2496
- var styles2 = import_react_native12.StyleSheet.create({
2532
+ var styles2 = import_react_native13.StyleSheet.create({
2497
2533
  container: {
2498
2534
  zIndex: 5
2499
2535
  }
2500
2536
  });
2501
2537
 
2502
2538
  // src/components/draw/DrawToolbar.tsx
2503
- var React13 = __toESM(require("react"));
2504
- var import_react_native14 = require("react-native");
2539
+ var React15 = __toESM(require("react"));
2540
+ var import_react_native15 = require("react-native");
2505
2541
  var import_react_native_safe_area_context2 = require("react-native-safe-area-context");
2506
2542
  var import_lucide_react_native = require("lucide-react-native");
2507
2543
 
@@ -2520,8 +2556,8 @@ async function impact(style) {
2520
2556
  }
2521
2557
 
2522
2558
  // src/components/draw/DrawColorPicker.tsx
2523
- var import_react_native13 = require("react-native");
2524
- var import_jsx_runtime10 = require("react/jsx-runtime");
2559
+ var import_react_native14 = require("react-native");
2560
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2525
2561
  function DrawColorPicker({
2526
2562
  colors,
2527
2563
  selected,
@@ -2555,10 +2591,10 @@ function DrawColorPicker({
2555
2591
  return { ...base, ...selectedStyle, ...whiteStyle };
2556
2592
  };
2557
2593
  if (!expanded) {
2558
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native13.Pressable, { onPress: onToggle, style: [swatchStyle(selected, true), style] });
2594
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native14.Pressable, { onPress: onToggle, style: [swatchStyle(selected, true), style] });
2559
2595
  }
2560
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_native13.View, { style: [{ flexDirection: "row", alignItems: "center", gap: 8 }, style], children: colors.map((c, idx) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2561
- import_react_native13.Pressable,
2596
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_react_native14.View, { style: [{ flexDirection: "row", alignItems: "center", gap: 8 }, style], children: colors.map((c, idx) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2597
+ import_react_native14.Pressable,
2562
2598
  {
2563
2599
  onPress: () => {
2564
2600
  onSelect(c);
@@ -2571,7 +2607,7 @@ function DrawColorPicker({
2571
2607
  }
2572
2608
 
2573
2609
  // src/components/draw/DrawToolbar.tsx
2574
- var import_jsx_runtime11 = require("react/jsx-runtime");
2610
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2575
2611
  function DrawToolbar({
2576
2612
  colors,
2577
2613
  selectedColor,
@@ -2589,14 +2625,14 @@ function DrawToolbar({
2589
2625
  style
2590
2626
  }) {
2591
2627
  const insets = (0, import_react_native_safe_area_context2.useSafeAreaInsets)();
2592
- const { width: screenWidth, height: screenHeight } = (0, import_react_native14.useWindowDimensions)();
2593
- const [expanded, setExpanded] = React13.useState(false);
2594
- const pos = React13.useRef(new import_react_native14.Animated.ValueXY({ x: screenWidth / 2 - 110, y: -140 })).current;
2595
- const start = React13.useRef({ x: 0, y: 0 });
2596
- const currentPos = React13.useRef({ x: 0, y: 0 });
2597
- React13.useEffect(() => {
2628
+ const { width: screenWidth, height: screenHeight } = (0, import_react_native15.useWindowDimensions)();
2629
+ const [expanded, setExpanded] = React15.useState(false);
2630
+ const pos = React15.useRef(new import_react_native15.Animated.ValueXY({ x: screenWidth / 2 - 110, y: -140 })).current;
2631
+ const start = React15.useRef({ x: 0, y: 0 });
2632
+ const currentPos = React15.useRef({ x: 0, y: 0 });
2633
+ React15.useEffect(() => {
2598
2634
  if (hidden) return;
2599
- import_react_native14.Animated.spring(pos.y, {
2635
+ import_react_native15.Animated.spring(pos.y, {
2600
2636
  toValue: insets.top + 60,
2601
2637
  useNativeDriver: true,
2602
2638
  damping: 12,
@@ -2604,7 +2640,7 @@ function DrawToolbar({
2604
2640
  mass: 0.8
2605
2641
  }).start();
2606
2642
  }, [hidden, insets.top, pos.y]);
2607
- React13.useEffect(() => {
2643
+ React15.useEffect(() => {
2608
2644
  const id = pos.addListener((v) => {
2609
2645
  currentPos.current = { x: v.x ?? 0, y: v.y ?? 0 };
2610
2646
  });
@@ -2612,7 +2648,7 @@ function DrawToolbar({
2612
2648
  pos.removeListener(id);
2613
2649
  };
2614
2650
  }, [pos]);
2615
- const clamp2 = React13.useCallback(
2651
+ const clamp2 = React15.useCallback(
2616
2652
  (x, y) => {
2617
2653
  const minX = 10;
2618
2654
  const maxX = Math.max(10, screenWidth - 230);
@@ -2622,8 +2658,8 @@ function DrawToolbar({
2622
2658
  },
2623
2659
  [insets.top, screenHeight, screenWidth]
2624
2660
  );
2625
- const panResponder = React13.useMemo(
2626
- () => import_react_native14.PanResponder.create({
2661
+ const panResponder = React15.useMemo(
2662
+ () => import_react_native15.PanResponder.create({
2627
2663
  onStartShouldSetPanResponder: () => false,
2628
2664
  onMoveShouldSetPanResponder: (_e, g) => Math.abs(g.dx) > 5 || Math.abs(g.dy) > 5,
2629
2665
  onPanResponderGrant: () => {
@@ -2635,7 +2671,7 @@ function DrawToolbar({
2635
2671
  },
2636
2672
  onPanResponderRelease: () => {
2637
2673
  const next = clamp2(currentPos.current.x, currentPos.current.y);
2638
- import_react_native14.Animated.spring(pos, { toValue: next, useNativeDriver: true }).start();
2674
+ import_react_native15.Animated.spring(pos, { toValue: next, useNativeDriver: true }).start();
2639
2675
  }
2640
2676
  }),
2641
2677
  [clamp2, pos]
@@ -2650,9 +2686,9 @@ function DrawToolbar({
2650
2686
  children
2651
2687
  }) {
2652
2688
  const isDisabled = Boolean(disabled) || Boolean(capturingDisabled);
2653
- const [pressed, setPressed] = React13.useState(false);
2654
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2655
- import_react_native14.View,
2689
+ const [pressed, setPressed] = React15.useState(false);
2690
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2691
+ import_react_native15.View,
2656
2692
  {
2657
2693
  style: {
2658
2694
  width: 28,
@@ -2663,8 +2699,8 @@ function DrawToolbar({
2663
2699
  backgroundColor,
2664
2700
  opacity: isDisabled ? 0.5 : pressed ? 0.85 : 1
2665
2701
  },
2666
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2667
- import_react_native14.Pressable,
2702
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2703
+ import_react_native15.Pressable,
2668
2704
  {
2669
2705
  accessibilityRole: "button",
2670
2706
  accessibilityLabel,
@@ -2680,8 +2716,8 @@ function DrawToolbar({
2680
2716
  }
2681
2717
  );
2682
2718
  }
2683
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2684
- import_react_native14.Animated.View,
2719
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2720
+ import_react_native15.Animated.View,
2685
2721
  {
2686
2722
  style: [
2687
2723
  {
@@ -2697,8 +2733,8 @@ function DrawToolbar({
2697
2733
  style
2698
2734
  ],
2699
2735
  ...panResponder.panHandlers,
2700
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2701
- import_react_native14.View,
2736
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2737
+ import_react_native15.View,
2702
2738
  {
2703
2739
  style: {
2704
2740
  backgroundColor: "#F43F5E",
@@ -2706,9 +2742,9 @@ function DrawToolbar({
2706
2742
  padding: 12,
2707
2743
  minWidth: 220
2708
2744
  },
2709
- children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_react_native14.View, { style: { flexDirection: "row", alignItems: "center", gap: 8 }, children: [
2710
- renderDragHandle ? renderDragHandle() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react_native.GripVertical, { size: 20, color: "rgba(255, 255, 255, 0.6)" }),
2711
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2745
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_react_native15.View, { style: { flexDirection: "row", alignItems: "center", gap: 8 }, children: [
2746
+ renderDragHandle ? renderDragHandle() : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react_native.GripVertical, { size: 20, color: "rgba(255, 255, 255, 0.6)" }),
2747
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2712
2748
  DrawColorPicker,
2713
2749
  {
2714
2750
  colors,
@@ -2724,8 +2760,8 @@ function DrawToolbar({
2724
2760
  }
2725
2761
  }
2726
2762
  ),
2727
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native14.View, { style: { width: 1, height: 20, backgroundColor: "rgba(255, 255, 255, 0.3)", marginHorizontal: 4 } }),
2728
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2763
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.View, { style: { width: 1, height: 20, backgroundColor: "rgba(255, 255, 255, 0.3)", marginHorizontal: 4 } }),
2764
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2729
2765
  CircleActionButton,
2730
2766
  {
2731
2767
  accessibilityLabel: "Undo",
@@ -2736,10 +2772,10 @@ function DrawToolbar({
2736
2772
  void impact("light");
2737
2773
  onUndo();
2738
2774
  },
2739
- children: renderUndoIcon ? renderUndoIcon() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react_native.Undo2, { size: 16, color: canUndo ? "#FFFFFF" : "rgba(255,255,255,0.4)" })
2775
+ children: renderUndoIcon ? renderUndoIcon() : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react_native.Undo2, { size: 16, color: canUndo ? "#FFFFFF" : "rgba(255,255,255,0.4)" })
2740
2776
  }
2741
2777
  ),
2742
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2778
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2743
2779
  CircleActionButton,
2744
2780
  {
2745
2781
  accessibilityLabel: "Cancel",
@@ -2749,10 +2785,10 @@ function DrawToolbar({
2749
2785
  void impact("medium");
2750
2786
  onCancel();
2751
2787
  },
2752
- children: renderCancelIcon ? renderCancelIcon() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react_native.X, { size: 16, color: "#FFFFFF" })
2788
+ children: renderCancelIcon ? renderCancelIcon() : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react_native.X, { size: 16, color: "#FFFFFF" })
2753
2789
  }
2754
2790
  ),
2755
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2791
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2756
2792
  CircleActionButton,
2757
2793
  {
2758
2794
  accessibilityLabel: "Done",
@@ -2762,7 +2798,7 @@ function DrawToolbar({
2762
2798
  void impact("medium");
2763
2799
  onDone();
2764
2800
  },
2765
- children: capturing ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react_native14.ActivityIndicator, { color: "#FFFFFF", size: "small" }) : renderDoneIcon ? renderDoneIcon() : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react_native.Check, { size: 16, color: "#FFFFFF" })
2801
+ children: capturing ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native15.ActivityIndicator, { color: "#FFFFFF", size: "small" }) : renderDoneIcon ? renderDoneIcon() : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react_native.Check, { size: 16, color: "#FFFFFF" })
2766
2802
  }
2767
2803
  )
2768
2804
  ] })
@@ -2773,7 +2809,7 @@ function DrawToolbar({
2773
2809
  }
2774
2810
 
2775
2811
  // src/components/draw/DrawModeOverlay.tsx
2776
- var import_jsx_runtime12 = require("react/jsx-runtime");
2812
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2777
2813
  function DrawModeOverlay({
2778
2814
  visible,
2779
2815
  captureTargetRef,
@@ -2788,7 +2824,7 @@ function DrawModeOverlay({
2788
2824
  renderDragHandle
2789
2825
  }) {
2790
2826
  const theme = useTheme();
2791
- const defaultPalette = React14.useMemo(
2827
+ const defaultPalette = React16.useMemo(
2792
2828
  () => [
2793
2829
  "#EF4444",
2794
2830
  // Red
@@ -2806,11 +2842,11 @@ function DrawModeOverlay({
2806
2842
  []
2807
2843
  );
2808
2844
  const colors = palette && palette.length > 0 ? palette : defaultPalette;
2809
- const [selectedColor, setSelectedColor] = React14.useState(colors[0] ?? "#EF4444");
2810
- const [strokes, setStrokes] = React14.useState([]);
2811
- const [capturing, setCapturing] = React14.useState(false);
2812
- const [hideUi, setHideUi] = React14.useState(false);
2813
- React14.useEffect(() => {
2845
+ const [selectedColor, setSelectedColor] = React16.useState(colors[0] ?? "#EF4444");
2846
+ const [strokes, setStrokes] = React16.useState([]);
2847
+ const [capturing, setCapturing] = React16.useState(false);
2848
+ const [hideUi, setHideUi] = React16.useState(false);
2849
+ React16.useEffect(() => {
2814
2850
  if (!visible) return;
2815
2851
  setStrokes([]);
2816
2852
  setSelectedColor(colors[0] ?? "#EF4444");
@@ -2818,14 +2854,14 @@ function DrawModeOverlay({
2818
2854
  setHideUi(false);
2819
2855
  }, [colors, visible]);
2820
2856
  const canUndo = strokes.length > 0;
2821
- const handleUndo = React14.useCallback(() => {
2857
+ const handleUndo = React16.useCallback(() => {
2822
2858
  setStrokes((prev) => prev.slice(0, -1));
2823
2859
  }, []);
2824
- const handleCancel = React14.useCallback(() => {
2860
+ const handleCancel = React16.useCallback(() => {
2825
2861
  setStrokes([]);
2826
2862
  onCancel();
2827
2863
  }, [onCancel]);
2828
- const handleDone = React14.useCallback(async () => {
2864
+ const handleDone = React16.useCallback(async () => {
2829
2865
  if (!captureTargetRef.current || capturing) return;
2830
2866
  try {
2831
2867
  setCapturing(true);
@@ -2847,9 +2883,9 @@ function DrawModeOverlay({
2847
2883
  }
2848
2884
  }, [captureTargetRef, capturing, onCapture]);
2849
2885
  if (!visible) return null;
2850
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_react_native15.View, { style: [import_react_native15.StyleSheet.absoluteFill, styles3.root, style], pointerEvents: "box-none", children: [
2851
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(EdgeGlowFrame, { visible: !hideUi, role: "danger", thickness: 50, intensity: 1 }),
2852
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2886
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_react_native16.View, { style: [import_react_native16.StyleSheet.absoluteFill, styles3.root, style], pointerEvents: "box-none", children: [
2887
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(EdgeGlowFrame, { visible: !hideUi, role: "danger", thickness: 50, intensity: 1 }),
2888
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2853
2889
  DrawSurface,
2854
2890
  {
2855
2891
  color: selectedColor,
@@ -2858,7 +2894,7 @@ function DrawModeOverlay({
2858
2894
  onAddStroke: (stroke) => setStrokes((prev) => [...prev, stroke])
2859
2895
  }
2860
2896
  ),
2861
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2897
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2862
2898
  DrawToolbar,
2863
2899
  {
2864
2900
  hidden: hideUi,
@@ -2878,32 +2914,32 @@ function DrawModeOverlay({
2878
2914
  )
2879
2915
  ] });
2880
2916
  }
2881
- var styles3 = import_react_native15.StyleSheet.create({
2917
+ var styles3 = import_react_native16.StyleSheet.create({
2882
2918
  root: {
2883
2919
  zIndex: 9999
2884
2920
  }
2885
2921
  });
2886
2922
 
2887
2923
  // src/components/comments/AppCommentsSheet.tsx
2888
- var React21 = __toESM(require("react"));
2889
- var import_react_native21 = require("react-native");
2924
+ var React23 = __toESM(require("react"));
2925
+ var import_react_native22 = require("react-native");
2890
2926
  var import_bottom_sheet3 = require("@gorhom/bottom-sheet");
2891
2927
  var import_react_native_safe_area_context3 = require("react-native-safe-area-context");
2892
- var import_liquid_glass4 = require("@callstack/liquid-glass");
2928
+ var import_liquid_glass5 = require("@callstack/liquid-glass");
2893
2929
  var import_lucide_react_native4 = require("lucide-react-native");
2894
2930
 
2895
2931
  // src/components/chat/ChatComposer.tsx
2896
- var React16 = __toESM(require("react"));
2897
- var import_react_native17 = require("react-native");
2898
- var import_liquid_glass3 = require("@callstack/liquid-glass");
2932
+ var React18 = __toESM(require("react"));
2933
+ var import_react_native18 = require("react-native");
2934
+ var import_liquid_glass4 = require("@callstack/liquid-glass");
2899
2935
  var import_lucide_react_native3 = require("lucide-react-native");
2900
2936
 
2901
2937
  // src/components/chat/MultilineTextInput.tsx
2902
- var React15 = __toESM(require("react"));
2903
- var import_react_native16 = require("react-native");
2938
+ var React17 = __toESM(require("react"));
2939
+ var import_react_native17 = require("react-native");
2904
2940
  var import_bottom_sheet2 = require("@gorhom/bottom-sheet");
2905
- var import_jsx_runtime13 = require("react/jsx-runtime");
2906
- var MultilineTextInput = React15.forwardRef(function MultilineTextInput2({ useBottomSheetTextInput = false, placeholder, placeholderTextColor, style, ...props }, ref) {
2941
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2942
+ var MultilineTextInput = React17.forwardRef(function MultilineTextInput2({ useBottomSheetTextInput = false, placeholder, placeholderTextColor, style, ...props }, ref) {
2907
2943
  const theme = useTheme();
2908
2944
  const baseStyle = {
2909
2945
  minHeight: 44,
@@ -2923,12 +2959,12 @@ var MultilineTextInput = React15.forwardRef(function MultilineTextInput2({ useBo
2923
2959
  style: [baseStyle, style],
2924
2960
  textAlignVertical: "top"
2925
2961
  };
2926
- return useBottomSheetTextInput ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_bottom_sheet2.BottomSheetTextInput, { ref, ...commonProps }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_react_native16.TextInput, { ref, ...commonProps });
2962
+ return useBottomSheetTextInput ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_bottom_sheet2.BottomSheetTextInput, { ref, ...commonProps }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native17.TextInput, { ref, ...commonProps });
2927
2963
  });
2928
2964
 
2929
2965
  // src/components/icons/StudioIcons.tsx
2930
2966
  var import_lucide_react_native2 = require("lucide-react-native");
2931
- var import_jsx_runtime14 = require("react/jsx-runtime");
2967
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2932
2968
  function useResolvedIconColor(token) {
2933
2969
  const theme = useTheme();
2934
2970
  switch (token) {
@@ -2952,7 +2988,7 @@ function useResolvedIconColor(token) {
2952
2988
  function makeIcon(Comp) {
2953
2989
  return function StudioIcon({ size = 20, strokeWidth = 2, colorToken = "floatingContent", ...rest }) {
2954
2990
  const color = useResolvedIconColor(colorToken);
2955
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Comp, { size, strokeWidth, color, ...rest });
2991
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Comp, { size, strokeWidth, color, ...rest });
2956
2992
  };
2957
2993
  }
2958
2994
  var IconHome = makeIcon(import_lucide_react_native2.Home);
@@ -2968,17 +3004,17 @@ var IconArrowDown = makeIcon(import_lucide_react_native2.ArrowDown);
2968
3004
  var IconApprove = makeIcon(import_lucide_react_native2.Check);
2969
3005
 
2970
3006
  // src/components/chat/ChatComposer.tsx
2971
- var import_jsx_runtime15 = require("react/jsx-runtime");
3007
+ var import_jsx_runtime17 = require("react/jsx-runtime");
2972
3008
  var THUMBNAIL_HEIGHT = 90;
2973
3009
  function AspectRatioThumbnail({
2974
3010
  uri,
2975
3011
  onRemove,
2976
3012
  renderRemoveIcon
2977
3013
  }) {
2978
- const [aspectRatio, setAspectRatio] = React16.useState(1);
2979
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native17.View, { style: { height: THUMBNAIL_HEIGHT, aspectRatio, position: "relative" }, children: [
2980
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native17.View, { style: { flex: 1, borderRadius: 8, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2981
- import_react_native17.Image,
3014
+ const [aspectRatio, setAspectRatio] = React18.useState(1);
3015
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native18.View, { style: { height: THUMBNAIL_HEIGHT, aspectRatio, position: "relative" }, children: [
3016
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native18.View, { style: { flex: 1, borderRadius: 8, overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3017
+ import_react_native18.Image,
2982
3018
  {
2983
3019
  source: { uri },
2984
3020
  style: { width: "100%", height: "100%" },
@@ -2990,8 +3026,8 @@ function AspectRatioThumbnail({
2990
3026
  }
2991
3027
  }
2992
3028
  ) }),
2993
- onRemove ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2994
- import_react_native17.Pressable,
3029
+ onRemove ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3030
+ import_react_native18.Pressable,
2995
3031
  {
2996
3032
  style: {
2997
3033
  position: "absolute",
@@ -3007,7 +3043,7 @@ function AspectRatioThumbnail({
3007
3043
  },
3008
3044
  onPress: onRemove,
3009
3045
  hitSlop: 10,
3010
- children: renderRemoveIcon ? renderRemoveIcon() : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconClose, { size: 12, colorToken: "onPrimary" })
3046
+ children: renderRemoveIcon ? renderRemoveIcon() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconClose, { size: 12, colorToken: "onPrimary" })
3011
3047
  }
3012
3048
  ) : null
3013
3049
  ] });
@@ -3032,19 +3068,19 @@ function ChatComposer({
3032
3068
  style
3033
3069
  }) {
3034
3070
  const theme = useTheme();
3035
- const [internal, setInternal] = React16.useState("");
3071
+ const [internal, setInternal] = React18.useState("");
3036
3072
  const text = value ?? internal;
3037
3073
  const setText = onChangeValue ?? setInternal;
3038
3074
  const hasAttachments = attachments.length > 0;
3039
3075
  const hasText = text.trim().length > 0;
3040
3076
  const composerMinHeight = hasAttachments ? THUMBNAIL_HEIGHT + 44 + 24 : 44;
3041
3077
  const isButtonDisabled = sending || disabled || sendDisabled;
3042
- const maxInputHeight = React16.useMemo(() => import_react_native17.Dimensions.get("window").height * 0.5, []);
3043
- const shakeAnim = React16.useRef(new import_react_native17.Animated.Value(0)).current;
3044
- const [sendPressed, setSendPressed] = React16.useState(false);
3045
- const inputRef = React16.useRef(null);
3046
- const prevAutoFocusRef = React16.useRef(false);
3047
- React16.useEffect(() => {
3078
+ const maxInputHeight = React18.useMemo(() => import_react_native18.Dimensions.get("window").height * 0.5, []);
3079
+ const shakeAnim = React18.useRef(new import_react_native18.Animated.Value(0)).current;
3080
+ const [sendPressed, setSendPressed] = React18.useState(false);
3081
+ const inputRef = React18.useRef(null);
3082
+ const prevAutoFocusRef = React18.useRef(false);
3083
+ React18.useEffect(() => {
3048
3084
  const shouldFocus = autoFocus && !prevAutoFocusRef.current && !disabled && !sending;
3049
3085
  prevAutoFocusRef.current = autoFocus;
3050
3086
  if (!shouldFocus) return;
@@ -3054,17 +3090,17 @@ function ChatComposer({
3054
3090
  }, 75);
3055
3091
  return () => clearTimeout(t);
3056
3092
  }, [autoFocus, disabled, sending]);
3057
- const triggerShake = React16.useCallback(() => {
3093
+ const triggerShake = React18.useCallback(() => {
3058
3094
  shakeAnim.setValue(0);
3059
- import_react_native17.Animated.sequence([
3060
- import_react_native17.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
3061
- import_react_native17.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
3062
- import_react_native17.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
3063
- import_react_native17.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
3064
- import_react_native17.Animated.timing(shakeAnim, { toValue: 0, duration: 50, useNativeDriver: true })
3095
+ import_react_native18.Animated.sequence([
3096
+ import_react_native18.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
3097
+ import_react_native18.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
3098
+ import_react_native18.Animated.timing(shakeAnim, { toValue: 10, duration: 50, useNativeDriver: true }),
3099
+ import_react_native18.Animated.timing(shakeAnim, { toValue: -10, duration: 50, useNativeDriver: true }),
3100
+ import_react_native18.Animated.timing(shakeAnim, { toValue: 0, duration: 50, useNativeDriver: true })
3065
3101
  ]).start();
3066
3102
  }, [shakeAnim]);
3067
- const handleSend = React16.useCallback(async () => {
3103
+ const handleSend = React18.useCallback(async () => {
3068
3104
  if (isButtonDisabled) return;
3069
3105
  if (!hasText) {
3070
3106
  triggerShake();
@@ -3076,33 +3112,34 @@ function ChatComposer({
3076
3112
  }, [attachments, hasText, isButtonDisabled, onSend, setText, text, triggerShake]);
3077
3113
  const textareaBgColor = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
3078
3114
  const placeholderTextColor = theme.scheme === "dark" ? "#A1A1AA" : "#71717A";
3079
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3080
- import_react_native17.View,
3115
+ const sendBg = withAlpha(theme.colors.primary, isButtonDisabled ? 0.6 : sendPressed ? 0.9 : 1);
3116
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3117
+ import_react_native18.View,
3081
3118
  {
3082
3119
  style: [{ paddingHorizontal: 16, paddingBottom: 12, paddingTop: 8 }, style],
3083
3120
  onLayout: (e) => onLayout == null ? void 0 : onLayout({ height: e.nativeEvent.layout.height }),
3084
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_react_native17.View, { style: { flexDirection: "row", alignItems: "flex-end", gap: 8 }, children: [
3085
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native17.Animated.View, { style: { flex: 1, transform: [{ translateX: shakeAnim }] }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3086
- import_liquid_glass3.LiquidGlassView,
3121
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native18.View, { style: { flexDirection: "row", alignItems: "flex-end", gap: 8 }, children: [
3122
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native18.Animated.View, { style: { flex: 1, transform: [{ translateX: shakeAnim }] }, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3123
+ ResettableLiquidGlassView,
3087
3124
  {
3088
3125
  style: [
3089
3126
  // LiquidGlassView doesn't reliably auto-size to children; ensure enough height for the
3090
3127
  // thumbnail strip when attachments are present.
3091
3128
  { borderRadius: 24, flex: 1, minHeight: composerMinHeight },
3092
- !import_liquid_glass3.isLiquidGlassSupported && { backgroundColor: textareaBgColor }
3129
+ !import_liquid_glass4.isLiquidGlassSupported && { backgroundColor: textareaBgColor }
3093
3130
  ],
3094
3131
  interactive: true,
3095
3132
  effect: "clear",
3096
3133
  children: [
3097
- hasAttachments ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
3098
- import_react_native17.ScrollView,
3134
+ hasAttachments ? /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3135
+ import_react_native18.ScrollView,
3099
3136
  {
3100
3137
  horizontal: true,
3101
3138
  showsHorizontalScrollIndicator: false,
3102
3139
  keyboardShouldPersistTaps: "handled",
3103
3140
  contentContainerStyle: { gap: 8, paddingHorizontal: 12, paddingTop: 12 },
3104
3141
  children: [
3105
- attachments.map((uri, index) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3142
+ attachments.map((uri, index) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3106
3143
  AspectRatioThumbnail,
3107
3144
  {
3108
3145
  uri,
@@ -3111,8 +3148,8 @@ function ChatComposer({
3111
3148
  },
3112
3149
  `attachment-${index}`
3113
3150
  )),
3114
- onAddAttachment ? renderAddAttachment ? renderAddAttachment() : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3115
- import_react_native17.Pressable,
3151
+ onAddAttachment ? renderAddAttachment ? renderAddAttachment() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3152
+ import_react_native18.Pressable,
3116
3153
  {
3117
3154
  style: {
3118
3155
  height: THUMBNAIL_HEIGHT,
@@ -3126,13 +3163,13 @@ function ChatComposer({
3126
3163
  backgroundColor: "rgba(255, 255, 255, 0.05)"
3127
3164
  },
3128
3165
  onPress: onAddAttachment,
3129
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react_native3.Plus, { size: 24, color: "rgba(255, 255, 255, 0.5)" })
3166
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_lucide_react_native3.Plus, { size: 24, color: "rgba(255, 255, 255, 0.5)" })
3130
3167
  }
3131
3168
  ) : null
3132
3169
  ]
3133
3170
  }
3134
3171
  ) : null,
3135
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3172
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3136
3173
  MultilineTextInput,
3137
3174
  {
3138
3175
  ref: inputRef,
@@ -3157,25 +3194,24 @@ function ChatComposer({
3157
3194
  ]
3158
3195
  }
3159
3196
  ) }),
3160
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3161
- import_liquid_glass3.LiquidGlassView,
3197
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3198
+ ResettableLiquidGlassView,
3162
3199
  {
3163
- style: [{ borderRadius: 100 }, !import_liquid_glass3.isLiquidGlassSupported && { backgroundColor: textareaBgColor }],
3200
+ style: [{ borderRadius: 100 }, !import_liquid_glass4.isLiquidGlassSupported && { backgroundColor: textareaBgColor }],
3164
3201
  interactive: true,
3165
3202
  effect: "clear",
3166
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3167
- import_react_native17.View,
3203
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3204
+ import_react_native18.View,
3168
3205
  {
3169
3206
  style: {
3170
3207
  width: 44,
3171
3208
  height: 44,
3172
3209
  borderRadius: 22,
3173
3210
  overflow: "hidden",
3174
- backgroundColor: theme.colors.primary,
3175
- opacity: isButtonDisabled ? 0.6 : sendPressed ? 0.9 : 1
3211
+ backgroundColor: sendBg
3176
3212
  },
3177
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
3178
- import_react_native17.Pressable,
3213
+ children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3214
+ import_react_native18.Pressable,
3179
3215
  {
3180
3216
  accessibilityRole: "button",
3181
3217
  accessibilityLabel: "Send",
@@ -3184,7 +3220,7 @@ function ChatComposer({
3184
3220
  onPressIn: () => setSendPressed(true),
3185
3221
  onPressOut: () => setSendPressed(false),
3186
3222
  style: { flex: 1, alignItems: "center", justifyContent: "center" },
3187
- children: sending ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_react_native17.ActivityIndicator, {}) : renderSendIcon ? renderSendIcon() : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(IconChevronRight, { size: 20, colorToken: "onPrimary" })
3223
+ children: sending ? /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(import_react_native18.ActivityIndicator, {}) : renderSendIcon ? renderSendIcon() : /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(IconChevronRight, { size: 20, colorToken: "onPrimary" })
3188
3224
  }
3189
3225
  )
3190
3226
  }
@@ -3197,12 +3233,12 @@ function ChatComposer({
3197
3233
  }
3198
3234
 
3199
3235
  // src/components/comments/CommentRow.tsx
3200
- var React17 = __toESM(require("react"));
3201
- var import_react_native19 = require("react-native");
3236
+ var React19 = __toESM(require("react"));
3237
+ var import_react_native20 = require("react-native");
3202
3238
 
3203
3239
  // src/components/primitives/Avatar.tsx
3204
- var import_react_native18 = require("react-native");
3205
- var import_jsx_runtime16 = require("react/jsx-runtime");
3240
+ var import_react_native19 = require("react-native");
3241
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3206
3242
  function initialsFrom(name) {
3207
3243
  var _a, _b;
3208
3244
  const trimmed = (name ?? "").trim();
@@ -3220,8 +3256,8 @@ function Avatar({
3220
3256
  const theme = useTheme();
3221
3257
  const radius = size / 2;
3222
3258
  const fallbackBg = fallbackBackgroundColor ?? theme.colors.neutral;
3223
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3224
- import_react_native18.View,
3259
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3260
+ import_react_native19.View,
3225
3261
  {
3226
3262
  style: [
3227
3263
  {
@@ -3235,14 +3271,14 @@ function Avatar({
3235
3271
  },
3236
3272
  style
3237
3273
  ],
3238
- children: uri ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3239
- import_react_native18.Image,
3274
+ children: uri ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3275
+ import_react_native19.Image,
3240
3276
  {
3241
3277
  source: { uri },
3242
3278
  style: [{ width: size, height: size }, imageStyle],
3243
3279
  resizeMode: "cover"
3244
3280
  }
3245
- ) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Text, { variant: "caption", style: { color: theme.colors.onNeutral }, children: initialsFrom(name) })
3281
+ ) : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { variant: "caption", style: { color: theme.colors.onNeutral }, children: initialsFrom(name) })
3246
3282
  }
3247
3283
  );
3248
3284
  }
@@ -3266,12 +3302,12 @@ function formatTimeAgo(iso) {
3266
3302
  }
3267
3303
 
3268
3304
  // src/components/comments/CommentRow.tsx
3269
- var import_jsx_runtime17 = require("react/jsx-runtime");
3305
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3270
3306
  function CommentRow({ comment, showDivider }) {
3271
3307
  const theme = useTheme();
3272
- const [authorName, setAuthorName] = React17.useState(null);
3273
- const [authorAvatar, setAuthorAvatar] = React17.useState(null);
3274
- React17.useEffect(() => {
3308
+ const [authorName, setAuthorName] = React19.useState(null);
3309
+ const [authorAvatar, setAuthorAvatar] = React19.useState(null);
3310
+ React19.useEffect(() => {
3275
3311
  let cancelled = false;
3276
3312
  (async () => {
3277
3313
  try {
@@ -3286,8 +3322,8 @@ function CommentRow({ comment, showDivider }) {
3286
3322
  cancelled = true;
3287
3323
  };
3288
3324
  }, [comment.authorId]);
3289
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(
3290
- import_react_native19.View,
3325
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(
3326
+ import_react_native20.View,
3291
3327
  {
3292
3328
  style: {
3293
3329
  flexDirection: "row",
@@ -3297,13 +3333,13 @@ function CommentRow({ comment, showDivider }) {
3297
3333
  borderBottomColor: withAlpha(theme.colors.border, 0.5)
3298
3334
  },
3299
3335
  children: [
3300
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Avatar, { size: 32, uri: authorAvatar, name: authorName ?? comment.authorId, style: { marginTop: 6 } }),
3301
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native19.View, { style: { flex: 1, minWidth: 0, gap: 4 }, children: [
3302
- /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_react_native19.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.sm }, children: [
3303
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { style: { fontSize: 14, lineHeight: 18, fontWeight: theme.typography.fontWeight.bold, color: theme.colors.text }, children: authorName ?? "Unknown User" }),
3304
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, children: formatTimeAgo(comment.createdAt) })
3336
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Avatar, { size: 32, uri: authorAvatar, name: authorName ?? comment.authorId, style: { marginTop: 6 } }),
3337
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native20.View, { style: { flex: 1, minWidth: 0, gap: 4 }, children: [
3338
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native20.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.sm }, children: [
3339
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { style: { fontSize: 14, lineHeight: 18, fontWeight: theme.typography.fontWeight.bold, color: theme.colors.text }, children: authorName ?? "Unknown User" }),
3340
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, children: formatTimeAgo(comment.createdAt) })
3305
3341
  ] }),
3306
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { style: { fontSize: 14, lineHeight: 20, color: theme.colors.text }, children: comment.body ?? comment.description ?? "" })
3342
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(Text, { style: { fontSize: 14, lineHeight: 20, color: theme.colors.text }, children: comment.body ?? comment.description ?? "" })
3307
3343
  ] })
3308
3344
  ]
3309
3345
  }
@@ -3311,7 +3347,7 @@ function CommentRow({ comment, showDivider }) {
3311
3347
  }
3312
3348
 
3313
3349
  // src/components/comments/useAppComments.ts
3314
- var React18 = __toESM(require("react"));
3350
+ var React20 = __toESM(require("react"));
3315
3351
 
3316
3352
  // src/data/comments/remote.ts
3317
3353
  var AppCommentsRemoteDataSourceImpl = class extends BaseRemote {
@@ -3383,18 +3419,18 @@ var appCommentsRepository = new AppCommentsRepositoryImpl(appCommentsRemoteDataS
3383
3419
 
3384
3420
  // src/components/comments/useAppComments.ts
3385
3421
  function useAppComments(appId) {
3386
- const [comments, setComments] = React18.useState([]);
3387
- const [loading, setLoading] = React18.useState(false);
3388
- const [sending, setSending] = React18.useState(false);
3389
- const [error, setError] = React18.useState(null);
3390
- const sortByCreatedAtAsc = React18.useCallback((items) => {
3422
+ const [comments, setComments] = React20.useState([]);
3423
+ const [loading, setLoading] = React20.useState(false);
3424
+ const [sending, setSending] = React20.useState(false);
3425
+ const [error, setError] = React20.useState(null);
3426
+ const sortByCreatedAtAsc = React20.useCallback((items) => {
3391
3427
  return [...items].sort((a, b) => {
3392
3428
  const at = a.createdAt ? new Date(a.createdAt).getTime() : 0;
3393
3429
  const bt = b.createdAt ? new Date(b.createdAt).getTime() : 0;
3394
3430
  return at - bt;
3395
3431
  });
3396
3432
  }, []);
3397
- const refresh = React18.useCallback(async () => {
3433
+ const refresh = React20.useCallback(async () => {
3398
3434
  if (!appId) {
3399
3435
  setComments([]);
3400
3436
  return;
@@ -3411,10 +3447,10 @@ function useAppComments(appId) {
3411
3447
  setLoading(false);
3412
3448
  }
3413
3449
  }, [appId, sortByCreatedAtAsc]);
3414
- React18.useEffect(() => {
3450
+ React20.useEffect(() => {
3415
3451
  void refresh();
3416
3452
  }, [refresh]);
3417
- const create = React18.useCallback(
3453
+ const create = React20.useCallback(
3418
3454
  async (text) => {
3419
3455
  if (!appId) return;
3420
3456
  const trimmed = text.trim();
@@ -3437,11 +3473,11 @@ function useAppComments(appId) {
3437
3473
  }
3438
3474
 
3439
3475
  // src/components/comments/useAppDetails.ts
3440
- var React19 = __toESM(require("react"));
3476
+ var React21 = __toESM(require("react"));
3441
3477
  function useAppDetails(appId) {
3442
- const [app, setApp] = React19.useState(null);
3443
- const [loading, setLoading] = React19.useState(false);
3444
- React19.useEffect(() => {
3478
+ const [app, setApp] = React21.useState(null);
3479
+ const [loading, setLoading] = React21.useState(false);
3480
+ React21.useEffect(() => {
3445
3481
  if (!appId) {
3446
3482
  setApp(null);
3447
3483
  return;
@@ -3466,14 +3502,14 @@ function useAppDetails(appId) {
3466
3502
  }
3467
3503
 
3468
3504
  // src/components/comments/useIosKeyboardSnapFix.ts
3469
- var React20 = __toESM(require("react"));
3470
- var import_react_native20 = require("react-native");
3505
+ var React22 = __toESM(require("react"));
3506
+ var import_react_native21 = require("react-native");
3471
3507
  function useIosKeyboardSnapFix(sheetRef, options) {
3472
- const [keyboardVisible, setKeyboardVisible] = React20.useState(false);
3473
- React20.useEffect(() => {
3474
- if (import_react_native20.Platform.OS !== "ios") return;
3475
- const show = import_react_native20.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
3476
- const hide = import_react_native20.Keyboard.addListener("keyboardWillHide", () => {
3508
+ const [keyboardVisible, setKeyboardVisible] = React22.useState(false);
3509
+ React22.useEffect(() => {
3510
+ if (import_react_native21.Platform.OS !== "ios") return;
3511
+ const show = import_react_native21.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
3512
+ const hide = import_react_native21.Keyboard.addListener("keyboardWillHide", () => {
3477
3513
  var _a;
3478
3514
  setKeyboardVisible(false);
3479
3515
  const target = (options == null ? void 0 : options.targetIndex) ?? 1;
@@ -3494,20 +3530,20 @@ function useIosKeyboardSnapFix(sheetRef, options) {
3494
3530
  }
3495
3531
 
3496
3532
  // src/components/comments/AppCommentsSheet.tsx
3497
- var import_jsx_runtime18 = require("react/jsx-runtime");
3533
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3498
3534
  function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3499
3535
  const theme = useTheme();
3500
3536
  const insets = (0, import_react_native_safe_area_context3.useSafeAreaInsets)();
3501
- const sheetRef = React21.useRef(null);
3502
- const snapPoints = React21.useMemo(() => ["50%", "90%"], []);
3503
- const currentIndexRef = React21.useRef(1);
3537
+ const sheetRef = React23.useRef(null);
3538
+ const snapPoints = React23.useMemo(() => ["50%", "90%"], []);
3539
+ const currentIndexRef = React23.useRef(1);
3504
3540
  const { comments, loading, sending, error, create, refresh } = useAppComments(appId);
3505
3541
  const { app, loading: loadingApp } = useAppDetails(appId);
3506
3542
  const { keyboardVisible } = useIosKeyboardSnapFix(sheetRef, {
3507
3543
  getCurrentIndex: () => currentIndexRef.current,
3508
3544
  targetIndex: 1
3509
3545
  });
3510
- React21.useEffect(() => {
3546
+ React23.useEffect(() => {
3511
3547
  var _a, _b;
3512
3548
  if (appId) {
3513
3549
  (_a = sheetRef.current) == null ? void 0 : _a.present();
@@ -3516,29 +3552,29 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3516
3552
  (_b = sheetRef.current) == null ? void 0 : _b.dismiss();
3517
3553
  }
3518
3554
  }, [appId, refresh]);
3519
- React21.useEffect(() => {
3555
+ React23.useEffect(() => {
3520
3556
  if (!appId) return;
3521
3557
  onCountChange == null ? void 0 : onCountChange(comments.length);
3522
3558
  }, [appId, comments.length, onCountChange]);
3523
- const renderBackdrop = React21.useCallback(
3524
- (props) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_bottom_sheet3.BottomSheetBackdrop, { ...props, disappearsOnIndex: -1, appearsOnIndex: 0, opacity: 0.5 }),
3559
+ const renderBackdrop = React23.useCallback(
3560
+ (props) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_bottom_sheet3.BottomSheetBackdrop, { ...props, disappearsOnIndex: -1, appearsOnIndex: 0, opacity: 0.5 }),
3525
3561
  []
3526
3562
  );
3527
- const handleChange = React21.useCallback(
3563
+ const handleChange = React23.useCallback(
3528
3564
  (index) => {
3529
3565
  currentIndexRef.current = index;
3530
3566
  if (index === -1) onClose();
3531
3567
  },
3532
3568
  [onClose]
3533
3569
  );
3534
- const handlePlay = React21.useCallback(async () => {
3570
+ const handlePlay = React23.useCallback(async () => {
3535
3571
  var _a;
3536
3572
  if (!appId) return;
3537
3573
  (_a = sheetRef.current) == null ? void 0 : _a.dismiss();
3538
3574
  await (onPlayApp == null ? void 0 : onPlayApp(appId));
3539
3575
  onClose();
3540
3576
  }, [appId, onClose, onPlayApp]);
3541
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3577
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3542
3578
  import_bottom_sheet3.BottomSheetModal,
3543
3579
  {
3544
3580
  ref: sheetRef,
@@ -3549,17 +3585,17 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3549
3585
  onChange: handleChange,
3550
3586
  backgroundStyle: {
3551
3587
  backgroundColor: theme.scheme === "dark" ? "#0B080F" : "#FFFFFF",
3552
- borderTopLeftRadius: import_react_native21.Platform.OS === "ios" ? 39 : 16,
3553
- borderTopRightRadius: import_react_native21.Platform.OS === "ios" ? 39 : 16
3588
+ borderTopLeftRadius: import_react_native22.Platform.OS === "ios" ? 39 : 16,
3589
+ borderTopRightRadius: import_react_native22.Platform.OS === "ios" ? 39 : 16
3554
3590
  },
3555
3591
  handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
3556
3592
  keyboardBehavior: "interactive",
3557
3593
  keyboardBlurBehavior: "restore",
3558
3594
  android_keyboardInputMode: "adjustResize",
3559
3595
  topInset: insets.top,
3560
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_react_native21.View, { style: { flex: 1 }, children: [
3561
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3562
- import_react_native21.View,
3596
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_react_native22.View, { style: { flex: 1 }, children: [
3597
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3598
+ import_react_native22.View,
3563
3599
  {
3564
3600
  style: {
3565
3601
  flexDirection: "row",
@@ -3571,7 +3607,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3571
3607
  borderBottomColor: withAlpha(theme.colors.border, 0.1)
3572
3608
  },
3573
3609
  children: [
3574
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3610
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3575
3611
  Text,
3576
3612
  {
3577
3613
  numberOfLines: 1,
@@ -3585,29 +3621,28 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3585
3621
  children: loadingApp ? "Loading..." : (app == null ? void 0 : app.name) || "Comments"
3586
3622
  }
3587
3623
  ),
3588
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3589
- import_liquid_glass4.LiquidGlassView,
3624
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3625
+ ResettableLiquidGlassView,
3590
3626
  {
3591
3627
  style: [
3592
3628
  { borderRadius: 24 },
3593
- !import_liquid_glass4.isLiquidGlassSupported && { backgroundColor: theme.scheme === "dark" ? "#18181B" : "#F6F6F6" }
3629
+ !import_liquid_glass5.isLiquidGlassSupported && { backgroundColor: theme.scheme === "dark" ? "#18181B" : "#F6F6F6" }
3594
3630
  ],
3595
3631
  interactive: true,
3596
3632
  effect: "clear",
3597
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3598
- import_react_native21.View,
3633
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3634
+ import_react_native22.View,
3599
3635
  {
3600
3636
  style: {
3601
3637
  width: 32,
3602
3638
  height: 32,
3603
3639
  borderRadius: 999,
3604
- backgroundColor: theme.colors.primary,
3640
+ backgroundColor: withAlpha(theme.colors.primary, appId ? 1 : 0.5),
3605
3641
  alignItems: "center",
3606
- justifyContent: "center",
3607
- opacity: appId ? 1 : 0.5
3642
+ justifyContent: "center"
3608
3643
  },
3609
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3610
- import_react_native21.Pressable,
3644
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3645
+ import_react_native22.Pressable,
3611
3646
  {
3612
3647
  disabled: !appId,
3613
3648
  onPress: () => void handlePlay(),
@@ -3619,9 +3654,9 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3619
3654
  alignItems: "center",
3620
3655
  justifyContent: "center"
3621
3656
  },
3622
- pressed ? { opacity: 0.85 } : null
3657
+ pressed ? { transform: [{ scale: 0.96 }] } : null
3623
3658
  ],
3624
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_lucide_react_native4.Play, { size: 16, color: theme.colors.onPrimary })
3659
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react_native4.Play, { size: 16, color: theme.colors.onPrimary })
3625
3660
  }
3626
3661
  )
3627
3662
  }
@@ -3631,7 +3666,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3631
3666
  ]
3632
3667
  }
3633
3668
  ),
3634
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
3669
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3635
3670
  import_bottom_sheet3.BottomSheetScrollView,
3636
3671
  {
3637
3672
  style: { flex: 1 },
@@ -3642,13 +3677,13 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3642
3677
  },
3643
3678
  keyboardShouldPersistTaps: "handled",
3644
3679
  children: [
3645
- loading && comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.ActivityIndicator, {}) }) : comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_react_native21.View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { variant: "bodyMuted", style: { textAlign: "center" }, children: "No comments yet" }) }) : comments.map((c, idx) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CommentRow, { comment: c, showDivider: idx < comments.length - 1 }, c.id)),
3646
- error ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Text, { variant: "captionMuted", style: { marginTop: theme.spacing.lg }, children: "Failed to load comments." }) : null
3680
+ loading && comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.ActivityIndicator, {}) }) : comments.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native22.View, { style: { flex: 1, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Text, { variant: "bodyMuted", style: { textAlign: "center" }, children: "No comments yet" }) }) : comments.map((c, idx) => /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(CommentRow, { comment: c, showDivider: idx < comments.length - 1 }, c.id)),
3681
+ error ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Text, { variant: "captionMuted", style: { marginTop: theme.spacing.lg }, children: "Failed to load comments." }) : null
3647
3682
  ]
3648
3683
  }
3649
3684
  ),
3650
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3651
- import_react_native21.View,
3685
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3686
+ import_react_native22.View,
3652
3687
  {
3653
3688
  style: {
3654
3689
  position: "absolute",
@@ -3657,12 +3692,12 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3657
3692
  bottom: 0,
3658
3693
  paddingHorizontal: theme.spacing.lg,
3659
3694
  paddingTop: theme.spacing.sm,
3660
- paddingBottom: import_react_native21.Platform.OS === "ios" ? keyboardVisible ? theme.spacing.lg : insets.bottom : insets.bottom + 10,
3695
+ paddingBottom: import_react_native22.Platform.OS === "ios" ? keyboardVisible ? theme.spacing.lg : insets.bottom : insets.bottom + 10,
3661
3696
  borderTopWidth: 1,
3662
3697
  borderTopColor: withAlpha(theme.colors.border, 0.1),
3663
3698
  backgroundColor: withAlpha(theme.colors.background, 0.8)
3664
3699
  },
3665
- children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3700
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
3666
3701
  ChatComposer,
3667
3702
  {
3668
3703
  placeholder: "Write a comment...",
@@ -3671,7 +3706,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3671
3706
  useBottomSheetTextInput: true,
3672
3707
  onSend: async (text) => {
3673
3708
  await create(text);
3674
- import_react_native21.Keyboard.dismiss();
3709
+ import_react_native22.Keyboard.dismiss();
3675
3710
  }
3676
3711
  }
3677
3712
  )
@@ -3683,17 +3718,17 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3683
3718
  }
3684
3719
 
3685
3720
  // src/studio/ui/PreviewPanel.tsx
3686
- var import_react_native42 = require("react-native");
3721
+ var import_react_native43 = require("react-native");
3687
3722
 
3688
3723
  // src/components/preview/PreviewPage.tsx
3689
- var import_react_native22 = require("react-native");
3724
+ var import_react_native23 = require("react-native");
3690
3725
  var import_bottom_sheet4 = require("@gorhom/bottom-sheet");
3691
- var import_jsx_runtime19 = require("react/jsx-runtime");
3726
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3692
3727
  function PreviewPage({ header, children, contentStyle }) {
3693
3728
  const theme = useTheme();
3694
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_react_native22.View, { style: { flex: 1 }, children: [
3695
- header ? /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(import_react_native22.View, { children: header }) : null,
3696
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3729
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_react_native23.View, { style: { flex: 1 }, children: [
3730
+ header ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native23.View, { children: header }) : null,
3731
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3697
3732
  import_bottom_sheet4.BottomSheetScrollView,
3698
3733
  {
3699
3734
  style: { flex: 1 },
@@ -3712,15 +3747,15 @@ function PreviewPage({ header, children, contentStyle }) {
3712
3747
  }
3713
3748
 
3714
3749
  // src/studio/ui/preview-panel/PreviewPanelHeader.tsx
3715
- var import_react_native25 = require("react-native");
3750
+ var import_react_native26 = require("react-native");
3716
3751
 
3717
3752
  // src/components/studio-sheet/StudioSheetHeader.tsx
3718
- var import_react_native23 = require("react-native");
3719
- var import_jsx_runtime20 = require("react/jsx-runtime");
3753
+ var import_react_native24 = require("react-native");
3754
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3720
3755
  function StudioSheetHeader({ left, center, right, style }) {
3721
3756
  const theme = useTheme();
3722
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
3723
- import_react_native23.View,
3757
+ return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
3758
+ import_react_native24.View,
3724
3759
  {
3725
3760
  style: [
3726
3761
  {
@@ -3733,19 +3768,19 @@ function StudioSheetHeader({ left, center, right, style }) {
3733
3768
  style
3734
3769
  ],
3735
3770
  children: [
3736
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native23.View, { style: { flexDirection: "row", alignItems: "center" }, children: left }),
3737
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native23.View, { style: { flex: 1, alignItems: "center" }, children: center }),
3738
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_react_native23.View, { style: { flexDirection: "row", alignItems: "center" }, children: right })
3771
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native24.View, { style: { flexDirection: "row", alignItems: "center" }, children: left }),
3772
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native24.View, { style: { flex: 1, alignItems: "center" }, children: center }),
3773
+ /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react_native24.View, { style: { flexDirection: "row", alignItems: "center" }, children: right })
3739
3774
  ]
3740
3775
  }
3741
3776
  );
3742
3777
  }
3743
3778
 
3744
3779
  // src/components/studio-sheet/StudioSheetHeaderIconButton.tsx
3745
- var React22 = __toESM(require("react"));
3746
- var import_react_native24 = require("react-native");
3747
- var import_liquid_glass5 = require("@callstack/liquid-glass");
3748
- var import_jsx_runtime21 = require("react/jsx-runtime");
3780
+ var React24 = __toESM(require("react"));
3781
+ var import_react_native25 = require("react-native");
3782
+ var import_liquid_glass6 = require("@callstack/liquid-glass");
3783
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3749
3784
  function StudioSheetHeaderIconButton({
3750
3785
  onPress,
3751
3786
  disabled,
@@ -3757,19 +3792,20 @@ function StudioSheetHeaderIconButton({
3757
3792
  }) {
3758
3793
  const theme = useTheme();
3759
3794
  const size = 44;
3760
- const [pressed, setPressed] = React22.useState(false);
3795
+ const [pressed, setPressed] = React24.useState(false);
3761
3796
  const solidBg = intent === "danger" ? theme.colors.danger : intent === "primary" ? theme.colors.primary : theme.colors.neutral;
3762
3797
  const glassFallbackBg = theme.scheme === "dark" ? "#18181B" : "#F6F6F6";
3763
3798
  const glassInnerBg = intent === "danger" ? theme.colors.danger : theme.colors.primary;
3764
3799
  const resolvedOpacity = disabled ? 0.6 : pressed ? 0.9 : 1;
3765
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_react_native24.View, { style, children: appearance === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3766
- import_liquid_glass5.LiquidGlassView,
3800
+ const glassBg = withAlpha(glassInnerBg, resolvedOpacity);
3801
+ return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_react_native25.View, { style, children: appearance === "glass" ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3802
+ ResettableLiquidGlassView,
3767
3803
  {
3768
- style: [{ borderRadius: 100 }, !import_liquid_glass5.isLiquidGlassSupported && { backgroundColor: glassFallbackBg }],
3804
+ style: [{ borderRadius: 100 }, !import_liquid_glass6.isLiquidGlassSupported && { backgroundColor: glassFallbackBg }],
3769
3805
  interactive: true,
3770
3806
  effect: "clear",
3771
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3772
- import_react_native24.View,
3807
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3808
+ import_react_native25.View,
3773
3809
  {
3774
3810
  style: {
3775
3811
  width: size,
@@ -3777,11 +3813,10 @@ function StudioSheetHeaderIconButton({
3777
3813
  borderRadius: 100,
3778
3814
  alignItems: "center",
3779
3815
  justifyContent: "center",
3780
- backgroundColor: glassInnerBg,
3781
- opacity: resolvedOpacity
3816
+ backgroundColor: glassBg
3782
3817
  },
3783
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3784
- import_react_native24.Pressable,
3818
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3819
+ import_react_native25.Pressable,
3785
3820
  {
3786
3821
  accessibilityRole: "button",
3787
3822
  accessibilityLabel,
@@ -3799,8 +3834,8 @@ function StudioSheetHeaderIconButton({
3799
3834
  }
3800
3835
  )
3801
3836
  }
3802
- ) : /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3803
- import_react_native24.View,
3837
+ ) : /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3838
+ import_react_native25.View,
3804
3839
  {
3805
3840
  style: {
3806
3841
  width: size,
@@ -3811,8 +3846,8 @@ function StudioSheetHeaderIconButton({
3811
3846
  backgroundColor: solidBg,
3812
3847
  opacity: resolvedOpacity
3813
3848
  },
3814
- children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
3815
- import_react_native24.Pressable,
3849
+ children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3850
+ import_react_native25.Pressable,
3816
3851
  {
3817
3852
  accessibilityRole: "button",
3818
3853
  accessibilityLabel,
@@ -3832,15 +3867,15 @@ function StudioSheetHeaderIconButton({
3832
3867
  }
3833
3868
 
3834
3869
  // src/studio/ui/preview-panel/PreviewPanelHeader.tsx
3835
- var import_jsx_runtime22 = require("react/jsx-runtime");
3870
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3836
3871
  function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
3837
- return /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3872
+ return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3838
3873
  StudioSheetHeader,
3839
3874
  {
3840
- left: onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconHome, { size: 20, colorToken: "onPrimary" }) }) : null,
3875
+ left: onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconHome, { size: 20, colorToken: "onPrimary" }) }) : null,
3841
3876
  center: null,
3842
- right: /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_react_native25.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
3843
- isOwner ? /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
3877
+ right: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_react_native26.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
3878
+ isOwner ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3844
3879
  StudioSheetHeaderIconButton,
3845
3880
  {
3846
3881
  onPress: onGoToChat,
@@ -3848,21 +3883,21 @@ function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
3848
3883
  intent: "primary",
3849
3884
  appearance: "glass",
3850
3885
  style: { marginRight: 8 },
3851
- children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconChat, { size: 20, colorToken: "onPrimary" })
3886
+ children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconChat, { size: 20, colorToken: "onPrimary" })
3852
3887
  }
3853
3888
  ) : null,
3854
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(IconClose, { size: 20, colorToken: "onPrimary" }) })
3889
+ /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", appearance: "glass", intent: "primary", children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(IconClose, { size: 20, colorToken: "onPrimary" }) })
3855
3890
  ] })
3856
3891
  }
3857
3892
  );
3858
3893
  }
3859
3894
 
3860
3895
  // src/components/preview/PreviewHeroCard.tsx
3861
- var import_react_native27 = require("react-native");
3896
+ var import_react_native28 = require("react-native");
3862
3897
 
3863
3898
  // src/components/primitives/Surface.tsx
3864
- var import_react_native26 = require("react-native");
3865
- var import_jsx_runtime23 = require("react/jsx-runtime");
3899
+ var import_react_native27 = require("react-native");
3900
+ var import_jsx_runtime25 = require("react/jsx-runtime");
3866
3901
  function backgroundFor(variant, theme) {
3867
3902
  const { colors } = theme;
3868
3903
  switch (variant) {
@@ -3879,8 +3914,8 @@ function backgroundFor(variant, theme) {
3879
3914
  }
3880
3915
  function Surface({ variant = "surface", border = false, style, ...props }) {
3881
3916
  const theme = useTheme();
3882
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
3883
- import_react_native26.View,
3917
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3918
+ import_react_native27.View,
3884
3919
  {
3885
3920
  ...props,
3886
3921
  style: [
@@ -3893,12 +3928,12 @@ function Surface({ variant = "surface", border = false, style, ...props }) {
3893
3928
  }
3894
3929
 
3895
3930
  // src/components/primitives/Card.tsx
3896
- var import_jsx_runtime24 = require("react/jsx-runtime");
3931
+ var import_jsx_runtime26 = require("react/jsx-runtime");
3897
3932
  function Card({ variant = "surface", padded = true, border = true, style, ...props }) {
3898
3933
  const theme = useTheme();
3899
3934
  const radius = theme.radii.lg;
3900
3935
  const padding = padded ? theme.spacing.lg : 0;
3901
- return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
3936
+ return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
3902
3937
  Surface,
3903
3938
  {
3904
3939
  ...props,
@@ -3910,7 +3945,7 @@ function Card({ variant = "surface", padded = true, border = true, style, ...pro
3910
3945
  }
3911
3946
 
3912
3947
  // src/components/preview/PreviewHeroCard.tsx
3913
- var import_jsx_runtime25 = require("react/jsx-runtime");
3948
+ var import_jsx_runtime27 = require("react/jsx-runtime");
3914
3949
  function PreviewHeroCard({
3915
3950
  aspectRatio = 4 / 3,
3916
3951
  overlayTopLeft,
@@ -3921,7 +3956,7 @@ function PreviewHeroCard({
3921
3956
  }) {
3922
3957
  const theme = useTheme();
3923
3958
  const radius = 16;
3924
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
3959
+ return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
3925
3960
  Card,
3926
3961
  {
3927
3962
  variant: "surfaceRaised",
@@ -3936,32 +3971,32 @@ function PreviewHeroCard({
3936
3971
  },
3937
3972
  style
3938
3973
  ],
3939
- children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_react_native27.View, { style: { flex: 1 }, children: [
3940
- background ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native27.View, { style: { position: "absolute", inset: 0 }, children: background }) : null,
3941
- image ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native27.View, { style: { position: "absolute", inset: 0 }, children: image }) : null,
3942
- overlayTopLeft ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native27.View, { style: { position: "absolute", top: theme.spacing.sm, left: theme.spacing.sm, zIndex: 2 }, children: overlayTopLeft }) : null,
3943
- overlayBottom ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_react_native27.View, { style: { flex: 1, justifyContent: "flex-end" }, children: overlayBottom }) : null
3974
+ children: /* @__PURE__ */ (0, import_jsx_runtime27.jsxs)(import_react_native28.View, { style: { flex: 1 }, children: [
3975
+ background ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native28.View, { style: { position: "absolute", inset: 0 }, children: background }) : null,
3976
+ image ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native28.View, { style: { position: "absolute", inset: 0 }, children: image }) : null,
3977
+ overlayTopLeft ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native28.View, { style: { position: "absolute", top: theme.spacing.sm, left: theme.spacing.sm, zIndex: 2 }, children: overlayTopLeft }) : null,
3978
+ overlayBottom ? /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(import_react_native28.View, { style: { flex: 1, justifyContent: "flex-end" }, children: overlayBottom }) : null
3944
3979
  ] })
3945
3980
  }
3946
3981
  );
3947
3982
  }
3948
3983
 
3949
3984
  // src/components/preview/PreviewPlaceholder.tsx
3950
- var React23 = __toESM(require("react"));
3951
- var import_react_native28 = require("react-native");
3985
+ var React25 = __toESM(require("react"));
3986
+ var import_react_native29 = require("react-native");
3952
3987
  var import_expo_linear_gradient2 = require("expo-linear-gradient");
3953
- var import_jsx_runtime26 = require("react/jsx-runtime");
3988
+ var import_jsx_runtime28 = require("react/jsx-runtime");
3954
3989
  function PreviewPlaceholder({ visible, style }) {
3955
3990
  if (!visible) return null;
3956
- const opacityAnim = React23.useRef(new import_react_native28.Animated.Value(0)).current;
3957
- React23.useEffect(() => {
3991
+ const opacityAnim = React25.useRef(new import_react_native29.Animated.Value(0)).current;
3992
+ React25.useEffect(() => {
3958
3993
  if (!visible) return;
3959
- const animation = import_react_native28.Animated.loop(
3960
- import_react_native28.Animated.sequence([
3961
- import_react_native28.Animated.timing(opacityAnim, { toValue: 1, duration: 1500, useNativeDriver: true }),
3962
- import_react_native28.Animated.timing(opacityAnim, { toValue: 2, duration: 1500, useNativeDriver: true }),
3963
- import_react_native28.Animated.timing(opacityAnim, { toValue: 3, duration: 1500, useNativeDriver: true }),
3964
- import_react_native28.Animated.timing(opacityAnim, { toValue: 0, duration: 1500, useNativeDriver: true })
3994
+ const animation = import_react_native29.Animated.loop(
3995
+ import_react_native29.Animated.sequence([
3996
+ import_react_native29.Animated.timing(opacityAnim, { toValue: 1, duration: 1500, useNativeDriver: true }),
3997
+ import_react_native29.Animated.timing(opacityAnim, { toValue: 2, duration: 1500, useNativeDriver: true }),
3998
+ import_react_native29.Animated.timing(opacityAnim, { toValue: 3, duration: 1500, useNativeDriver: true }),
3999
+ import_react_native29.Animated.timing(opacityAnim, { toValue: 0, duration: 1500, useNativeDriver: true })
3965
4000
  ])
3966
4001
  );
3967
4002
  animation.start();
@@ -3971,8 +4006,8 @@ function PreviewPlaceholder({ visible, style }) {
3971
4006
  const opacity2 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 1, 0, 0] });
3972
4007
  const opacity3 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 1, 0] });
3973
4008
  const opacity4 = opacityAnim.interpolate({ inputRange: [0, 1, 2, 3], outputRange: [0, 0, 0, 1] });
3974
- return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
3975
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native28.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4009
+ return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(import_jsx_runtime28.Fragment, { children: [
4010
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native29.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3976
4011
  import_expo_linear_gradient2.LinearGradient,
3977
4012
  {
3978
4013
  colors: ["rgba(98, 0, 238, 0.45)", "rgba(168, 85, 247, 0.35)"],
@@ -3981,7 +4016,7 @@ function PreviewPlaceholder({ visible, style }) {
3981
4016
  style: { width: "100%", height: "100%" }
3982
4017
  }
3983
4018
  ) }),
3984
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native28.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity2 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4019
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native29.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity2 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3985
4020
  import_expo_linear_gradient2.LinearGradient,
3986
4021
  {
3987
4022
  colors: ["rgba(168, 85, 247, 0.45)", "rgba(139, 92, 246, 0.35)"],
@@ -3990,7 +4025,7 @@ function PreviewPlaceholder({ visible, style }) {
3990
4025
  style: { width: "100%", height: "100%" }
3991
4026
  }
3992
4027
  ) }),
3993
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native28.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity3 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4028
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native29.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity3 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
3994
4029
  import_expo_linear_gradient2.LinearGradient,
3995
4030
  {
3996
4031
  colors: ["rgba(139, 92, 246, 0.45)", "rgba(126, 34, 206, 0.35)"],
@@ -3999,7 +4034,7 @@ function PreviewPlaceholder({ visible, style }) {
3999
4034
  style: { width: "100%", height: "100%" }
4000
4035
  }
4001
4036
  ) }),
4002
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_react_native28.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity4 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
4037
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native29.Animated.View, { style: [{ position: "absolute", inset: 0, opacity: opacity4 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4003
4038
  import_expo_linear_gradient2.LinearGradient,
4004
4039
  {
4005
4040
  colors: ["rgba(126, 34, 206, 0.45)", "rgba(98, 0, 238, 0.35)"],
@@ -4012,12 +4047,12 @@ function PreviewPlaceholder({ visible, style }) {
4012
4047
  }
4013
4048
 
4014
4049
  // src/components/preview/PreviewImage.tsx
4015
- var import_react_native29 = require("react-native");
4016
- var import_jsx_runtime27 = require("react/jsx-runtime");
4050
+ var import_react_native30 = require("react-native");
4051
+ var import_jsx_runtime29 = require("react/jsx-runtime");
4017
4052
  function PreviewImage({ uri, onLoad, style }) {
4018
4053
  if (!uri) return null;
4019
- return /* @__PURE__ */ (0, import_jsx_runtime27.jsx)(
4020
- import_react_native29.Image,
4054
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4055
+ import_react_native30.Image,
4021
4056
  {
4022
4057
  source: { uri },
4023
4058
  resizeMode: "cover",
@@ -4028,15 +4063,15 @@ function PreviewImage({ uri, onLoad, style }) {
4028
4063
  }
4029
4064
 
4030
4065
  // src/components/preview/StatsBar.tsx
4031
- var import_react_native30 = require("react-native");
4032
- var import_liquid_glass6 = require("@callstack/liquid-glass");
4066
+ var import_react_native31 = require("react-native");
4067
+ var import_liquid_glass7 = require("@callstack/liquid-glass");
4033
4068
  var import_lucide_react_native5 = require("lucide-react-native");
4034
4069
 
4035
4070
  // src/components/icons/MergeIcon.tsx
4036
4071
  var import_react_native_svg2 = __toESM(require("react-native-svg"));
4037
- var import_jsx_runtime28 = require("react/jsx-runtime");
4072
+ var import_jsx_runtime30 = require("react/jsx-runtime");
4038
4073
  function MergeIcon({ color = "currentColor", width = 24, height = 24, ...props }) {
4039
- return /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_react_native_svg2.default, { viewBox: "0 0 486 486", width, height, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(
4074
+ return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_react_native_svg2.default, { viewBox: "0 0 486 486", width, height, ...props, children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
4040
4075
  import_react_native_svg2.Path,
4041
4076
  {
4042
4077
  d: "M237.025 0H243.664C254.876 95.0361 275.236 175.597 304.743 241.684C334.249 307.478 367.002 357.774 403 392.572L389.722 486C361.691 458.22 338.233 429.417 319.349 399.59C300.464 369.764 284.531 335.843 271.548 297.829C258.565 259.522 246.615 214.343 235.697 162.292L237.91 161.415C228.468 214.928 217.993 261.569 206.485 301.338C194.978 341.107 179.634 375.904 160.455 405.731C141.571 435.265 115.752 462.022 83 486L96.278 392.572C124.014 369.179 147.62 336.72 167.094 295.197C186.864 253.381 202.65 206.886 214.452 155.713C226.255 104.247 233.779 52.343 237.025 0Z",
@@ -4046,7 +4081,7 @@ function MergeIcon({ color = "currentColor", width = 24, height = 24, ...props }
4046
4081
  }
4047
4082
 
4048
4083
  // src/components/preview/StatsBar.tsx
4049
- var import_jsx_runtime29 = require("react/jsx-runtime");
4084
+ var import_jsx_runtime31 = require("react/jsx-runtime");
4050
4085
  function StatsBar({
4051
4086
  likeCount,
4052
4087
  commentCount,
@@ -4060,33 +4095,33 @@ function StatsBar({
4060
4095
  }) {
4061
4096
  const theme = useTheme();
4062
4097
  const statsBgColor = theme.scheme === "dark" ? "rgba(24, 24, 27, 0.5)" : "rgba(255, 255, 255, 0.5)";
4063
- return /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4064
- import_react_native30.View,
4098
+ return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4099
+ import_react_native31.View,
4065
4100
  {
4066
4101
  style: [
4067
4102
  { position: "absolute", bottom: 12, width: "100%", paddingHorizontal: 12 },
4068
4103
  centered && { alignItems: "center" },
4069
4104
  style
4070
4105
  ],
4071
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4072
- import_liquid_glass6.LiquidGlassView,
4106
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4107
+ ResettableLiquidGlassView,
4073
4108
  {
4074
4109
  style: [
4075
4110
  { borderRadius: 100, overflow: "hidden" },
4076
4111
  fixedWidth ? { width: fixedWidth } : void 0,
4077
- !import_liquid_glass6.isLiquidGlassSupported && { backgroundColor: statsBgColor }
4112
+ !import_liquid_glass7.isLiquidGlassSupported && { backgroundColor: statsBgColor }
4078
4113
  ],
4079
4114
  effect: "clear",
4080
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 }, children: [
4081
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4082
- import_react_native30.Pressable,
4115
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: 16 }, children: [
4116
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4117
+ import_react_native31.Pressable,
4083
4118
  {
4084
4119
  disabled: !onPressLike,
4085
4120
  onPress: onPressLike,
4086
4121
  hitSlop: 8,
4087
4122
  style: { paddingVertical: 8 },
4088
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
4089
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4123
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
4124
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4090
4125
  import_lucide_react_native5.Heart,
4091
4126
  {
4092
4127
  size: 16,
@@ -4095,8 +4130,8 @@ function StatsBar({
4095
4130
  fill: isLiked ? theme.colors.danger : "transparent"
4096
4131
  }
4097
4132
  ),
4098
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native30.View, { style: { width: 4 } }),
4099
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4133
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native31.View, { style: { width: 4 } }),
4134
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4100
4135
  Text,
4101
4136
  {
4102
4137
  variant: "caption",
@@ -4110,24 +4145,24 @@ function StatsBar({
4110
4145
  ] })
4111
4146
  }
4112
4147
  ),
4113
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
4114
- import_react_native30.Pressable,
4148
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4149
+ import_react_native31.Pressable,
4115
4150
  {
4116
4151
  disabled: !onPressComments,
4117
4152
  onPress: onPressComments,
4118
4153
  hitSlop: 8,
4119
4154
  style: { paddingVertical: 8 },
4120
- children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
4121
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_lucide_react_native5.MessageCircle, { size: 16, strokeWidth: 2.5, color: "#FFFFFF" }),
4122
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native30.View, { style: { width: 4 } }),
4123
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: commentCount })
4155
+ children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
4156
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_lucide_react_native5.MessageCircle, { size: 16, strokeWidth: 2.5, color: "#FFFFFF" }),
4157
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native31.View, { style: { width: 4 } }),
4158
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: commentCount })
4124
4159
  ] })
4125
4160
  }
4126
4161
  ),
4127
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(import_react_native30.View, { style: { flexDirection: "row", alignItems: "center", paddingVertical: 8 }, children: [
4128
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native30.View, { style: { transform: [{ scaleY: -1 }] }, children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(MergeIcon, { width: 14, height: 14, color: "#FFFFFF" }) }),
4129
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_react_native30.View, { style: { width: 4 } }),
4130
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: forkCount })
4162
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(import_react_native31.View, { style: { flexDirection: "row", alignItems: "center", paddingVertical: 8 }, children: [
4163
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native31.View, { style: { transform: [{ scaleY: -1 }] }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(MergeIcon, { width: 14, height: 14, color: "#FFFFFF" }) }),
4164
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_react_native31.View, { style: { width: 4 } }),
4165
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Text, { variant: "caption", style: { color: "#FFFFFF", fontWeight: theme.typography.fontWeight.bold }, children: forkCount })
4131
4166
  ] })
4132
4167
  ] })
4133
4168
  }
@@ -4137,7 +4172,7 @@ function StatsBar({
4137
4172
  }
4138
4173
 
4139
4174
  // src/components/preview/PreviewStatusBadge.tsx
4140
- var import_react_native31 = require("react-native");
4175
+ var import_react_native32 = require("react-native");
4141
4176
  var import_lucide_react_native6 = require("lucide-react-native");
4142
4177
 
4143
4178
  // src/data/apps/types.ts
@@ -4152,7 +4187,7 @@ var APP_STATUS_LABEL = {
4152
4187
  };
4153
4188
 
4154
4189
  // src/components/preview/PreviewStatusBadge.tsx
4155
- var import_jsx_runtime30 = require("react/jsx-runtime");
4190
+ var import_jsx_runtime32 = require("react/jsx-runtime");
4156
4191
  var STATUS_BG = {
4157
4192
  ready: "#10B981",
4158
4193
  // emerald-500
@@ -4181,8 +4216,8 @@ var STATUS_ICON = {
4181
4216
  function PreviewStatusBadge({ status }) {
4182
4217
  const IconComp = STATUS_ICON[status];
4183
4218
  const label = APP_STATUS_LABEL[status] ?? status;
4184
- return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
4185
- import_react_native31.View,
4219
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(
4220
+ import_react_native32.View,
4186
4221
  {
4187
4222
  style: {
4188
4223
  flexDirection: "row",
@@ -4193,15 +4228,15 @@ function PreviewStatusBadge({ status }) {
4193
4228
  backgroundColor: STATUS_BG[status]
4194
4229
  },
4195
4230
  children: [
4196
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(IconComp, { size: 12, color: "#FFFFFF", style: { marginRight: 4 } }),
4197
- /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(Text, { style: { color: "#FFFFFF", fontSize: 11, lineHeight: 14 }, children: label })
4231
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(IconComp, { size: 12, color: "#FFFFFF", style: { marginRight: 4 } }),
4232
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Text, { style: { color: "#FFFFFF", fontSize: 11, lineHeight: 14 }, children: label })
4198
4233
  ]
4199
4234
  }
4200
4235
  );
4201
4236
  }
4202
4237
 
4203
4238
  // src/studio/ui/preview-panel/PreviewHeroSection.tsx
4204
- var import_jsx_runtime31 = require("react/jsx-runtime");
4239
+ var import_jsx_runtime33 = require("react/jsx-runtime");
4205
4240
  function PreviewHeroSection({
4206
4241
  appStatus,
4207
4242
  showProcessing,
@@ -4210,13 +4245,13 @@ function PreviewHeroSection({
4210
4245
  onImageLoad,
4211
4246
  stats
4212
4247
  }) {
4213
- return /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4248
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
4214
4249
  PreviewHeroCard,
4215
4250
  {
4216
- overlayTopLeft: showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(PreviewStatusBadge, { status: appStatus }) : null,
4217
- background: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(PreviewPlaceholder, { visible: !imageLoaded }),
4218
- image: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(PreviewImage, { uri: imageUrl, onLoad: onImageLoad }),
4219
- overlayBottom: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
4251
+ overlayTopLeft: showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PreviewStatusBadge, { status: appStatus }) : null,
4252
+ background: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PreviewPlaceholder, { visible: !imageLoaded }),
4253
+ image: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(PreviewImage, { uri: imageUrl, onLoad: onImageLoad }),
4254
+ overlayBottom: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
4220
4255
  StatsBar,
4221
4256
  {
4222
4257
  likeCount: stats.likeCount,
@@ -4235,11 +4270,11 @@ function PreviewHeroSection({
4235
4270
  }
4236
4271
 
4237
4272
  // src/studio/ui/preview-panel/PreviewMetaSection.tsx
4238
- var import_react_native33 = require("react-native");
4273
+ var import_react_native34 = require("react-native");
4239
4274
 
4240
4275
  // src/components/preview/PreviewMetaRow.tsx
4241
- var import_react_native32 = require("react-native");
4242
- var import_jsx_runtime32 = require("react/jsx-runtime");
4276
+ var import_react_native33 = require("react-native");
4277
+ var import_jsx_runtime34 = require("react/jsx-runtime");
4243
4278
  function PreviewMetaRow({
4244
4279
  avatarUri,
4245
4280
  creatorName,
@@ -4250,11 +4285,11 @@ function PreviewMetaRow({
4250
4285
  style
4251
4286
  }) {
4252
4287
  const theme = useTheme();
4253
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native32.View, { style: [{ alignSelf: "stretch" }, style], children: [
4254
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native32.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
4255
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Avatar, { uri: avatarUri, name: creatorName, size: 24, style: { marginRight: theme.spacing.sm } }),
4256
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_react_native32.View, { style: { flexDirection: "row", alignItems: "center", flex: 1, minWidth: 0, marginRight: theme.spacing.sm }, children: [
4257
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4288
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native33.View, { style: [{ alignSelf: "stretch" }, style], children: [
4289
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native33.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
4290
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Avatar, { uri: avatarUri, name: creatorName, size: 24, style: { marginRight: theme.spacing.sm } }),
4291
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native33.View, { style: { flexDirection: "row", alignItems: "center", flex: 1, minWidth: 0, marginRight: theme.spacing.sm }, children: [
4292
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
4258
4293
  Text,
4259
4294
  {
4260
4295
  numberOfLines: 1,
@@ -4268,11 +4303,11 @@ function PreviewMetaRow({
4268
4303
  children: title
4269
4304
  }
4270
4305
  ),
4271
- tag ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_native32.View, { style: { marginLeft: theme.spacing.sm }, children: tag }) : null
4306
+ tag ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_native33.View, { style: { marginLeft: theme.spacing.sm }, children: tag }) : null
4272
4307
  ] }),
4273
- rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_react_native32.View, { children: rightMetric }) : null
4308
+ rightMetric ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_native33.View, { children: rightMetric }) : null
4274
4309
  ] }),
4275
- subtitle ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
4310
+ subtitle ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
4276
4311
  Text,
4277
4312
  {
4278
4313
  numberOfLines: 2,
@@ -4315,20 +4350,20 @@ function statusDescription(status, statusError) {
4315
4350
  }
4316
4351
 
4317
4352
  // src/studio/ui/preview-panel/PreviewMetaSection.tsx
4318
- var import_jsx_runtime33 = require("react/jsx-runtime");
4353
+ var import_jsx_runtime35 = require("react/jsx-runtime");
4319
4354
  function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
4320
4355
  var _a;
4321
4356
  const theme = useTheme();
4322
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
4357
+ return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
4323
4358
  PreviewMetaRow,
4324
4359
  {
4325
4360
  title: app.name,
4326
4361
  subtitle: app.description,
4327
4362
  avatarUri: (creator == null ? void 0 : creator.avatar) ?? null,
4328
4363
  creatorName: (creator == null ? void 0 : creator.name) ?? null,
4329
- tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_react_native33.View, { style: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 999, backgroundColor: "#3700B3" }, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Text, { variant: "caption", style: { color: "#fff", fontWeight: theme.typography.fontWeight.semibold }, children: app.forkedFromAppId ? "Remix" : "Owner" }) }) : null,
4330
- rightMetric: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(
4331
- import_react_native33.View,
4364
+ tag: isOwner || app.forkedFromAppId ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(import_react_native34.View, { style: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 999, backgroundColor: "#3700B3" }, children: /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(Text, { variant: "caption", style: { color: "#fff", fontWeight: theme.typography.fontWeight.semibold }, children: app.forkedFromAppId ? "Remix" : "Owner" }) }) : null,
4365
+ rightMetric: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)(
4366
+ import_react_native34.View,
4332
4367
  {
4333
4368
  style: {
4334
4369
  flexDirection: "row",
@@ -4339,7 +4374,7 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
4339
4374
  backgroundColor: withAlpha(theme.colors.neutral, 0.3)
4340
4375
  },
4341
4376
  children: [
4342
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
4377
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
4343
4378
  Text,
4344
4379
  {
4345
4380
  style: {
@@ -4352,7 +4387,7 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
4352
4387
  children: formatCount(downloadsCount ?? ((_a = app.insights) == null ? void 0 : _a.totalDownloads) ?? 0)
4353
4388
  }
4354
4389
  ),
4355
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(IconPlay, { size: 14, colorToken: "textMuted", fill: theme.colors.textMuted })
4390
+ /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(IconPlay, { size: 14, colorToken: "textMuted", fill: theme.colors.textMuted })
4356
4391
  ]
4357
4392
  }
4358
4393
  ),
@@ -4362,11 +4397,11 @@ function PreviewMetaSection({ app, isOwner, creator, downloadsCount }) {
4362
4397
  }
4363
4398
 
4364
4399
  // src/studio/ui/preview-panel/PreviewCustomizeSection.tsx
4365
- var import_react_native35 = require("react-native");
4400
+ var import_react_native36 = require("react-native");
4366
4401
 
4367
4402
  // src/studio/ui/preview-panel/PressableCardRow.tsx
4368
- var import_react_native34 = require("react-native");
4369
- var import_jsx_runtime34 = require("react/jsx-runtime");
4403
+ var import_react_native35 = require("react-native");
4404
+ var import_jsx_runtime36 = require("react/jsx-runtime");
4370
4405
  function PressableCardRow({
4371
4406
  accessibilityLabel,
4372
4407
  onPress,
@@ -4377,31 +4412,31 @@ function PressableCardRow({
4377
4412
  right,
4378
4413
  style
4379
4414
  }) {
4380
- return /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
4381
- import_react_native34.Pressable,
4415
+ return /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4416
+ import_react_native35.Pressable,
4382
4417
  {
4383
4418
  accessibilityRole: "button",
4384
4419
  accessibilityLabel,
4385
4420
  disabled,
4386
4421
  onPress,
4387
4422
  style: ({ pressed }) => ({ opacity: disabled ? 0.6 : pressed ? 0.85 : 1 }),
4388
- children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(Card, { padded: false, border: false, style, children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native34.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
4423
+ children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Card, { padded: false, border: false, style, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
4389
4424
  left,
4390
- /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)(import_react_native34.View, { style: { flex: 1, minWidth: 0 }, children: [
4425
+ /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { style: { flex: 1, minWidth: 0 }, children: [
4391
4426
  title,
4392
4427
  subtitle ? subtitle : null
4393
4428
  ] }),
4394
- right ? /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(import_react_native34.View, { style: { marginLeft: 16 }, children: right }) : null
4429
+ right ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native35.View, { style: { marginLeft: 16 }, children: right }) : null
4395
4430
  ] }) })
4396
4431
  }
4397
4432
  );
4398
4433
  }
4399
4434
 
4400
4435
  // src/studio/ui/preview-panel/SectionTitle.tsx
4401
- var import_jsx_runtime35 = require("react/jsx-runtime");
4436
+ var import_jsx_runtime37 = require("react/jsx-runtime");
4402
4437
  function SectionTitle({ children, marginTop }) {
4403
4438
  const theme = useTheme();
4404
- return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(
4439
+ return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
4405
4440
  Text,
4406
4441
  {
4407
4442
  style: {
@@ -4420,7 +4455,7 @@ function SectionTitle({ children, marginTop }) {
4420
4455
  }
4421
4456
 
4422
4457
  // src/studio/ui/preview-panel/PreviewCustomizeSection.tsx
4423
- var import_jsx_runtime36 = require("react/jsx-runtime");
4458
+ var import_jsx_runtime38 = require("react/jsx-runtime");
4424
4459
  function PreviewCustomizeSection({
4425
4460
  app,
4426
4461
  isOwner,
@@ -4430,10 +4465,10 @@ function PreviewCustomizeSection({
4430
4465
  onStartDraw
4431
4466
  }) {
4432
4467
  const theme = useTheme();
4433
- return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
4434
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(SectionTitle, { children: "Customize" }),
4435
- showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
4436
- import_react_native35.View,
4468
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_jsx_runtime38.Fragment, { children: [
4469
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SectionTitle, { children: "Customize" }),
4470
+ showProcessing ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
4471
+ import_react_native36.View,
4437
4472
  {
4438
4473
  style: {
4439
4474
  flexDirection: "row",
@@ -4446,8 +4481,8 @@ function PreviewCustomizeSection({
4446
4481
  marginBottom: theme.spacing.sm
4447
4482
  },
4448
4483
  children: [
4449
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4450
- import_react_native35.View,
4484
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4485
+ import_react_native36.View,
4451
4486
  {
4452
4487
  style: {
4453
4488
  width: 40,
@@ -4458,17 +4493,17 @@ function PreviewCustomizeSection({
4458
4493
  backgroundColor: withAlpha(theme.colors.warning, 0.1),
4459
4494
  marginRight: theme.spacing.lg
4460
4495
  },
4461
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_react_native35.ActivityIndicator, { color: theme.colors.warning, size: "small" })
4496
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native36.ActivityIndicator, { color: theme.colors.warning, size: "small" })
4462
4497
  }
4463
4498
  ),
4464
- /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_react_native35.View, { style: { flex: 1, minWidth: 0 }, children: [
4465
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: app.status === "error" ? "Error" : "Processing" }),
4466
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: statusDescription(app.status, app.statusError) })
4499
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native36.View, { style: { flex: 1, minWidth: 0 }, children: [
4500
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: app.status === "error" ? "Error" : "Processing" }),
4501
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: statusDescription(app.status, app.statusError) })
4467
4502
  ] })
4468
4503
  ]
4469
4504
  }
4470
4505
  ) : null,
4471
- /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4506
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4472
4507
  PressableCardRow,
4473
4508
  {
4474
4509
  accessibilityLabel: isOwner ? "Edit app" : "Remix app",
@@ -4481,8 +4516,8 @@ function PreviewCustomizeSection({
4481
4516
  borderColor: withAlpha(theme.colors.primary, 0.1),
4482
4517
  marginBottom: theme.spacing.sm
4483
4518
  },
4484
- left: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4485
- import_react_native35.View,
4519
+ left: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4520
+ import_react_native36.View,
4486
4521
  {
4487
4522
  style: {
4488
4523
  width: 40,
@@ -4493,15 +4528,15 @@ function PreviewCustomizeSection({
4493
4528
  backgroundColor: withAlpha(theme.colors.primary, 0.1),
4494
4529
  marginRight: theme.spacing.lg
4495
4530
  },
4496
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(IconChat, { size: 20, colorToken: "primary" })
4531
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(IconChat, { size: 20, colorToken: "primary" })
4497
4532
  }
4498
4533
  ),
4499
- title: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: isOwner ? app.forkedFromAppId ? "Edit your Remix" : "Edit Your App" : "Remix App" }),
4500
- subtitle: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: isOwner && app.forkedFromAppId ? "Make changes to your remix with chat" : shouldForkOnEdit ? "Chat to create your own copy and edit it" : "Chat to apply changes" }),
4501
- right: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(IconChevronRight, { size: 20, colorToken: "textMuted" })
4534
+ title: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: isOwner ? app.forkedFromAppId ? "Edit your Remix" : "Edit Your App" : "Remix App" }),
4535
+ subtitle: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: isOwner && app.forkedFromAppId ? "Make changes to your remix with chat" : shouldForkOnEdit ? "Chat to create your own copy and edit it" : "Chat to apply changes" }),
4536
+ right: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(IconChevronRight, { size: 20, colorToken: "textMuted" })
4502
4537
  }
4503
4538
  ),
4504
- isOwner && onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4539
+ isOwner && onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4505
4540
  PressableCardRow,
4506
4541
  {
4507
4542
  accessibilityLabel: "Draw changes",
@@ -4514,8 +4549,8 @@ function PreviewCustomizeSection({
4514
4549
  borderColor: withAlpha(theme.colors.danger, 0.1),
4515
4550
  marginBottom: theme.spacing.sm
4516
4551
  },
4517
- left: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
4518
- import_react_native35.View,
4552
+ left: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4553
+ import_react_native36.View,
4519
4554
  {
4520
4555
  style: {
4521
4556
  width: 40,
@@ -4526,31 +4561,31 @@ function PreviewCustomizeSection({
4526
4561
  backgroundColor: withAlpha(theme.colors.danger, 0.1),
4527
4562
  marginRight: theme.spacing.lg
4528
4563
  },
4529
- children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(IconDraw, { size: 20, colorToken: "danger" })
4564
+ children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(IconDraw, { size: 20, colorToken: "danger" })
4530
4565
  }
4531
4566
  ),
4532
- title: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Draw Changes" }),
4533
- subtitle: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Annotate the app with drawings" }),
4534
- right: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(IconChevronRight, { size: 20, colorToken: "textMuted" })
4567
+ title: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Draw Changes" }),
4568
+ subtitle: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Annotate the app with drawings" }),
4569
+ right: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(IconChevronRight, { size: 20, colorToken: "textMuted" })
4535
4570
  }
4536
4571
  ) : null
4537
4572
  ] });
4538
4573
  }
4539
4574
 
4540
4575
  // src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
4541
- var React29 = __toESM(require("react"));
4542
- var import_react_native41 = require("react-native");
4576
+ var React31 = __toESM(require("react"));
4577
+ var import_react_native42 = require("react-native");
4543
4578
  var import_lucide_react_native9 = require("lucide-react-native");
4544
4579
 
4545
4580
  // src/components/merge-requests/MergeRequestStatusCard.tsx
4546
- var React25 = __toESM(require("react"));
4547
- var import_react_native37 = require("react-native");
4581
+ var React27 = __toESM(require("react"));
4582
+ var import_react_native38 = require("react-native");
4548
4583
  var import_lucide_react_native7 = require("lucide-react-native");
4549
4584
 
4550
4585
  // src/components/primitives/MarkdownText.tsx
4551
- var import_react_native36 = require("react-native");
4586
+ var import_react_native37 = require("react-native");
4552
4587
  var import_react_native_markdown_display = __toESM(require("react-native-markdown-display"));
4553
- var import_jsx_runtime37 = require("react/jsx-runtime");
4588
+ var import_jsx_runtime39 = require("react/jsx-runtime");
4554
4589
  function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
4555
4590
  const theme = useTheme();
4556
4591
  const isDark = theme.scheme === "dark";
@@ -4561,7 +4596,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
4561
4596
  const codeTextColor = isDark ? "#FFFFFF" : theme.colors.text;
4562
4597
  const paragraphBottom = variant === "mergeRequest" ? 8 : 6;
4563
4598
  const baseLineHeight = variant === "mergeRequest" ? 22 : 20;
4564
- return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_react_native36.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
4599
+ return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_react_native37.View, { style, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4565
4600
  import_react_native_markdown_display.default,
4566
4601
  {
4567
4602
  style: {
@@ -4574,7 +4609,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
4574
4609
  paddingHorizontal: variant === "mergeRequest" ? 6 : 4,
4575
4610
  paddingVertical: variant === "mergeRequest" ? 2 : 0,
4576
4611
  borderRadius: variant === "mergeRequest" ? 6 : 4,
4577
- fontFamily: import_react_native36.Platform.OS === "ios" ? "Menlo" : "monospace",
4612
+ fontFamily: import_react_native37.Platform.OS === "ios" ? "Menlo" : "monospace",
4578
4613
  fontSize: 13
4579
4614
  },
4580
4615
  code_block: {
@@ -4625,11 +4660,11 @@ function toIsoString(input) {
4625
4660
  }
4626
4661
 
4627
4662
  // src/components/merge-requests/useControlledExpansion.ts
4628
- var React24 = __toESM(require("react"));
4663
+ var React26 = __toESM(require("react"));
4629
4664
  function useControlledExpansion(props) {
4630
- const [uncontrolled, setUncontrolled] = React24.useState(false);
4665
+ const [uncontrolled, setUncontrolled] = React26.useState(false);
4631
4666
  const expanded = props.expanded ?? uncontrolled;
4632
- const setExpanded = React24.useCallback(
4667
+ const setExpanded = React26.useCallback(
4633
4668
  (next) => {
4634
4669
  var _a;
4635
4670
  (_a = props.onExpandedChange) == null ? void 0 : _a.call(props, next);
@@ -4641,7 +4676,7 @@ function useControlledExpansion(props) {
4641
4676
  }
4642
4677
 
4643
4678
  // src/components/merge-requests/MergeRequestStatusCard.tsx
4644
- var import_jsx_runtime38 = require("react/jsx-runtime");
4679
+ var import_jsx_runtime40 = require("react/jsx-runtime");
4645
4680
  function MergeRequestStatusCard({
4646
4681
  mergeRequest,
4647
4682
  expanded: expandedProp,
@@ -4654,8 +4689,8 @@ function MergeRequestStatusCard({
4654
4689
  const isDark = theme.scheme === "dark";
4655
4690
  const textColor = isDark ? "#FFFFFF" : "#000000";
4656
4691
  const subTextColor = isDark ? "#A1A1AA" : "#71717A";
4657
- const status = React25.useMemo(() => getMergeRequestStatusDisplay(String(mergeRequest.status)), [mergeRequest.status]);
4658
- const { StatusIcon, iconColor, bgColor, statusText } = React25.useMemo(() => {
4692
+ const status = React27.useMemo(() => getMergeRequestStatusDisplay(String(mergeRequest.status)), [mergeRequest.status]);
4693
+ const { StatusIcon, iconColor, bgColor, statusText } = React27.useMemo(() => {
4659
4694
  switch (mergeRequest.status) {
4660
4695
  case "approved":
4661
4696
  case "merged":
@@ -4686,15 +4721,15 @@ function MergeRequestStatusCard({
4686
4721
  const createdIso = toIsoString(mergeRequest.createdAt ?? null);
4687
4722
  const headerTimeAgo = updatedIso ? formatTimeAgo(updatedIso) : "";
4688
4723
  const createdTimeAgo = createdIso ? formatTimeAgo(createdIso) : "";
4689
- const rotate = React25.useRef(new import_react_native37.Animated.Value(expanded ? 1 : 0)).current;
4690
- React25.useEffect(() => {
4691
- import_react_native37.Animated.timing(rotate, {
4724
+ const rotate = React27.useRef(new import_react_native38.Animated.Value(expanded ? 1 : 0)).current;
4725
+ React27.useEffect(() => {
4726
+ import_react_native38.Animated.timing(rotate, {
4692
4727
  toValue: expanded ? 1 : 0,
4693
4728
  duration: 200,
4694
4729
  useNativeDriver: true
4695
4730
  }).start();
4696
4731
  }, [expanded, rotate]);
4697
- return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native37.Pressable, { onPress: () => setExpanded(!expanded), style: ({ pressed }) => [{ opacity: pressed ? 0.95 : 1 }], children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
4732
+ return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.Pressable, { onPress: () => setExpanded(!expanded), style: ({ pressed }) => [{ opacity: pressed ? 0.95 : 1 }], children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
4698
4733
  Card,
4699
4734
  {
4700
4735
  padded: false,
@@ -4707,11 +4742,11 @@ function MergeRequestStatusCard({
4707
4742
  style
4708
4743
  ],
4709
4744
  children: [
4710
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native37.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.lg }, children: [
4711
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native37.View, { style: { width: 40, height: 40, borderRadius: 999, alignItems: "center", justifyContent: "center", backgroundColor: bgColor }, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(StatusIcon, { size: 20, color: iconColor }) }),
4712
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native37.View, { style: { flex: 1, minWidth: 0 }, children: [
4713
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native37.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
4714
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4745
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", gap: theme.spacing.lg }, children: [
4746
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.View, { style: { width: 40, height: 40, borderRadius: 999, alignItems: "center", justifyContent: "center", backgroundColor: bgColor }, children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(StatusIcon, { size: 20, color: iconColor }) }),
4747
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flex: 1, minWidth: 0 }, children: [
4748
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
4749
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4715
4750
  Text,
4716
4751
  {
4717
4752
  style: {
@@ -4725,12 +4760,12 @@ function MergeRequestStatusCard({
4725
4760
  children: statusText
4726
4761
  }
4727
4762
  ),
4728
- headerTimeAgo ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { fontSize: 10, lineHeight: 14, marginLeft: theme.spacing.sm, color: withAlpha(theme.colors.textMuted, 0.6) }, children: headerTimeAgo }) : null
4763
+ headerTimeAgo ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 10, lineHeight: 14, marginLeft: theme.spacing.sm, color: withAlpha(theme.colors.textMuted, 0.6) }, children: headerTimeAgo }) : null
4729
4764
  ] }),
4730
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, numberOfLines: 1, children: mergeRequest.title ?? "Untitled merge request" })
4765
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 12, lineHeight: 16, color: theme.colors.textMuted }, numberOfLines: 1, children: mergeRequest.title ?? "Untitled merge request" })
4731
4766
  ] }),
4732
- headerRight ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_react_native37.View, { children: headerRight }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4733
- import_react_native37.Animated.View,
4767
+ headerRight ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native38.View, { children: headerRight }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4768
+ import_react_native38.Animated.View,
4734
4769
  {
4735
4770
  style: {
4736
4771
  transform: [
@@ -4739,12 +4774,12 @@ function MergeRequestStatusCard({
4739
4774
  }
4740
4775
  ]
4741
4776
  },
4742
- children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_lucide_react_native7.ChevronDown, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
4777
+ children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native7.ChevronDown, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
4743
4778
  }
4744
4779
  )
4745
4780
  ] }),
4746
- expanded ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(import_react_native37.View, { style: { marginTop: 16, marginLeft: 56 }, children: [
4747
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4781
+ expanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native38.View, { style: { marginTop: 16, marginLeft: 56 }, children: [
4782
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4748
4783
  Text,
4749
4784
  {
4750
4785
  style: {
@@ -4758,7 +4793,7 @@ function MergeRequestStatusCard({
4758
4793
  children: status.text
4759
4794
  }
4760
4795
  ),
4761
- createdTimeAgo ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
4796
+ createdTimeAgo ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4762
4797
  Text,
4763
4798
  {
4764
4799
  style: {
@@ -4769,8 +4804,8 @@ function MergeRequestStatusCard({
4769
4804
  children: createdTimeAgo
4770
4805
  }
4771
4806
  ) : null,
4772
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { style: { fontSize: 16, fontWeight: "600", color: textColor, marginBottom: 8 }, children: mergeRequest.title ?? "Untitled merge request" }),
4773
- mergeRequest.description ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(MarkdownText, { markdown: mergeRequest.description, variant: "mergeRequest" }) : null
4807
+ /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 16, fontWeight: "600", color: textColor, marginBottom: 8 }, children: mergeRequest.title ?? "Untitled merge request" }),
4808
+ mergeRequest.description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MarkdownText, { markdown: mergeRequest.description, variant: "mergeRequest" }) : null
4774
4809
  ] }) : null
4775
4810
  ]
4776
4811
  }
@@ -4778,18 +4813,18 @@ function MergeRequestStatusCard({
4778
4813
  }
4779
4814
 
4780
4815
  // src/components/merge-requests/ReviewMergeRequestCarousel.tsx
4781
- var React28 = __toESM(require("react"));
4782
- var import_react_native40 = require("react-native");
4816
+ var React30 = __toESM(require("react"));
4817
+ var import_react_native41 = require("react-native");
4783
4818
 
4784
4819
  // src/components/merge-requests/ReviewMergeRequestCard.tsx
4785
- var React27 = __toESM(require("react"));
4786
- var import_react_native39 = require("react-native");
4820
+ var React29 = __toESM(require("react"));
4821
+ var import_react_native40 = require("react-native");
4787
4822
  var import_lucide_react_native8 = require("lucide-react-native");
4788
4823
 
4789
4824
  // src/components/merge-requests/ReviewMergeRequestActionButton.tsx
4790
- var React26 = __toESM(require("react"));
4791
- var import_react_native38 = require("react-native");
4792
- var import_jsx_runtime39 = require("react/jsx-runtime");
4825
+ var React28 = __toESM(require("react"));
4826
+ var import_react_native39 = require("react-native");
4827
+ var import_jsx_runtime41 = require("react/jsx-runtime");
4793
4828
  function ReviewMergeRequestActionButton({
4794
4829
  accessibilityLabel,
4795
4830
  backgroundColor,
@@ -4798,14 +4833,14 @@ function ReviewMergeRequestActionButton({
4798
4833
  children,
4799
4834
  iconOnly
4800
4835
  }) {
4801
- const [pressed, setPressed] = React26.useState(false);
4836
+ const [pressed, setPressed] = React28.useState(false);
4802
4837
  const height = iconOnly ? 36 : 40;
4803
4838
  const width = iconOnly ? 36 : void 0;
4804
4839
  const paddingHorizontal = iconOnly ? 0 : 16;
4805
4840
  const paddingVertical = iconOnly ? 0 : 8;
4806
4841
  const opacity = disabled ? 0.5 : pressed ? 0.9 : 1;
4807
- return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4808
- import_react_native38.View,
4842
+ return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
4843
+ import_react_native39.View,
4809
4844
  {
4810
4845
  style: {
4811
4846
  width,
@@ -4819,8 +4854,8 @@ function ReviewMergeRequestActionButton({
4819
4854
  paddingVertical,
4820
4855
  justifyContent: "center"
4821
4856
  },
4822
- children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
4823
- import_react_native38.Pressable,
4857
+ children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
4858
+ import_react_native39.Pressable,
4824
4859
  {
4825
4860
  accessibilityRole: "button",
4826
4861
  accessibilityLabel,
@@ -4843,7 +4878,7 @@ function ReviewMergeRequestActionButton({
4843
4878
  }
4844
4879
 
4845
4880
  // src/components/merge-requests/ReviewMergeRequestCard.tsx
4846
- var import_jsx_runtime40 = require("react/jsx-runtime");
4881
+ var import_jsx_runtime42 = require("react/jsx-runtime");
4847
4882
  function ReviewMergeRequestCard({
4848
4883
  mr,
4849
4884
  index,
@@ -4860,14 +4895,14 @@ function ReviewMergeRequestCard({
4860
4895
  onTest
4861
4896
  }) {
4862
4897
  const theme = useTheme();
4863
- const status = React27.useMemo(() => getMergeRequestStatusDisplay(mr.status), [mr.status]);
4898
+ const status = React29.useMemo(() => getMergeRequestStatusDisplay(mr.status), [mr.status]);
4864
4899
  const canAct = mr.status === "open";
4865
- const rotate = React27.useRef(new import_react_native39.Animated.Value(isExpanded ? 1 : 0)).current;
4866
- React27.useEffect(() => {
4867
- import_react_native39.Animated.timing(rotate, { toValue: isExpanded ? 1 : 0, duration: 200, useNativeDriver: true }).start();
4900
+ const rotate = React29.useRef(new import_react_native40.Animated.Value(isExpanded ? 1 : 0)).current;
4901
+ React29.useEffect(() => {
4902
+ import_react_native40.Animated.timing(rotate, { toValue: isExpanded ? 1 : 0, duration: 200, useNativeDriver: true }).start();
4868
4903
  }, [isExpanded, rotate]);
4869
4904
  const position = total > 1 ? `${index + 1}/${total}` : "Merge request";
4870
- return /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.Pressable, { onPress: onToggle, style: ({ pressed }) => ({ opacity: pressed ? 0.95 : 1 }), children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(
4905
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native40.Pressable, { onPress: onToggle, style: ({ pressed }) => ({ opacity: pressed ? 0.95 : 1 }), children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
4871
4906
  Card,
4872
4907
  {
4873
4908
  padded: false,
@@ -4880,10 +4915,10 @@ function ReviewMergeRequestCard({
4880
4915
  }
4881
4916
  ],
4882
4917
  children: [
4883
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
4884
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Avatar, { size: 40, uri: (creator == null ? void 0 : creator.avatar) ?? null, name: (creator == null ? void 0 : creator.name) ?? void 0 }),
4885
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flex: 1, minWidth: 0 }, children: [
4886
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4918
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: 12 }, children: [
4919
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Avatar, { size: 40, uri: (creator == null ? void 0 : creator.avatar) ?? null, name: (creator == null ? void 0 : creator.name) ?? void 0 }),
4920
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flex: 1, minWidth: 0 }, children: [
4921
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4887
4922
  Text,
4888
4923
  {
4889
4924
  style: { fontWeight: theme.typography.fontWeight.semibold, color: theme.colors.text, fontSize: 16, lineHeight: 20 },
@@ -4891,24 +4926,24 @@ function ReviewMergeRequestCard({
4891
4926
  children: mr.title ?? "Untitled merge request"
4892
4927
  }
4893
4928
  ),
4894
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16 }, numberOfLines: 1, children: [
4929
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16 }, numberOfLines: 1, children: [
4895
4930
  (creator == null ? void 0 : creator.name) ?? "Loading...",
4896
4931
  " \xB7 ",
4897
4932
  position
4898
4933
  ] })
4899
4934
  ] }),
4900
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4901
- import_react_native39.Animated.View,
4935
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4936
+ import_react_native40.Animated.View,
4902
4937
  {
4903
4938
  style: {
4904
4939
  transform: [{ rotate: rotate.interpolate({ inputRange: [0, 1], outputRange: ["0deg", "180deg"] }) }]
4905
4940
  },
4906
- children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.ChevronDown, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
4941
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react_native8.ChevronDown, { size: 20, color: withAlpha(theme.colors.textMuted, 0.4) })
4907
4942
  }
4908
4943
  )
4909
4944
  ] }),
4910
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { marginTop: 16 }, children: [
4911
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4945
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { marginTop: 16 }, children: [
4946
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4912
4947
  Text,
4913
4948
  {
4914
4949
  style: {
@@ -4922,13 +4957,13 @@ function ReviewMergeRequestCard({
4922
4957
  children: status.text
4923
4958
  }
4924
4959
  ),
4925
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginBottom: 12 }, children: creator ? `${creator.approvedOpenedMergeRequests} approved merge${creator.approvedOpenedMergeRequests !== 1 ? "s" : ""}` : "Loading stats..." }),
4926
- mr.description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(MarkdownText, { markdown: mr.description, variant: "mergeRequest" }) : null
4960
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginBottom: 12 }, children: creator ? `${creator.approvedOpenedMergeRequests} approved merge${creator.approvedOpenedMergeRequests !== 1 ? "s" : ""}` : "Loading stats..." }),
4961
+ mr.description ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MarkdownText, { markdown: mr.description, variant: "mergeRequest" }) : null
4927
4962
  ] }) : null,
4928
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.View, { style: { height: 1, backgroundColor: withAlpha(theme.colors.borderStrong, 0.5), marginTop: 12, marginBottom: 12 } }),
4929
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
4930
- /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", gap: 8 }, children: [
4931
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4963
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native40.View, { style: { height: 1, backgroundColor: withAlpha(theme.colors.borderStrong, 0.5), marginTop: 12, marginBottom: 12 } }),
4964
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" }, children: [
4965
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", gap: 8 }, children: [
4966
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4932
4967
  ReviewMergeRequestActionButton,
4933
4968
  {
4934
4969
  accessibilityLabel: "Reject",
@@ -4936,13 +4971,13 @@ function ReviewMergeRequestCard({
4936
4971
  disabled: !canAct || isAnyProcessing,
4937
4972
  onPress: onReject,
4938
4973
  iconOnly: !isExpanded,
4939
- children: /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
4940
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.X, { size: 18, color: "#FFFFFF" }),
4941
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Reject" }) : null
4974
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
4975
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react_native8.X, { size: 18, color: "#FFFFFF" }),
4976
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Reject" }) : null
4942
4977
  ] })
4943
4978
  }
4944
4979
  ),
4945
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4980
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4946
4981
  ReviewMergeRequestActionButton,
4947
4982
  {
4948
4983
  accessibilityLabel: !canAct ? "Not actionable" : isProcessing ? "Processing" : "Approve",
@@ -4950,17 +4985,17 @@ function ReviewMergeRequestCard({
4950
4985
  disabled: !canAct || isAnyProcessing,
4951
4986
  onPress: onApprove,
4952
4987
  iconOnly: !isExpanded,
4953
- children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
4954
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
4955
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Processing" }) : null
4956
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
4957
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.Check, { size: 18, color: "#FFFFFF" }),
4958
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Approve" }) : null
4988
+ children: isProcessing ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
4989
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native40.ActivityIndicator, { size: "small", color: "#FFFFFF" }),
4990
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Processing" }) : null
4991
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
4992
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react_native8.Check, { size: 18, color: "#FFFFFF" }),
4993
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 13, color: "#FFFFFF", fontWeight: theme.typography.fontWeight.semibold }, children: "Approve" }) : null
4959
4994
  ] })
4960
4995
  }
4961
4996
  )
4962
4997
  ] }),
4963
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(
4998
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4964
4999
  ReviewMergeRequestActionButton,
4965
5000
  {
4966
5001
  accessibilityLabel: "Test",
@@ -4968,9 +5003,9 @@ function ReviewMergeRequestCard({
4968
5003
  disabled: isBuilding || isTestingThis,
4969
5004
  onPress: onTest,
4970
5005
  iconOnly: !isExpanded,
4971
- children: isTestingThis ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_react_native39.ActivityIndicator, { size: "small", color: "#888" }) : /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_react_native39.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
4972
- /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(import_lucide_react_native8.Play, { size: 14, color: theme.colors.text }),
4973
- isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { style: { fontSize: 13, color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: "Test" }) : null
5006
+ children: isTestingThis ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native40.ActivityIndicator, { size: "small", color: "#888" }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_react_native40.View, { style: { flexDirection: "row", alignItems: "center", gap: isExpanded ? 4 : 0 }, children: [
5007
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react_native8.Play, { size: 14, color: theme.colors.text }),
5008
+ isExpanded ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { fontSize: 13, color: theme.colors.text, fontWeight: theme.typography.fontWeight.semibold }, children: "Test" }) : null
4974
5009
  ] })
4975
5010
  }
4976
5011
  )
@@ -4981,7 +5016,7 @@ function ReviewMergeRequestCard({
4981
5016
  }
4982
5017
 
4983
5018
  // src/components/merge-requests/ReviewMergeRequestCarousel.tsx
4984
- var import_jsx_runtime41 = require("react/jsx-runtime");
5019
+ var import_jsx_runtime43 = require("react/jsx-runtime");
4985
5020
  function ReviewMergeRequestCarousel({
4986
5021
  mergeRequests,
4987
5022
  creatorStatsById,
@@ -4994,32 +5029,32 @@ function ReviewMergeRequestCarousel({
4994
5029
  style
4995
5030
  }) {
4996
5031
  const theme = useTheme();
4997
- const { width } = (0, import_react_native40.useWindowDimensions)();
4998
- const [expanded, setExpanded] = React28.useState({});
4999
- const carouselScrollX = React28.useRef(new import_react_native40.Animated.Value(0)).current;
5032
+ const { width } = (0, import_react_native41.useWindowDimensions)();
5033
+ const [expanded, setExpanded] = React30.useState({});
5034
+ const carouselScrollX = React30.useRef(new import_react_native41.Animated.Value(0)).current;
5000
5035
  const peekAmount = 24;
5001
5036
  const gap = 16;
5002
- const cardWidth = React28.useMemo(() => Math.max(1, width - theme.spacing.lg * 2 - peekAmount), [peekAmount, theme.spacing.lg, width]);
5037
+ const cardWidth = React30.useMemo(() => Math.max(1, width - theme.spacing.lg * 2 - peekAmount), [peekAmount, theme.spacing.lg, width]);
5003
5038
  const snapInterval = cardWidth + gap;
5004
5039
  const dotColor = theme.scheme === "dark" ? "#FFFFFF" : "#000000";
5005
5040
  if (mergeRequests.length === 0) return null;
5006
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(import_react_native40.View, { style: [{ marginHorizontal: -theme.spacing.lg }, style], children: [
5007
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
5008
- import_react_native40.FlatList,
5041
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native41.View, { style: [{ marginHorizontal: -theme.spacing.lg }, style], children: [
5042
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
5043
+ import_react_native41.FlatList,
5009
5044
  {
5010
5045
  horizontal: true,
5011
5046
  data: mergeRequests,
5012
5047
  keyExtractor: (mr) => mr.id,
5013
5048
  showsHorizontalScrollIndicator: false,
5014
5049
  contentContainerStyle: { paddingHorizontal: theme.spacing.lg, paddingVertical: theme.spacing.sm },
5015
- ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { style: { width: gap } }),
5050
+ ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.View, { style: { width: gap } }),
5016
5051
  snapToAlignment: "start",
5017
5052
  decelerationRate: "fast",
5018
5053
  snapToInterval: snapInterval,
5019
5054
  disableIntervalMomentum: true,
5020
5055
  style: { paddingRight: peekAmount },
5021
- ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { style: { width: peekAmount } }),
5022
- onScroll: import_react_native40.Animated.event([{ nativeEvent: { contentOffset: { x: carouselScrollX } } }], {
5056
+ ListFooterComponent: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.View, { style: { width: peekAmount } }),
5057
+ onScroll: import_react_native41.Animated.event([{ nativeEvent: { contentOffset: { x: carouselScrollX } } }], {
5023
5058
  useNativeDriver: false
5024
5059
  }),
5025
5060
  scrollEventThrottle: 16,
@@ -5030,7 +5065,7 @@ function ReviewMergeRequestCarousel({
5030
5065
  const isProcessing = Boolean(processingMrId && processingMrId === item.id);
5031
5066
  const isAnyProcessing = Boolean(processingMrId);
5032
5067
  const isTestingThis = Boolean(testingMrId && testingMrId === item.id);
5033
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { style: { width: cardWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
5068
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.View, { style: { width: cardWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
5034
5069
  ReviewMergeRequestCard,
5035
5070
  {
5036
5071
  mr: item,
@@ -5051,7 +5086,7 @@ function ReviewMergeRequestCarousel({
5051
5086
  }
5052
5087
  }
5053
5088
  ),
5054
- mergeRequests.length >= 1 ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_react_native40.View, { style: { flexDirection: "row", justifyContent: "center", columnGap: 8, marginTop: theme.spacing.md }, children: mergeRequests.map((mr, index) => {
5089
+ mergeRequests.length >= 1 ? /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native41.View, { style: { flexDirection: "row", justifyContent: "center", columnGap: 8, marginTop: theme.spacing.md }, children: mergeRequests.map((mr, index) => {
5055
5090
  const inputRange = [(index - 1) * snapInterval, index * snapInterval, (index + 1) * snapInterval];
5056
5091
  const scale = carouselScrollX.interpolate({
5057
5092
  inputRange,
@@ -5063,8 +5098,8 @@ function ReviewMergeRequestCarousel({
5063
5098
  outputRange: [0.4, 1, 0.4],
5064
5099
  extrapolate: "clamp"
5065
5100
  });
5066
- return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
5067
- import_react_native40.Animated.View,
5101
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
5102
+ import_react_native41.Animated.View,
5068
5103
  {
5069
5104
  style: {
5070
5105
  width: 8,
@@ -5082,7 +5117,7 @@ function ReviewMergeRequestCarousel({
5082
5117
  }
5083
5118
 
5084
5119
  // src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
5085
- var import_jsx_runtime42 = require("react/jsx-runtime");
5120
+ var import_jsx_runtime44 = require("react/jsx-runtime");
5086
5121
  function PreviewCollaborateSection({
5087
5122
  canSubmitMergeRequest,
5088
5123
  incomingMergeRequests,
@@ -5098,13 +5133,13 @@ function PreviewCollaborateSection({
5098
5133
  onTestMr
5099
5134
  }) {
5100
5135
  const theme = useTheme();
5101
- const [submittingMr, setSubmittingMr] = React29.useState(false);
5136
+ const [submittingMr, setSubmittingMr] = React31.useState(false);
5102
5137
  const hasSection = canSubmitMergeRequest || incomingMergeRequests.length > 0 || outgoingMergeRequests.length > 0;
5103
5138
  if (!hasSection) return null;
5104
5139
  const showActionsSubtitle = canSubmitMergeRequest && onSubmitMergeRequest || onTestMr && incomingMergeRequests.length > 0;
5105
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
5106
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SectionTitle, { marginTop: theme.spacing.xl, children: "Collaborate" }),
5107
- showActionsSubtitle ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
5140
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, { children: [
5141
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(SectionTitle, { marginTop: theme.spacing.xl, children: "Collaborate" }),
5142
+ showActionsSubtitle ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
5108
5143
  Text,
5109
5144
  {
5110
5145
  style: {
@@ -5119,13 +5154,13 @@ function PreviewCollaborateSection({
5119
5154
  children: "Actions"
5120
5155
  }
5121
5156
  ) : null,
5122
- canSubmitMergeRequest && onSubmitMergeRequest ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
5157
+ canSubmitMergeRequest && onSubmitMergeRequest ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
5123
5158
  PressableCardRow,
5124
5159
  {
5125
5160
  accessibilityLabel: "Submit merge request",
5126
5161
  disabled: submittingMr,
5127
5162
  onPress: () => {
5128
- import_react_native41.Alert.alert(
5163
+ import_react_native42.Alert.alert(
5129
5164
  "Submit Merge Request",
5130
5165
  "Are you sure you want to submit your changes to the original app?",
5131
5166
  [
@@ -5150,8 +5185,8 @@ function PreviewCollaborateSection({
5150
5185
  borderColor: withAlpha("#03DAC6", 0.2),
5151
5186
  marginBottom: theme.spacing.sm
5152
5187
  },
5153
- left: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
5154
- import_react_native41.View,
5188
+ left: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
5189
+ import_react_native42.View,
5155
5190
  {
5156
5191
  style: {
5157
5192
  width: 40,
@@ -5162,15 +5197,15 @@ function PreviewCollaborateSection({
5162
5197
  backgroundColor: withAlpha("#03DAC6", 0.1),
5163
5198
  marginRight: theme.spacing.lg
5164
5199
  },
5165
- children: submittingMr ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native41.ActivityIndicator, { color: "#03DAC6", size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MergeIcon, { width: 20, height: 20, color: "#03DAC6" })
5200
+ children: submittingMr ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native42.ActivityIndicator, { color: "#03DAC6", size: "small" }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(MergeIcon, { width: 20, height: 20, color: "#03DAC6" })
5166
5201
  }
5167
5202
  ),
5168
- title: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Submit your new changes" }),
5169
- subtitle: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Ask to merge this remix to the original app" }),
5170
- right: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_lucide_react_native9.Send, { size: 16, color: "#03DAC6" })
5203
+ title: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Submit your new changes" }),
5204
+ subtitle: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: "Ask to merge this remix to the original app" }),
5205
+ right: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native9.Send, { size: 16, color: "#03DAC6" })
5171
5206
  }
5172
5207
  ) : null,
5173
- onTestMr && incomingMergeRequests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
5208
+ onTestMr && incomingMergeRequests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
5174
5209
  ReviewMergeRequestCarousel,
5175
5210
  {
5176
5211
  mergeRequests: incomingMergeRequests,
@@ -5183,8 +5218,8 @@ function PreviewCollaborateSection({
5183
5218
  onTest: (mr) => onTestMr ? onTestMr(mr) : void 0
5184
5219
  }
5185
5220
  ) : null,
5186
- outgoingMergeRequests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(import_jsx_runtime42.Fragment, { children: [
5187
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
5221
+ outgoingMergeRequests.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_jsx_runtime44.Fragment, { children: [
5222
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
5188
5223
  Text,
5189
5224
  {
5190
5225
  style: {
@@ -5200,13 +5235,13 @@ function PreviewCollaborateSection({
5200
5235
  children: "History"
5201
5236
  }
5202
5237
  ),
5203
- outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(import_react_native41.View, { style: { marginBottom: theme.spacing.sm }, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(MergeRequestStatusCard, { mergeRequest: toMergeRequestSummary(mr) }) }, mr.id))
5238
+ outgoingMergeRequests.map((mr) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native42.View, { style: { marginBottom: theme.spacing.sm }, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(MergeRequestStatusCard, { mergeRequest: toMergeRequestSummary(mr) }) }, mr.id))
5204
5239
  ] }) : null
5205
5240
  ] });
5206
5241
  }
5207
5242
 
5208
5243
  // src/studio/ui/preview-panel/usePreviewPanelData.ts
5209
- var React31 = __toESM(require("react"));
5244
+ var React33 = __toESM(require("react"));
5210
5245
 
5211
5246
  // src/data/apps/images/remote.ts
5212
5247
  var AppImagesRemoteDataSourceImpl = class extends BaseRemote {
@@ -5257,7 +5292,7 @@ var AppImagesRepositoryImpl = class extends BaseRepository {
5257
5292
  var appImagesRepository = new AppImagesRepositoryImpl(appImagesRemoteDataSource);
5258
5293
 
5259
5294
  // src/studio/hooks/useAppStats.ts
5260
- var React30 = __toESM(require("react"));
5295
+ var React32 = __toESM(require("react"));
5261
5296
  var Haptics2 = __toESM(require("expo-haptics"));
5262
5297
 
5263
5298
  // src/data/likes/remote.ts
@@ -5326,34 +5361,34 @@ function useAppStats({
5326
5361
  initialIsLiked = false,
5327
5362
  onOpenComments
5328
5363
  }) {
5329
- const [likeCount, setLikeCount] = React30.useState(initialLikes);
5330
- const [commentCount, setCommentCount] = React30.useState(initialComments);
5331
- const [forkCount, setForkCount] = React30.useState(initialForks);
5332
- const [isLiked, setIsLiked] = React30.useState(initialIsLiked);
5333
- const didMutateRef = React30.useRef(false);
5334
- const lastAppIdRef = React30.useRef("");
5335
- React30.useEffect(() => {
5364
+ const [likeCount, setLikeCount] = React32.useState(initialLikes);
5365
+ const [commentCount, setCommentCount] = React32.useState(initialComments);
5366
+ const [forkCount, setForkCount] = React32.useState(initialForks);
5367
+ const [isLiked, setIsLiked] = React32.useState(initialIsLiked);
5368
+ const didMutateRef = React32.useRef(false);
5369
+ const lastAppIdRef = React32.useRef("");
5370
+ React32.useEffect(() => {
5336
5371
  if (lastAppIdRef.current === appId) return;
5337
5372
  lastAppIdRef.current = appId;
5338
5373
  didMutateRef.current = false;
5339
5374
  }, [appId]);
5340
- React30.useEffect(() => {
5375
+ React32.useEffect(() => {
5341
5376
  if (didMutateRef.current) return;
5342
5377
  setLikeCount(initialLikes);
5343
5378
  }, [appId, initialLikes]);
5344
- React30.useEffect(() => {
5379
+ React32.useEffect(() => {
5345
5380
  if (didMutateRef.current) return;
5346
5381
  setCommentCount(initialComments);
5347
5382
  }, [appId, initialComments]);
5348
- React30.useEffect(() => {
5383
+ React32.useEffect(() => {
5349
5384
  if (didMutateRef.current) return;
5350
5385
  setForkCount(initialForks);
5351
5386
  }, [appId, initialForks]);
5352
- React30.useEffect(() => {
5387
+ React32.useEffect(() => {
5353
5388
  if (didMutateRef.current) return;
5354
5389
  setIsLiked(initialIsLiked);
5355
5390
  }, [appId, initialIsLiked]);
5356
- const handleLike = React30.useCallback(async () => {
5391
+ const handleLike = React32.useCallback(async () => {
5357
5392
  var _a, _b;
5358
5393
  if (!appId) return;
5359
5394
  didMutateRef.current = true;
@@ -5377,7 +5412,7 @@ function useAppStats({
5377
5412
  setLikeCount((prev) => Math.max(0, prev + (newIsLiked ? -1 : 1)));
5378
5413
  }
5379
5414
  }, [appId, isLiked, likeCount]);
5380
- const handleOpenComments = React30.useCallback(() => {
5415
+ const handleOpenComments = React32.useCallback(() => {
5381
5416
  if (!appId) return;
5382
5417
  try {
5383
5418
  void Haptics2.impactAsync(Haptics2.ImpactFeedbackStyle.Light);
@@ -5392,11 +5427,11 @@ function useAppStats({
5392
5427
  var LIKE_DEBUG_PREFIX = "[COMERGE_LIKE_DEBUG]";
5393
5428
  function usePreviewPanelData(params) {
5394
5429
  const { app, isOwner, outgoingMergeRequests, onOpenComments, commentCountOverride } = params;
5395
- const [imageUrl, setImageUrl] = React31.useState(null);
5396
- const [imageLoaded, setImageLoaded] = React31.useState(false);
5397
- const [insights, setInsights] = React31.useState({ likes: 0, comments: 0, forks: 0, downloads: 0 });
5398
- const [creator, setCreator] = React31.useState(null);
5399
- React31.useEffect(() => {
5430
+ const [imageUrl, setImageUrl] = React33.useState(null);
5431
+ const [imageLoaded, setImageLoaded] = React33.useState(false);
5432
+ const [insights, setInsights] = React33.useState({ likes: 0, comments: 0, forks: 0, downloads: 0 });
5433
+ const [creator, setCreator] = React33.useState(null);
5434
+ React33.useEffect(() => {
5400
5435
  if (!(app == null ? void 0 : app.id)) return;
5401
5436
  let cancelled = false;
5402
5437
  (async () => {
@@ -5411,7 +5446,7 @@ function usePreviewPanelData(params) {
5411
5446
  cancelled = true;
5412
5447
  };
5413
5448
  }, [app == null ? void 0 : app.id]);
5414
- React31.useEffect(() => {
5449
+ React33.useEffect(() => {
5415
5450
  if (!(app == null ? void 0 : app.createdBy)) return;
5416
5451
  let cancelled = false;
5417
5452
  (async () => {
@@ -5427,10 +5462,10 @@ function usePreviewPanelData(params) {
5427
5462
  cancelled = true;
5428
5463
  };
5429
5464
  }, [app == null ? void 0 : app.createdBy]);
5430
- React31.useEffect(() => {
5465
+ React33.useEffect(() => {
5431
5466
  setImageLoaded(false);
5432
5467
  }, [app == null ? void 0 : app.id]);
5433
- React31.useEffect(() => {
5468
+ React33.useEffect(() => {
5434
5469
  if (!(app == null ? void 0 : app.id)) return;
5435
5470
  let cancelled = false;
5436
5471
  (async () => {
@@ -5455,7 +5490,7 @@ function usePreviewPanelData(params) {
5455
5490
  cancelled = true;
5456
5491
  };
5457
5492
  }, [app == null ? void 0 : app.id]);
5458
- React31.useEffect(() => {
5493
+ React33.useEffect(() => {
5459
5494
  if (!(app == null ? void 0 : app.id)) return;
5460
5495
  log.debug(
5461
5496
  `${LIKE_DEBUG_PREFIX} usePreviewPanelData.appChanged appId=${app.id} app.isLiked=${String(app.isLiked)}`
@@ -5469,7 +5504,7 @@ function usePreviewPanelData(params) {
5469
5504
  initialIsLiked: Boolean(app == null ? void 0 : app.isLiked),
5470
5505
  onOpenComments
5471
5506
  });
5472
- const canSubmitMergeRequest = React31.useMemo(() => {
5507
+ const canSubmitMergeRequest = React33.useMemo(() => {
5473
5508
  if (!isOwner) return false;
5474
5509
  if (!app) return false;
5475
5510
  if (!app.forkedFromAppId) return false;
@@ -5491,7 +5526,7 @@ function usePreviewPanelData(params) {
5491
5526
  }
5492
5527
 
5493
5528
  // src/studio/ui/PreviewPanel.tsx
5494
- var import_jsx_runtime43 = require("react/jsx-runtime");
5529
+ var import_jsx_runtime45 = require("react/jsx-runtime");
5495
5530
  function PreviewPanel({
5496
5531
  app,
5497
5532
  loading,
@@ -5522,16 +5557,16 @@ function PreviewPanel({
5522
5557
  onOpenComments,
5523
5558
  commentCountOverride
5524
5559
  });
5525
- const header = /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PreviewPanelHeader, { isOwner, onClose, onNavigateHome, onGoToChat });
5560
+ const header = /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(PreviewPanelHeader, { isOwner, onClose, onNavigateHome, onGoToChat });
5526
5561
  if (loading || !app) {
5527
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PreviewPage, { header, children: /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(import_react_native42.View, { style: { flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, children: [
5528
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native42.ActivityIndicator, {}),
5529
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(import_react_native42.View, { style: { height: 12 } }),
5530
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(Text, { variant: "bodyMuted", children: "Loading app\u2026" })
5562
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(PreviewPage, { header, children: /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(import_react_native43.View, { style: { flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, children: [
5563
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native43.ActivityIndicator, {}),
5564
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native43.View, { style: { height: 12 } }),
5565
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(Text, { variant: "bodyMuted", children: "Loading app\u2026" })
5531
5566
  ] }) });
5532
5567
  }
5533
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(PreviewPage, { header, children: [
5534
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
5568
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(PreviewPage, { header, children: [
5569
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5535
5570
  PreviewHeroSection,
5536
5571
  {
5537
5572
  appStatus: app.status,
@@ -5549,8 +5584,8 @@ function PreviewPanel({
5549
5584
  }
5550
5585
  }
5551
5586
  ),
5552
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(PreviewMetaSection, { app, isOwner, creator, downloadsCount: insights.downloads }),
5553
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
5587
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(PreviewMetaSection, { app, isOwner, creator, downloadsCount: insights.downloads }),
5588
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5554
5589
  PreviewCustomizeSection,
5555
5590
  {
5556
5591
  app,
@@ -5561,7 +5596,7 @@ function PreviewPanel({
5561
5596
  onStartDraw
5562
5597
  }
5563
5598
  ),
5564
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
5599
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5565
5600
  PreviewCollaborateSection,
5566
5601
  {
5567
5602
  canSubmitMergeRequest,
@@ -5582,23 +5617,23 @@ function PreviewPanel({
5582
5617
  }
5583
5618
 
5584
5619
  // src/studio/ui/ChatPanel.tsx
5585
- var React36 = __toESM(require("react"));
5586
- var import_react_native50 = require("react-native");
5620
+ var React38 = __toESM(require("react"));
5621
+ var import_react_native51 = require("react-native");
5587
5622
 
5588
5623
  // src/components/chat/ChatPage.tsx
5589
- var React34 = __toESM(require("react"));
5590
- var import_react_native46 = require("react-native");
5624
+ var React36 = __toESM(require("react"));
5625
+ var import_react_native47 = require("react-native");
5591
5626
  var import_react_native_safe_area_context4 = require("react-native-safe-area-context");
5592
5627
 
5593
5628
  // src/components/chat/ChatMessageList.tsx
5594
- var React33 = __toESM(require("react"));
5595
- var import_react_native45 = require("react-native");
5629
+ var React35 = __toESM(require("react"));
5630
+ var import_react_native46 = require("react-native");
5596
5631
  var import_bottom_sheet5 = require("@gorhom/bottom-sheet");
5597
5632
 
5598
5633
  // src/components/chat/ChatMessageBubble.tsx
5599
- var import_react_native43 = require("react-native");
5634
+ var import_react_native44 = require("react-native");
5600
5635
  var import_lucide_react_native10 = require("lucide-react-native");
5601
- var import_jsx_runtime44 = require("react/jsx-runtime");
5636
+ var import_jsx_runtime46 = require("react/jsx-runtime");
5602
5637
  function ChatMessageBubble({ message, renderContent, style }) {
5603
5638
  var _a, _b;
5604
5639
  const theme = useTheme();
@@ -5612,7 +5647,7 @@ function ChatMessageBubble({ message, renderContent, style }) {
5612
5647
  const bubbleVariant = isHuman ? "surface" : "surfaceRaised";
5613
5648
  const cornerStyle = isHuman ? { borderTopRightRadius: 0 } : { borderTopLeftRadius: 0 };
5614
5649
  const bodyColor = metaStatus === "success" ? theme.colors.success : metaStatus === "error" ? theme.colors.danger : void 0;
5615
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.View, { style: [align, style], children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
5650
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native44.View, { style: [align, style], children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5616
5651
  Surface,
5617
5652
  {
5618
5653
  variant: bubbleVariant,
@@ -5627,34 +5662,34 @@ function ChatMessageBubble({ message, renderContent, style }) {
5627
5662
  },
5628
5663
  cornerStyle
5629
5664
  ],
5630
- children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(import_react_native43.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
5631
- isMergeCompleted ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native10.CheckCheck, { size: 16, color: theme.colors.success, style: { marginRight: theme.spacing.sm } }) : null,
5632
- isMergeApproved ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_lucide_react_native10.GitMerge, { size: 16, color: theme.colors.text, style: { marginRight: theme.spacing.sm } }) : null,
5633
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(import_react_native43.View, { style: { flexShrink: 1, minWidth: 0 }, children: renderContent ? renderContent(message) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(MarkdownText, { markdown: message.content, variant: "chat", bodyColor }) })
5665
+ children: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_react_native44.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
5666
+ isMergeCompleted ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react_native10.CheckCheck, { size: 16, color: theme.colors.success, style: { marginRight: theme.spacing.sm } }) : null,
5667
+ isMergeApproved ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_lucide_react_native10.GitMerge, { size: 16, color: theme.colors.text, style: { marginRight: theme.spacing.sm } }) : null,
5668
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native44.View, { style: { flexShrink: 1, minWidth: 0 }, children: renderContent ? renderContent(message) : /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(MarkdownText, { markdown: message.content, variant: "chat", bodyColor }) })
5634
5669
  ] })
5635
5670
  }
5636
5671
  ) });
5637
5672
  }
5638
5673
 
5639
5674
  // src/components/chat/TypingIndicator.tsx
5640
- var React32 = __toESM(require("react"));
5641
- var import_react_native44 = require("react-native");
5642
- var import_jsx_runtime45 = require("react/jsx-runtime");
5675
+ var React34 = __toESM(require("react"));
5676
+ var import_react_native45 = require("react-native");
5677
+ var import_jsx_runtime47 = require("react/jsx-runtime");
5643
5678
  function TypingIndicator({ style }) {
5644
5679
  const theme = useTheme();
5645
5680
  const dotColor = theme.colors.textSubtle;
5646
- const anims = React32.useMemo(
5647
- () => [new import_react_native44.Animated.Value(0.3), new import_react_native44.Animated.Value(0.3), new import_react_native44.Animated.Value(0.3)],
5681
+ const anims = React34.useMemo(
5682
+ () => [new import_react_native45.Animated.Value(0.3), new import_react_native45.Animated.Value(0.3), new import_react_native45.Animated.Value(0.3)],
5648
5683
  []
5649
5684
  );
5650
- React32.useEffect(() => {
5685
+ React34.useEffect(() => {
5651
5686
  const loops = [];
5652
5687
  anims.forEach((a, idx) => {
5653
- const seq = import_react_native44.Animated.sequence([
5654
- import_react_native44.Animated.timing(a, { toValue: 1, duration: 420, useNativeDriver: true, delay: idx * 140 }),
5655
- import_react_native44.Animated.timing(a, { toValue: 0.3, duration: 420, useNativeDriver: true })
5688
+ const seq = import_react_native45.Animated.sequence([
5689
+ import_react_native45.Animated.timing(a, { toValue: 1, duration: 420, useNativeDriver: true, delay: idx * 140 }),
5690
+ import_react_native45.Animated.timing(a, { toValue: 0.3, duration: 420, useNativeDriver: true })
5656
5691
  ]);
5657
- const loop = import_react_native44.Animated.loop(seq);
5692
+ const loop = import_react_native45.Animated.loop(seq);
5658
5693
  loops.push(loop);
5659
5694
  loop.start();
5660
5695
  });
@@ -5662,8 +5697,8 @@ function TypingIndicator({ style }) {
5662
5697
  loops.forEach((l) => l.stop());
5663
5698
  };
5664
5699
  }, [anims]);
5665
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(import_react_native44.View, { style: [{ flexDirection: "row", alignItems: "center" }, style], children: anims.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
5666
- import_react_native44.Animated.View,
5700
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native45.View, { style: [{ flexDirection: "row", alignItems: "center" }, style], children: anims.map((a, i) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5701
+ import_react_native45.Animated.View,
5667
5702
  {
5668
5703
  style: {
5669
5704
  width: 8,
@@ -5672,7 +5707,7 @@ function TypingIndicator({ style }) {
5672
5707
  marginHorizontal: 3,
5673
5708
  backgroundColor: dotColor,
5674
5709
  opacity: a,
5675
- transform: [{ translateY: import_react_native44.Animated.multiply(import_react_native44.Animated.subtract(a, 0.3), 2) }]
5710
+ transform: [{ translateY: import_react_native45.Animated.multiply(import_react_native45.Animated.subtract(a, 0.3), 2) }]
5676
5711
  }
5677
5712
  },
5678
5713
  i
@@ -5680,8 +5715,8 @@ function TypingIndicator({ style }) {
5680
5715
  }
5681
5716
 
5682
5717
  // src/components/chat/ChatMessageList.tsx
5683
- var import_jsx_runtime46 = require("react/jsx-runtime");
5684
- var ChatMessageList = React33.forwardRef(
5718
+ var import_jsx_runtime48 = require("react/jsx-runtime");
5719
+ var ChatMessageList = React35.forwardRef(
5685
5720
  ({
5686
5721
  messages,
5687
5722
  showTypingIndicator = false,
@@ -5692,20 +5727,20 @@ var ChatMessageList = React33.forwardRef(
5692
5727
  nearBottomThreshold = 200
5693
5728
  }, ref) => {
5694
5729
  const theme = useTheme();
5695
- const listRef = React33.useRef(null);
5696
- const nearBottomRef = React33.useRef(true);
5697
- const initialScrollDoneRef = React33.useRef(false);
5698
- const lastMessageIdRef = React33.useRef(null);
5699
- const data = React33.useMemo(() => {
5730
+ const listRef = React35.useRef(null);
5731
+ const nearBottomRef = React35.useRef(true);
5732
+ const initialScrollDoneRef = React35.useRef(false);
5733
+ const lastMessageIdRef = React35.useRef(null);
5734
+ const data = React35.useMemo(() => {
5700
5735
  return [...messages].reverse();
5701
5736
  }, [messages]);
5702
- const scrollToBottom = React33.useCallback((options) => {
5737
+ const scrollToBottom = React35.useCallback((options) => {
5703
5738
  var _a;
5704
5739
  const animated = (options == null ? void 0 : options.animated) ?? true;
5705
5740
  (_a = listRef.current) == null ? void 0 : _a.scrollToOffset({ offset: 0, animated });
5706
5741
  }, []);
5707
- React33.useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);
5708
- const handleScroll = React33.useCallback(
5742
+ React35.useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);
5743
+ const handleScroll = React35.useCallback(
5709
5744
  (e) => {
5710
5745
  const { contentOffset, contentSize, layoutMeasurement } = e.nativeEvent;
5711
5746
  const distanceFromBottom = Math.max(contentOffset.y - Math.max(bottomInset, 0), 0);
@@ -5717,7 +5752,7 @@ var ChatMessageList = React33.forwardRef(
5717
5752
  },
5718
5753
  [bottomInset, nearBottomThreshold, onNearBottomChange]
5719
5754
  );
5720
- React33.useEffect(() => {
5755
+ React35.useEffect(() => {
5721
5756
  if (!initialScrollDoneRef.current) return;
5722
5757
  const lastId = messages.length > 0 ? messages[messages.length - 1].id : null;
5723
5758
  const prevLastId = lastMessageIdRef.current;
@@ -5727,14 +5762,14 @@ var ChatMessageList = React33.forwardRef(
5727
5762
  const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
5728
5763
  return () => cancelAnimationFrame(id);
5729
5764
  }, [messages, scrollToBottom]);
5730
- React33.useEffect(() => {
5765
+ React35.useEffect(() => {
5731
5766
  if (showTypingIndicator && nearBottomRef.current) {
5732
5767
  const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
5733
5768
  return () => cancelAnimationFrame(id);
5734
5769
  }
5735
5770
  return void 0;
5736
5771
  }, [showTypingIndicator, scrollToBottom]);
5737
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
5772
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5738
5773
  import_bottom_sheet5.BottomSheetFlatList,
5739
5774
  {
5740
5775
  ref: listRef,
@@ -5760,11 +5795,11 @@ var ChatMessageList = React33.forwardRef(
5760
5795
  },
5761
5796
  contentStyle
5762
5797
  ],
5763
- ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.View, { style: { height: theme.spacing.sm } }),
5764
- renderItem: ({ item }) => /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(ChatMessageBubble, { message: item, renderContent: renderMessageContent }),
5765
- ListHeaderComponent: /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(import_react_native45.View, { children: [
5766
- showTypingIndicator ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.View, { style: { marginTop: theme.spacing.sm, alignSelf: "flex-start", paddingHorizontal: theme.spacing.lg }, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(TypingIndicator, {}) }) : null,
5767
- bottomInset > 0 ? /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(import_react_native45.View, { style: { height: bottomInset } }) : null
5798
+ ItemSeparatorComponent: () => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native46.View, { style: { height: theme.spacing.sm } }),
5799
+ renderItem: ({ item }) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ChatMessageBubble, { message: item, renderContent: renderMessageContent }),
5800
+ ListHeaderComponent: /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(import_react_native46.View, { children: [
5801
+ showTypingIndicator ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native46.View, { style: { marginTop: theme.spacing.sm, alignSelf: "flex-start", paddingHorizontal: theme.spacing.lg }, children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(TypingIndicator, {}) }) : null,
5802
+ bottomInset > 0 ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_react_native46.View, { style: { height: bottomInset } }) : null
5768
5803
  ] })
5769
5804
  }
5770
5805
  );
@@ -5773,7 +5808,7 @@ var ChatMessageList = React33.forwardRef(
5773
5808
  ChatMessageList.displayName = "ChatMessageList";
5774
5809
 
5775
5810
  // src/components/chat/ChatPage.tsx
5776
- var import_jsx_runtime47 = require("react/jsx-runtime");
5811
+ var import_jsx_runtime49 = require("react/jsx-runtime");
5777
5812
  function ChatPage({
5778
5813
  header,
5779
5814
  messages,
@@ -5789,39 +5824,39 @@ function ChatPage({
5789
5824
  }) {
5790
5825
  const theme = useTheme();
5791
5826
  const insets = (0, import_react_native_safe_area_context4.useSafeAreaInsets)();
5792
- const [composerHeight, setComposerHeight] = React34.useState(0);
5793
- const [keyboardVisible, setKeyboardVisible] = React34.useState(false);
5794
- React34.useEffect(() => {
5795
- if (import_react_native46.Platform.OS !== "ios") return;
5796
- const show = import_react_native46.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
5797
- const hide = import_react_native46.Keyboard.addListener("keyboardWillHide", () => setKeyboardVisible(false));
5827
+ const [composerHeight, setComposerHeight] = React36.useState(0);
5828
+ const [keyboardVisible, setKeyboardVisible] = React36.useState(false);
5829
+ React36.useEffect(() => {
5830
+ if (import_react_native47.Platform.OS !== "ios") return;
5831
+ const show = import_react_native47.Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
5832
+ const hide = import_react_native47.Keyboard.addListener("keyboardWillHide", () => setKeyboardVisible(false));
5798
5833
  return () => {
5799
5834
  show.remove();
5800
5835
  hide.remove();
5801
5836
  };
5802
5837
  }, []);
5803
- const footerBottomPadding = import_react_native46.Platform.OS === "ios" ? keyboardVisible ? 0 : insets.bottom : insets.bottom + 10;
5838
+ const footerBottomPadding = import_react_native47.Platform.OS === "ios" ? keyboardVisible ? 0 : insets.bottom : insets.bottom + 10;
5804
5839
  const overlayBottom = composerHeight + footerBottomPadding + theme.spacing.lg;
5805
5840
  const bottomInset = composerHeight + footerBottomPadding + theme.spacing.xl;
5806
- const resolvedOverlay = React34.useMemo(() => {
5841
+ const resolvedOverlay = React36.useMemo(() => {
5807
5842
  var _a;
5808
5843
  if (!overlay) return null;
5809
- if (!React34.isValidElement(overlay)) return overlay;
5844
+ if (!React36.isValidElement(overlay)) return overlay;
5810
5845
  const prevStyle = (_a = overlay.props) == null ? void 0 : _a.style;
5811
- return React34.cloneElement(overlay, {
5846
+ return React36.cloneElement(overlay, {
5812
5847
  style: [prevStyle, { bottom: overlayBottom }]
5813
5848
  });
5814
5849
  }, [overlay, overlayBottom]);
5815
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native46.View, { style: [{ flex: 1 }, style], children: [
5816
- header ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native46.View, { children: header }) : null,
5817
- topBanner ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(import_react_native46.View, { style: { paddingHorizontal: theme.spacing.lg, paddingTop: theme.spacing.sm }, children: topBanner }) : null,
5818
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_react_native46.View, { style: { flex: 1 }, children: [
5819
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
5820
- import_react_native46.View,
5850
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native47.View, { style: [{ flex: 1 }, style], children: [
5851
+ header ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native47.View, { children: header }) : null,
5852
+ topBanner ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_react_native47.View, { style: { paddingHorizontal: theme.spacing.lg, paddingTop: theme.spacing.sm }, children: topBanner }) : null,
5853
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_react_native47.View, { style: { flex: 1 }, children: [
5854
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
5855
+ import_react_native47.View,
5821
5856
  {
5822
5857
  style: { flex: 1 },
5823
5858
  children: [
5824
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5859
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
5825
5860
  ChatMessageList,
5826
5861
  {
5827
5862
  ref: listRef,
@@ -5836,8 +5871,8 @@ function ChatPage({
5836
5871
  ]
5837
5872
  }
5838
5873
  ),
5839
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5840
- import_react_native46.View,
5874
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
5875
+ import_react_native47.View,
5841
5876
  {
5842
5877
  style: {
5843
5878
  position: "absolute",
@@ -5848,7 +5883,7 @@ function ChatPage({
5848
5883
  paddingTop: theme.spacing.sm,
5849
5884
  paddingBottom: footerBottomPadding
5850
5885
  },
5851
- children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
5886
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
5852
5887
  ChatComposer,
5853
5888
  {
5854
5889
  ...composer,
@@ -5863,15 +5898,15 @@ function ChatPage({
5863
5898
  }
5864
5899
 
5865
5900
  // src/components/chat/ScrollToBottomButton.tsx
5866
- var React35 = __toESM(require("react"));
5867
- var import_react_native47 = require("react-native");
5901
+ var React37 = __toESM(require("react"));
5902
+ var import_react_native48 = require("react-native");
5868
5903
  var import_react_native_reanimated2 = __toESM(require("react-native-reanimated"));
5869
- var import_jsx_runtime48 = require("react/jsx-runtime");
5904
+ var import_jsx_runtime50 = require("react/jsx-runtime");
5870
5905
  function ScrollToBottomButton({ visible, onPress, children, style }) {
5871
5906
  const theme = useTheme();
5872
5907
  const progress = (0, import_react_native_reanimated2.useSharedValue)(visible ? 1 : 0);
5873
- const [pressed, setPressed] = React35.useState(false);
5874
- React35.useEffect(() => {
5908
+ const [pressed, setPressed] = React37.useState(false);
5909
+ React37.useEffect(() => {
5875
5910
  progress.value = (0, import_react_native_reanimated2.withTiming)(visible ? 1 : 0, { duration: 200, easing: import_react_native_reanimated2.Easing.out(import_react_native_reanimated2.Easing.ease) });
5876
5911
  }, [progress, visible]);
5877
5912
  const animStyle = (0, import_react_native_reanimated2.useAnimatedStyle)(() => ({
@@ -5880,7 +5915,7 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
5880
5915
  }));
5881
5916
  const bg = theme.scheme === "dark" ? "rgba(39,39,42,0.9)" : "rgba(244,244,245,0.95)";
5882
5917
  const border = theme.scheme === "dark" ? withAlpha("#FFFFFF", 0.12) : withAlpha("#000000", 0.08);
5883
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5918
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
5884
5919
  import_react_native_reanimated2.default.View,
5885
5920
  {
5886
5921
  pointerEvents: visible ? "auto" : "none",
@@ -5894,8 +5929,8 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
5894
5929
  style,
5895
5930
  animStyle
5896
5931
  ],
5897
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5898
- import_react_native47.View,
5932
+ children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
5933
+ import_react_native48.View,
5899
5934
  {
5900
5935
  style: {
5901
5936
  width: 44,
@@ -5913,8 +5948,8 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
5913
5948
  elevation: 5,
5914
5949
  opacity: pressed ? 0.85 : 1
5915
5950
  },
5916
- children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
5917
- import_react_native47.Pressable,
5951
+ children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
5952
+ import_react_native48.Pressable,
5918
5953
  {
5919
5954
  onPress,
5920
5955
  onPressIn: () => setPressed(true),
@@ -5931,16 +5966,16 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
5931
5966
  }
5932
5967
 
5933
5968
  // src/components/chat/ChatHeader.tsx
5934
- var import_react_native48 = require("react-native");
5935
- var import_jsx_runtime49 = require("react/jsx-runtime");
5969
+ var import_react_native49 = require("react-native");
5970
+ var import_jsx_runtime51 = require("react/jsx-runtime");
5936
5971
  function ChatHeader({ left, right, center, style }) {
5937
- const flattenedStyle = import_react_native48.StyleSheet.flatten([
5972
+ const flattenedStyle = import_react_native49.StyleSheet.flatten([
5938
5973
  {
5939
5974
  paddingTop: 0
5940
5975
  },
5941
5976
  style
5942
5977
  ]);
5943
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
5978
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
5944
5979
  StudioSheetHeader,
5945
5980
  {
5946
5981
  left,
@@ -5952,13 +5987,13 @@ function ChatHeader({ left, right, center, style }) {
5952
5987
  }
5953
5988
 
5954
5989
  // src/components/chat/ForkNoticeBanner.tsx
5955
- var import_react_native49 = require("react-native");
5956
- var import_jsx_runtime50 = require("react/jsx-runtime");
5990
+ var import_react_native50 = require("react-native");
5991
+ var import_jsx_runtime52 = require("react/jsx-runtime");
5957
5992
  function ForkNoticeBanner({ isOwner = true, title, description, style }) {
5958
5993
  const theme = useTheme();
5959
5994
  const resolvedTitle = title ?? (isOwner ? "Remixed app" : "Remix app");
5960
5995
  const resolvedDescription = description ?? (isOwner ? "Any changes you make will be a remix of the original app. You can view the edited version in the Remix tab in your apps page." : "Once you make edits, this remixed version will appear on your Remixed apps page.");
5961
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
5996
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
5962
5997
  Card,
5963
5998
  {
5964
5999
  variant: "surfaceRaised",
@@ -5973,8 +6008,8 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
5973
6008
  },
5974
6009
  style
5975
6010
  ],
5976
- children: /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_react_native49.View, { style: { minWidth: 0 }, children: [
5977
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
6011
+ children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_react_native50.View, { style: { minWidth: 0 }, children: [
6012
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
5978
6013
  Text,
5979
6014
  {
5980
6015
  style: {
@@ -5988,7 +6023,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
5988
6023
  children: resolvedTitle
5989
6024
  }
5990
6025
  ),
5991
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
6026
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
5992
6027
  Text,
5993
6028
  {
5994
6029
  style: {
@@ -6006,7 +6041,7 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
6006
6041
  }
6007
6042
 
6008
6043
  // src/studio/ui/ChatPanel.tsx
6009
- var import_jsx_runtime51 = require("react/jsx-runtime");
6044
+ var import_jsx_runtime53 = require("react/jsx-runtime");
6010
6045
  function ChatPanel({
6011
6046
  title = "Chat",
6012
6047
  autoFocusComposer = false,
@@ -6026,9 +6061,9 @@ function ChatPanel({
6026
6061
  onStartDraw,
6027
6062
  onSend
6028
6063
  }) {
6029
- const listRef = React36.useRef(null);
6030
- const [nearBottom, setNearBottom] = React36.useState(true);
6031
- const handleSend = React36.useCallback(
6064
+ const listRef = React38.useRef(null);
6065
+ const [nearBottom, setNearBottom] = React38.useState(true);
6066
+ const handleSend = React38.useCallback(
6032
6067
  async (text, composerAttachments) => {
6033
6068
  const all = composerAttachments ?? attachments;
6034
6069
  await onSend(text, all.length > 0 ? all : void 0);
@@ -6042,25 +6077,25 @@ function ChatPanel({
6042
6077
  },
6043
6078
  [attachments, nearBottom, onClearAttachments, onSend]
6044
6079
  );
6045
- const handleScrollToBottom = React36.useCallback(() => {
6080
+ const handleScrollToBottom = React38.useCallback(() => {
6046
6081
  var _a;
6047
6082
  (_a = listRef.current) == null ? void 0 : _a.scrollToBottom({ animated: true });
6048
6083
  }, []);
6049
- const header = /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6084
+ const header = /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6050
6085
  ChatHeader,
6051
6086
  {
6052
- left: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
6053
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onBack, accessibilityLabel: "Back", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconBack, { size: 20, colorToken: "floatingContent" }) }),
6054
- onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconHome, { size: 20, colorToken: "floatingContent" }) }) : null
6087
+ left: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native51.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
6088
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(StudioSheetHeaderIconButton, { onPress: onBack, accessibilityLabel: "Back", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconBack, { size: 20, colorToken: "floatingContent" }) }),
6089
+ onNavigateHome ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(StudioSheetHeaderIconButton, { onPress: onNavigateHome, accessibilityLabel: "Home", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconHome, { size: 20, colorToken: "floatingContent" }) }) : null
6055
6090
  ] }),
6056
- right: /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
6057
- onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onStartDraw, accessibilityLabel: "Draw", intent: "danger", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconDraw, { size: 20, colorToken: "onDanger" }) }) : null,
6058
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconClose, { size: 20, colorToken: "floatingContent" }) })
6091
+ right: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native51.View, { style: { flexDirection: "row", alignItems: "center" }, children: [
6092
+ onStartDraw ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(StudioSheetHeaderIconButton, { onPress: onStartDraw, accessibilityLabel: "Draw", intent: "danger", style: { marginRight: 8 }, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconDraw, { size: 20, colorToken: "onDanger" }) }) : null,
6093
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconClose, { size: 20, colorToken: "floatingContent" }) })
6059
6094
  ] }),
6060
6095
  center: null
6061
6096
  }
6062
6097
  );
6063
- const topBanner = shouldForkOnEdit ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6098
+ const topBanner = shouldForkOnEdit ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6064
6099
  ForkNoticeBanner,
6065
6100
  {
6066
6101
  isOwner: !shouldForkOnEdit,
@@ -6069,17 +6104,17 @@ function ChatPanel({
6069
6104
  ) : null;
6070
6105
  const showMessagesLoading = Boolean(loading) && messages.length === 0 || forking;
6071
6106
  if (showMessagesLoading) {
6072
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { style: { flex: 1 }, children: [
6073
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { children: header }),
6074
- topBanner ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { style: { paddingHorizontal: 16, paddingTop: 8 }, children: topBanner }) : null,
6075
- /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)(import_react_native50.View, { style: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 24, paddingVertical: 12 }, children: [
6076
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.ActivityIndicator, {}),
6077
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(import_react_native50.View, { style: { height: 12 } }),
6078
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(Text, { variant: "bodyMuted", children: forking ? "Creating your copy\u2026" : "Loading messages\u2026" })
6107
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native51.View, { style: { flex: 1 }, children: [
6108
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { children: header }),
6109
+ topBanner ? /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { style: { paddingHorizontal: 16, paddingTop: 8 }, children: topBanner }) : null,
6110
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native51.View, { style: { flex: 1, alignItems: "center", justifyContent: "center", paddingHorizontal: 24, paddingVertical: 12 }, children: [
6111
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.ActivityIndicator, {}),
6112
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native51.View, { style: { height: 12 } }),
6113
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Text, { variant: "bodyMuted", children: forking ? "Creating your copy\u2026" : "Loading messages\u2026" })
6079
6114
  ] })
6080
6115
  ] });
6081
6116
  }
6082
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6117
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6083
6118
  ChatPage,
6084
6119
  {
6085
6120
  header,
@@ -6089,13 +6124,13 @@ function ChatPanel({
6089
6124
  composerHorizontalPadding: 0,
6090
6125
  listRef,
6091
6126
  onNearBottomChange: setNearBottom,
6092
- overlay: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
6127
+ overlay: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6093
6128
  ScrollToBottomButton,
6094
6129
  {
6095
6130
  visible: !nearBottom,
6096
6131
  onPress: handleScrollToBottom,
6097
6132
  style: { bottom: 80 },
6098
- children: /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(IconArrowDown, { size: 20, colorToken: "floatingContent" })
6133
+ children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(IconArrowDown, { size: 20, colorToken: "floatingContent" })
6099
6134
  }
6100
6135
  ),
6101
6136
  composer: {
@@ -6116,12 +6151,12 @@ function ChatPanel({
6116
6151
  }
6117
6152
 
6118
6153
  // src/components/dialogs/ConfirmMergeRequestDialog.tsx
6119
- var React37 = __toESM(require("react"));
6120
- var import_react_native52 = require("react-native");
6154
+ var React39 = __toESM(require("react"));
6155
+ var import_react_native53 = require("react-native");
6121
6156
 
6122
6157
  // src/components/primitives/Modal.tsx
6123
- var import_react_native51 = require("react-native");
6124
- var import_jsx_runtime52 = require("react/jsx-runtime");
6158
+ var import_react_native52 = require("react-native");
6159
+ var import_jsx_runtime54 = require("react/jsx-runtime");
6125
6160
  function Modal({
6126
6161
  visible,
6127
6162
  onRequestClose,
@@ -6130,30 +6165,30 @@ function Modal({
6130
6165
  contentStyle
6131
6166
  }) {
6132
6167
  const theme = useTheme();
6133
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
6134
- import_react_native51.Modal,
6168
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
6169
+ import_react_native52.Modal,
6135
6170
  {
6136
6171
  visible,
6137
6172
  transparent: true,
6138
6173
  animationType: "fade",
6139
6174
  onRequestClose,
6140
- children: /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)(import_react_native51.View, { style: { flex: 1, backgroundColor: theme.colors.backdrop, justifyContent: "center", padding: theme.spacing.lg }, children: [
6141
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
6142
- import_react_native51.Pressable,
6175
+ children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_react_native52.View, { style: { flex: 1, backgroundColor: theme.colors.backdrop, justifyContent: "center", padding: theme.spacing.lg }, children: [
6176
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
6177
+ import_react_native52.Pressable,
6143
6178
  {
6144
6179
  accessibilityRole: "button",
6145
6180
  onPress: dismissOnBackdropPress ? onRequestClose : void 0,
6146
6181
  style: { position: "absolute", inset: 0 }
6147
6182
  }
6148
6183
  ),
6149
- /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(Card, { variant: "surfaceRaised", padded: true, style: [{ borderRadius: theme.radii.xl }, contentStyle], children })
6184
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(Card, { variant: "surfaceRaised", padded: true, style: [{ borderRadius: theme.radii.xl }, contentStyle], children })
6150
6185
  ] })
6151
6186
  }
6152
6187
  );
6153
6188
  }
6154
6189
 
6155
6190
  // src/components/dialogs/ConfirmMergeRequestDialog.tsx
6156
- var import_jsx_runtime53 = require("react/jsx-runtime");
6191
+ var import_jsx_runtime55 = require("react/jsx-runtime");
6157
6192
  function ConfirmMergeRequestDialog({
6158
6193
  visible,
6159
6194
  onOpenChange,
@@ -6164,14 +6199,14 @@ function ConfirmMergeRequestDialog({
6164
6199
  onTestFirst
6165
6200
  }) {
6166
6201
  const theme = useTheme();
6167
- const close = React37.useCallback(() => onOpenChange(false), [onOpenChange]);
6202
+ const close = React39.useCallback(() => onOpenChange(false), [onOpenChange]);
6168
6203
  const canConfirm = Boolean(mergeRequest) && !approveDisabled;
6169
- const handleConfirm = React37.useCallback(() => {
6204
+ const handleConfirm = React39.useCallback(() => {
6170
6205
  if (!mergeRequest) return;
6171
6206
  onOpenChange(false);
6172
6207
  void onConfirm();
6173
6208
  }, [mergeRequest, onConfirm, onOpenChange]);
6174
- const handleTestFirst = React37.useCallback(() => {
6209
+ const handleTestFirst = React39.useCallback(() => {
6175
6210
  if (!mergeRequest) return;
6176
6211
  onOpenChange(false);
6177
6212
  void onTestFirst(mergeRequest);
@@ -6183,7 +6218,7 @@ function ConfirmMergeRequestDialog({
6183
6218
  justifyContent: "center",
6184
6219
  alignSelf: "stretch"
6185
6220
  };
6186
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
6221
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
6187
6222
  Modal,
6188
6223
  {
6189
6224
  visible,
@@ -6194,7 +6229,7 @@ function ConfirmMergeRequestDialog({
6194
6229
  backgroundColor: theme.colors.background
6195
6230
  },
6196
6231
  children: [
6197
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native52.View, { children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6232
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native53.View, { children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6198
6233
  Text,
6199
6234
  {
6200
6235
  style: {
@@ -6206,9 +6241,9 @@ function ConfirmMergeRequestDialog({
6206
6241
  children: "Are you sure you want to approve this merge request?"
6207
6242
  }
6208
6243
  ) }),
6209
- /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(import_react_native52.View, { style: { marginTop: 16 }, children: [
6210
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6211
- import_react_native52.View,
6244
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_react_native53.View, { style: { marginTop: 16 }, children: [
6245
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6246
+ import_react_native53.View,
6212
6247
  {
6213
6248
  style: [
6214
6249
  fullWidthButtonBase,
@@ -6217,22 +6252,22 @@ function ConfirmMergeRequestDialog({
6217
6252
  opacity: canConfirm ? 1 : 0.5
6218
6253
  }
6219
6254
  ],
6220
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6221
- import_react_native52.Pressable,
6255
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6256
+ import_react_native53.Pressable,
6222
6257
  {
6223
6258
  accessibilityRole: "button",
6224
6259
  accessibilityLabel: "Approve Merge",
6225
6260
  disabled: !canConfirm,
6226
6261
  onPress: handleConfirm,
6227
6262
  style: [fullWidthButtonBase, { flex: 1 }],
6228
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Text, { style: { textAlign: "center", color: theme.colors.onPrimary }, children: "Approve Merge" })
6263
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Text, { style: { textAlign: "center", color: theme.colors.onPrimary }, children: "Approve Merge" })
6229
6264
  }
6230
6265
  )
6231
6266
  }
6232
6267
  ),
6233
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native52.View, { style: { height: 8 } }),
6234
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6235
- import_react_native52.View,
6268
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native53.View, { style: { height: 8 } }),
6269
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6270
+ import_react_native53.View,
6236
6271
  {
6237
6272
  style: [
6238
6273
  fullWidthButtonBase,
@@ -6243,22 +6278,22 @@ function ConfirmMergeRequestDialog({
6243
6278
  opacity: isBuilding || !mergeRequest ? 0.5 : 1
6244
6279
  }
6245
6280
  ],
6246
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6247
- import_react_native52.Pressable,
6281
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6282
+ import_react_native53.Pressable,
6248
6283
  {
6249
6284
  accessibilityRole: "button",
6250
6285
  accessibilityLabel: isBuilding ? "Preparing\u2026" : "Test edits first",
6251
6286
  disabled: isBuilding || !mergeRequest,
6252
6287
  onPress: handleTestFirst,
6253
6288
  style: [fullWidthButtonBase, { flex: 1 }],
6254
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Text, { style: { textAlign: "center", color: theme.colors.text }, children: isBuilding ? "Preparing\u2026" : "Test edits first" })
6289
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Text, { style: { textAlign: "center", color: theme.colors.text }, children: isBuilding ? "Preparing\u2026" : "Test edits first" })
6255
6290
  }
6256
6291
  )
6257
6292
  }
6258
6293
  ),
6259
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(import_react_native52.View, { style: { height: 8 } }),
6260
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6261
- import_react_native52.View,
6294
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native53.View, { style: { height: 8 } }),
6295
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6296
+ import_react_native53.View,
6262
6297
  {
6263
6298
  style: [
6264
6299
  fullWidthButtonBase,
@@ -6268,14 +6303,14 @@ function ConfirmMergeRequestDialog({
6268
6303
  borderColor: theme.colors.border
6269
6304
  }
6270
6305
  ],
6271
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
6272
- import_react_native52.Pressable,
6306
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6307
+ import_react_native53.Pressable,
6273
6308
  {
6274
6309
  accessibilityRole: "button",
6275
6310
  accessibilityLabel: "Cancel",
6276
6311
  onPress: close,
6277
6312
  style: [fullWidthButtonBase, { flex: 1 }],
6278
- children: /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(Text, { style: { textAlign: "center", color: theme.colors.text }, children: "Cancel" })
6313
+ children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(Text, { style: { textAlign: "center", color: theme.colors.text }, children: "Cancel" })
6279
6314
  }
6280
6315
  )
6281
6316
  }
@@ -6287,7 +6322,7 @@ function ConfirmMergeRequestDialog({
6287
6322
  }
6288
6323
 
6289
6324
  // src/studio/ui/ConfirmMergeFlow.tsx
6290
- var import_jsx_runtime54 = require("react/jsx-runtime");
6325
+ var import_jsx_runtime56 = require("react/jsx-runtime");
6291
6326
  function ConfirmMergeFlow({
6292
6327
  visible,
6293
6328
  onOpenChange,
@@ -6298,7 +6333,7 @@ function ConfirmMergeFlow({
6298
6333
  onConfirm,
6299
6334
  onTestFirst
6300
6335
  }) {
6301
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
6336
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
6302
6337
  ConfirmMergeRequestDialog,
6303
6338
  {
6304
6339
  visible,
@@ -6320,7 +6355,7 @@ function ConfirmMergeFlow({
6320
6355
  }
6321
6356
 
6322
6357
  // src/studio/hooks/useOptimisticChatMessages.ts
6323
- var React38 = __toESM(require("react"));
6358
+ var React40 = __toESM(require("react"));
6324
6359
  function makeOptimisticId() {
6325
6360
  return `optimistic:${Date.now().toString(36)}:${Math.random().toString(36).slice(2, 10)}`;
6326
6361
  }
@@ -6358,11 +6393,11 @@ function useOptimisticChatMessages({
6358
6393
  chatMessages,
6359
6394
  onSendChat
6360
6395
  }) {
6361
- const [optimisticChat, setOptimisticChat] = React38.useState([]);
6362
- React38.useEffect(() => {
6396
+ const [optimisticChat, setOptimisticChat] = React40.useState([]);
6397
+ React40.useEffect(() => {
6363
6398
  setOptimisticChat([]);
6364
6399
  }, [threadId]);
6365
- const messages = React38.useMemo(() => {
6400
+ const messages = React40.useMemo(() => {
6366
6401
  if (!optimisticChat || optimisticChat.length === 0) return chatMessages;
6367
6402
  const unresolved = optimisticChat.filter((o) => !isOptimisticResolvedByServer(chatMessages, o));
6368
6403
  if (unresolved.length === 0) return chatMessages;
@@ -6378,7 +6413,7 @@ function useOptimisticChatMessages({
6378
6413
  merged.sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt)));
6379
6414
  return merged;
6380
6415
  }, [chatMessages, optimisticChat]);
6381
- React38.useEffect(() => {
6416
+ React40.useEffect(() => {
6382
6417
  if (optimisticChat.length === 0) return;
6383
6418
  setOptimisticChat((prev) => {
6384
6419
  if (prev.length === 0) return prev;
@@ -6386,7 +6421,7 @@ function useOptimisticChatMessages({
6386
6421
  return next.length === prev.length ? prev : next;
6387
6422
  });
6388
6423
  }, [chatMessages, optimisticChat.length]);
6389
- const onSend = React38.useCallback(
6424
+ const onSend = React40.useCallback(
6390
6425
  async (text, attachments) => {
6391
6426
  if (shouldForkOnEdit) {
6392
6427
  await onSendChat(text, attachments);
@@ -6406,7 +6441,7 @@ function useOptimisticChatMessages({
6406
6441
  }
6407
6442
 
6408
6443
  // src/studio/ui/StudioOverlay.tsx
6409
- var import_jsx_runtime55 = require("react/jsx-runtime");
6444
+ var import_jsx_runtime57 = require("react/jsx-runtime");
6410
6445
  function StudioOverlay({
6411
6446
  captureTargetRef,
6412
6447
  app,
@@ -6436,13 +6471,13 @@ function StudioOverlay({
6436
6471
  onNavigateHome
6437
6472
  }) {
6438
6473
  const theme = useTheme();
6439
- const { width } = (0, import_react_native53.useWindowDimensions)();
6440
- const [sheetOpen, setSheetOpen] = React39.useState(false);
6441
- const [activePage, setActivePage] = React39.useState("preview");
6442
- const [drawing, setDrawing] = React39.useState(false);
6443
- const [chatAttachments, setChatAttachments] = React39.useState([]);
6444
- const [commentsAppId, setCommentsAppId] = React39.useState(null);
6445
- const [commentsCount, setCommentsCount] = React39.useState(null);
6474
+ const { width } = (0, import_react_native54.useWindowDimensions)();
6475
+ const [sheetOpen, setSheetOpen] = React41.useState(false);
6476
+ const [activePage, setActivePage] = React41.useState("preview");
6477
+ const [drawing, setDrawing] = React41.useState(false);
6478
+ const [chatAttachments, setChatAttachments] = React41.useState([]);
6479
+ const [commentsAppId, setCommentsAppId] = React41.useState(null);
6480
+ const [commentsCount, setCommentsCount] = React41.useState(null);
6446
6481
  const threadId = (app == null ? void 0 : app.threadId) ?? null;
6447
6482
  const optimistic = useOptimisticChatMessages({
6448
6483
  threadId,
@@ -6450,26 +6485,26 @@ function StudioOverlay({
6450
6485
  chatMessages,
6451
6486
  onSendChat
6452
6487
  });
6453
- const [confirmMrId, setConfirmMrId] = React39.useState(null);
6454
- const confirmMr = React39.useMemo(
6488
+ const [confirmMrId, setConfirmMrId] = React41.useState(null);
6489
+ const confirmMr = React41.useMemo(
6455
6490
  () => confirmMrId ? incomingMergeRequests.find((m) => m.id === confirmMrId) ?? null : null,
6456
6491
  [confirmMrId, incomingMergeRequests]
6457
6492
  );
6458
- const handleSheetOpenChange = React39.useCallback((open) => {
6493
+ const handleSheetOpenChange = React41.useCallback((open) => {
6459
6494
  setSheetOpen(open);
6460
- if (!open) import_react_native53.Keyboard.dismiss();
6495
+ if (!open) import_react_native54.Keyboard.dismiss();
6461
6496
  }, []);
6462
- const closeSheet = React39.useCallback(() => {
6497
+ const closeSheet = React41.useCallback(() => {
6463
6498
  handleSheetOpenChange(false);
6464
6499
  }, [handleSheetOpenChange]);
6465
- const openSheet = React39.useCallback(() => setSheetOpen(true), []);
6466
- const goToChat = React39.useCallback(() => {
6500
+ const openSheet = React41.useCallback(() => setSheetOpen(true), []);
6501
+ const goToChat = React41.useCallback(() => {
6467
6502
  setActivePage("chat");
6468
6503
  openSheet();
6469
6504
  }, [openSheet]);
6470
- const backToPreview = React39.useCallback(() => {
6471
- if (import_react_native53.Platform.OS !== "ios") {
6472
- import_react_native53.Keyboard.dismiss();
6505
+ const backToPreview = React41.useCallback(() => {
6506
+ if (import_react_native54.Platform.OS !== "ios") {
6507
+ import_react_native54.Keyboard.dismiss();
6473
6508
  setActivePage("preview");
6474
6509
  return;
6475
6510
  }
@@ -6481,15 +6516,15 @@ function StudioOverlay({
6481
6516
  clearTimeout(t);
6482
6517
  setActivePage("preview");
6483
6518
  };
6484
- const sub = import_react_native53.Keyboard.addListener("keyboardDidHide", finalize);
6519
+ const sub = import_react_native54.Keyboard.addListener("keyboardDidHide", finalize);
6485
6520
  const t = setTimeout(finalize, 350);
6486
- import_react_native53.Keyboard.dismiss();
6521
+ import_react_native54.Keyboard.dismiss();
6487
6522
  }, []);
6488
- const startDraw = React39.useCallback(() => {
6523
+ const startDraw = React41.useCallback(() => {
6489
6524
  setDrawing(true);
6490
6525
  closeSheet();
6491
6526
  }, [closeSheet]);
6492
- const handleDrawCapture = React39.useCallback(
6527
+ const handleDrawCapture = React41.useCallback(
6493
6528
  (dataUrl) => {
6494
6529
  setChatAttachments((prev) => [...prev, dataUrl]);
6495
6530
  setDrawing(false);
@@ -6498,7 +6533,7 @@ function StudioOverlay({
6498
6533
  },
6499
6534
  [openSheet]
6500
6535
  );
6501
- const toggleSheet = React39.useCallback(async () => {
6536
+ const toggleSheet = React41.useCallback(async () => {
6502
6537
  if (!sheetOpen) {
6503
6538
  const shouldExitTest = Boolean(testingMrId) || isTesting;
6504
6539
  if (shouldExitTest) {
@@ -6510,7 +6545,7 @@ function StudioOverlay({
6510
6545
  closeSheet();
6511
6546
  }
6512
6547
  }, [closeSheet, isTesting, onRestoreBase, sheetOpen, testingMrId]);
6513
- const handleTestMr = React39.useCallback(
6548
+ const handleTestMr = React41.useCallback(
6514
6549
  async (mr) => {
6515
6550
  if (!onTestMr) return;
6516
6551
  await onTestMr(mr);
@@ -6518,14 +6553,14 @@ function StudioOverlay({
6518
6553
  },
6519
6554
  [closeSheet, onTestMr]
6520
6555
  );
6521
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(import_jsx_runtime55.Fragment, { children: [
6522
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(EdgeGlowFrame, { visible: isTesting, role: "accent", thickness: 40, intensity: 1 }),
6523
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(StudioBottomSheet, { open: sheetOpen, onOpenChange: handleSheetOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6556
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(import_jsx_runtime57.Fragment, { children: [
6557
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(EdgeGlowFrame, { visible: isTesting, role: "accent", thickness: 40, intensity: 1 }),
6558
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(StudioBottomSheet, { open: sheetOpen, onOpenChange: handleSheetOpenChange, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
6524
6559
  StudioSheetPager,
6525
6560
  {
6526
6561
  activePage,
6527
6562
  width,
6528
- preview: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6563
+ preview: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
6529
6564
  PreviewPanel,
6530
6565
  {
6531
6566
  app,
@@ -6551,7 +6586,7 @@ function StudioOverlay({
6551
6586
  commentCountOverride: commentsCount ?? void 0
6552
6587
  }
6553
6588
  ),
6554
- chat: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6589
+ chat: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
6555
6590
  ChatPanel,
6556
6591
  {
6557
6592
  messages: optimistic.messages,
@@ -6574,7 +6609,7 @@ function StudioOverlay({
6574
6609
  )
6575
6610
  }
6576
6611
  ) }),
6577
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6612
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
6578
6613
  FloatingDraggableButton,
6579
6614
  {
6580
6615
  visible: !sheetOpen && !drawing,
@@ -6582,10 +6617,10 @@ function StudioOverlay({
6582
6617
  badgeCount: incomingMergeRequests.length,
6583
6618
  onPress: toggleSheet,
6584
6619
  isLoading: (app == null ? void 0 : app.status) === "editing",
6585
- children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(import_react_native53.View, { style: { width: 28, height: 28, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(MergeIcon, { width: 24, height: 24, color: theme.colors.floatingContent }) })
6620
+ children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(import_react_native54.View, { style: { width: 28, height: 28, alignItems: "center", justifyContent: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(MergeIcon, { width: 24, height: 24, color: theme.colors.floatingContent }) })
6586
6621
  }
6587
6622
  ),
6588
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6623
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
6589
6624
  DrawModeOverlay,
6590
6625
  {
6591
6626
  visible: drawing,
@@ -6594,7 +6629,7 @@ function StudioOverlay({
6594
6629
  onCapture: handleDrawCapture
6595
6630
  }
6596
6631
  ),
6597
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6632
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
6598
6633
  ConfirmMergeFlow,
6599
6634
  {
6600
6635
  visible: Boolean(confirmMr),
@@ -6607,7 +6642,7 @@ function StudioOverlay({
6607
6642
  onTestFirst: handleTestMr
6608
6643
  }
6609
6644
  ),
6610
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
6645
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
6611
6646
  AppCommentsSheet,
6612
6647
  {
6613
6648
  appId: commentsAppId,
@@ -6620,7 +6655,7 @@ function StudioOverlay({
6620
6655
  }
6621
6656
 
6622
6657
  // src/studio/ComergeStudio.tsx
6623
- var import_jsx_runtime56 = require("react/jsx-runtime");
6658
+ var import_jsx_runtime58 = require("react/jsx-runtime");
6624
6659
  function ComergeStudio({
6625
6660
  appId,
6626
6661
  apiKey,
@@ -6628,17 +6663,17 @@ function ComergeStudio({
6628
6663
  onNavigateHome,
6629
6664
  style
6630
6665
  }) {
6631
- const [activeAppId, setActiveAppId] = React40.useState(appId);
6632
- const [runtimeAppId, setRuntimeAppId] = React40.useState(appId);
6633
- const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] = React40.useState(null);
6634
- const platform = React40.useMemo(() => import_react_native54.Platform.OS === "ios" ? "ios" : "android", []);
6635
- React40.useEffect(() => {
6666
+ const [activeAppId, setActiveAppId] = React42.useState(appId);
6667
+ const [runtimeAppId, setRuntimeAppId] = React42.useState(appId);
6668
+ const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] = React42.useState(null);
6669
+ const platform = React42.useMemo(() => import_react_native55.Platform.OS === "ios" ? "ios" : "android", []);
6670
+ React42.useEffect(() => {
6636
6671
  setActiveAppId(appId);
6637
6672
  setRuntimeAppId(appId);
6638
6673
  setPendingRuntimeTargetAppId(null);
6639
6674
  }, [appId]);
6640
- const captureTargetRef = React40.useRef(null);
6641
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(StudioBootstrap, { apiKey, children: ({ userId }) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_bottom_sheet6.BottomSheetModalProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
6675
+ const captureTargetRef = React42.useRef(null);
6676
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(StudioBootstrap, { apiKey, children: ({ userId }) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_bottom_sheet6.BottomSheetModalProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(LiquidGlassResetProvider, { resetTriggers: [appId, activeAppId, runtimeAppId], children: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
6642
6677
  ComergeStudioInner,
6643
6678
  {
6644
6679
  userId,
@@ -6654,7 +6689,7 @@ function ComergeStudio({
6654
6689
  captureTargetRef,
6655
6690
  style
6656
6691
  }
6657
- ) }) });
6692
+ ) }) }) });
6658
6693
  }
6659
6694
  function ComergeStudioInner({
6660
6695
  userId,
@@ -6673,11 +6708,11 @@ function ComergeStudioInner({
6673
6708
  const { app, loading: appLoading } = useApp(activeAppId);
6674
6709
  const { app: runtimeAppFromHook } = useApp(runtimeAppId, { enabled: runtimeAppId !== activeAppId });
6675
6710
  const runtimeApp = runtimeAppId === activeAppId ? app : runtimeAppFromHook;
6676
- const sawEditingOnPendingTargetRef = React40.useRef(false);
6677
- React40.useEffect(() => {
6711
+ const sawEditingOnPendingTargetRef = React42.useRef(false);
6712
+ React42.useEffect(() => {
6678
6713
  sawEditingOnPendingTargetRef.current = false;
6679
6714
  }, [pendingRuntimeTargetAppId]);
6680
- React40.useEffect(() => {
6715
+ React42.useEffect(() => {
6681
6716
  if (!pendingRuntimeTargetAppId) return;
6682
6717
  if (activeAppId !== pendingRuntimeTargetAppId) return;
6683
6718
  if ((app == null ? void 0 : app.status) === "editing") {
@@ -6694,13 +6729,13 @@ function ComergeStudioInner({
6694
6729
  platform,
6695
6730
  canRequestLatest: (runtimeApp == null ? void 0 : runtimeApp.status) === "ready"
6696
6731
  });
6697
- const sawEditingOnActiveAppRef = React40.useRef(false);
6698
- const [showPostEditPreparing, setShowPostEditPreparing] = React40.useState(false);
6699
- React40.useEffect(() => {
6732
+ const sawEditingOnActiveAppRef = React42.useRef(false);
6733
+ const [showPostEditPreparing, setShowPostEditPreparing] = React42.useState(false);
6734
+ React42.useEffect(() => {
6700
6735
  sawEditingOnActiveAppRef.current = false;
6701
6736
  setShowPostEditPreparing(false);
6702
6737
  }, [activeAppId]);
6703
- React40.useEffect(() => {
6738
+ React42.useEffect(() => {
6704
6739
  if (!(app == null ? void 0 : app.id)) return;
6705
6740
  if (app.status === "editing") {
6706
6741
  sawEditingOnActiveAppRef.current = true;
@@ -6712,7 +6747,7 @@ function ComergeStudioInner({
6712
6747
  sawEditingOnActiveAppRef.current = false;
6713
6748
  }
6714
6749
  }, [app == null ? void 0 : app.id, app == null ? void 0 : app.status]);
6715
- React40.useEffect(() => {
6750
+ React42.useEffect(() => {
6716
6751
  if (!showPostEditPreparing) return;
6717
6752
  const stillProcessingBaseBundle = bundle.loading && bundle.loadingMode === "base" && !bundle.isTesting;
6718
6753
  if (!stillProcessingBaseBundle) {
@@ -6722,10 +6757,10 @@ function ComergeStudioInner({
6722
6757
  const threadId = (app == null ? void 0 : app.threadId) ?? "";
6723
6758
  const thread = useThreadMessages(threadId);
6724
6759
  const mergeRequests = useMergeRequests({ appId: activeAppId });
6725
- const hasOpenOutgoingMr = React40.useMemo(() => {
6760
+ const hasOpenOutgoingMr = React42.useMemo(() => {
6726
6761
  return mergeRequests.lists.outgoing.some((mr) => mr.status === "open");
6727
6762
  }, [mergeRequests.lists.outgoing]);
6728
- const incomingReviewMrs = React40.useMemo(() => {
6763
+ const incomingReviewMrs = React42.useMemo(() => {
6729
6764
  if (!userId) return mergeRequests.lists.incoming;
6730
6765
  return mergeRequests.lists.incoming.filter((mr) => mr.createdBy !== userId);
6731
6766
  }, [mergeRequests.lists.incoming, userId]);
@@ -6747,17 +6782,17 @@ function ComergeStudioInner({
6747
6782
  uploadAttachments: uploader.uploadBase64Images
6748
6783
  });
6749
6784
  const chatSendDisabled = hasNoOutcomeAfterLastHuman(thread.raw);
6750
- const [processingMrId, setProcessingMrId] = React40.useState(null);
6751
- const [testingMrId, setTestingMrId] = React40.useState(null);
6752
- const chatShowTypingIndicator = React40.useMemo(() => {
6785
+ const [processingMrId, setProcessingMrId] = React42.useState(null);
6786
+ const [testingMrId, setTestingMrId] = React42.useState(null);
6787
+ const chatShowTypingIndicator = React42.useMemo(() => {
6753
6788
  var _a;
6754
6789
  if (!thread.raw || thread.raw.length === 0) return false;
6755
6790
  const last = thread.raw[thread.raw.length - 1];
6756
6791
  const payloadType = typeof ((_a = last.payload) == null ? void 0 : _a.type) === "string" ? String(last.payload.type) : void 0;
6757
6792
  return payloadType !== "outcome";
6758
6793
  }, [thread.raw]);
6759
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(import_react_native54.View, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(import_react_native54.View, { ref: captureTargetRef, style: { flex: 1 }, collapsable: false, children: [
6760
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
6794
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(import_react_native55.View, { style: [{ flex: 1 }, style], children: /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_react_native55.View, { ref: captureTargetRef, style: { flex: 1 }, collapsable: false, children: [
6795
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
6761
6796
  RuntimeRenderer,
6762
6797
  {
6763
6798
  appKey,
@@ -6766,7 +6801,7 @@ function ComergeStudioInner({
6766
6801
  renderToken: bundle.renderToken
6767
6802
  }
6768
6803
  ),
6769
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
6804
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
6770
6805
  StudioOverlay,
6771
6806
  {
6772
6807
  captureTargetRef,