@comergehq/studio 0.1.5 → 0.1.6

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.mjs CHANGED
@@ -1637,11 +1637,11 @@ function RuntimeRenderer({ appKey, bundlePath, renderToken, style }) {
1637
1637
 
1638
1638
  // src/studio/ui/StudioOverlay.tsx
1639
1639
  import * as React37 from "react";
1640
- import { Keyboard as Keyboard3, View as View44, useWindowDimensions as useWindowDimensions4 } from "react-native";
1640
+ import { Keyboard as Keyboard5, Platform as Platform7, View as View44, useWindowDimensions as useWindowDimensions4 } from "react-native";
1641
1641
 
1642
1642
  // src/components/studio-sheet/StudioBottomSheet.tsx
1643
1643
  import * as React8 from "react";
1644
- import { View as View4 } from "react-native";
1644
+ import { Keyboard, Platform as Platform2, View as View4 } from "react-native";
1645
1645
  import BottomSheet from "@gorhom/bottom-sheet";
1646
1646
  import { useSafeAreaInsets } from "react-native-safe-area-context";
1647
1647
 
@@ -1710,6 +1710,16 @@ function StudioBottomSheet({
1710
1710
  const insets = useSafeAreaInsets();
1711
1711
  const internalSheetRef = React8.useRef(null);
1712
1712
  const resolvedSheetRef = sheetRef ?? internalSheetRef;
1713
+ React8.useEffect(() => {
1714
+ if (Platform2.OS !== "ios") return;
1715
+ const sub = Keyboard.addListener("keyboardDidHide", () => {
1716
+ const sheet = resolvedSheetRef.current;
1717
+ if (!sheet || !open) return;
1718
+ const targetIndex = snapPoints.length - 1;
1719
+ setTimeout(() => sheet.snapToIndex(targetIndex), 10);
1720
+ });
1721
+ return () => sub.remove();
1722
+ }, [open, resolvedSheetRef, snapPoints.length]);
1713
1723
  React8.useEffect(() => {
1714
1724
  const sheet = resolvedSheetRef.current;
1715
1725
  if (!sheet) return;
@@ -1732,12 +1742,12 @@ function StudioBottomSheet({
1732
1742
  index: open ? snapPoints.length - 1 : -1,
1733
1743
  snapPoints,
1734
1744
  enablePanDownToClose: true,
1735
- keyboardBehavior: "extend",
1745
+ keyboardBehavior: Platform2.OS === "ios" ? "interactive" : "extend",
1736
1746
  keyboardBlurBehavior: "restore",
1737
1747
  android_keyboardInputMode: "adjustResize",
1738
1748
  backgroundComponent: (props) => /* @__PURE__ */ jsx5(StudioSheetBackground, { ...props, renderBackground: background == null ? void 0 : background.renderBackground }),
1739
1749
  topInset: insets.top,
1740
- bottomInset: insets.bottom,
1750
+ bottomInset: 0,
1741
1751
  handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
1742
1752
  onChange: handleChange,
1743
1753
  ...bottomSheetProps,
@@ -2711,7 +2721,7 @@ var styles3 = StyleSheet3.create({
2711
2721
 
2712
2722
  // src/components/comments/AppCommentsSheet.tsx
2713
2723
  import * as React20 from "react";
2714
- import { ActivityIndicator as ActivityIndicator3, Keyboard as Keyboard2, Platform as Platform3, Pressable as Pressable5, View as View14 } from "react-native";
2724
+ import { ActivityIndicator as ActivityIndicator3, Keyboard as Keyboard3, Platform as Platform4, Pressable as Pressable5, View as View14 } from "react-native";
2715
2725
  import {
2716
2726
  BottomSheetBackdrop,
2717
2727
  BottomSheetModal,
@@ -3315,13 +3325,13 @@ function useAppDetails(appId) {
3315
3325
 
3316
3326
  // src/components/comments/useIosKeyboardSnapFix.ts
3317
3327
  import * as React19 from "react";
3318
- import { Keyboard, Platform as Platform2 } from "react-native";
3328
+ import { Keyboard as Keyboard2, Platform as Platform3 } from "react-native";
3319
3329
  function useIosKeyboardSnapFix(sheetRef) {
3320
3330
  const [keyboardVisible, setKeyboardVisible] = React19.useState(false);
3321
3331
  React19.useEffect(() => {
3322
- if (Platform2.OS !== "ios") return;
3323
- const show = Keyboard.addListener("keyboardWillShow", () => setKeyboardVisible(true));
3324
- const hide = Keyboard.addListener("keyboardWillHide", () => {
3332
+ if (Platform3.OS !== "ios") return;
3333
+ const show = Keyboard2.addListener("keyboardWillShow", () => setKeyboardVisible(true));
3334
+ const hide = Keyboard2.addListener("keyboardWillHide", () => {
3325
3335
  setKeyboardVisible(false);
3326
3336
  setTimeout(() => {
3327
3337
  var _a, _b;
@@ -3387,8 +3397,8 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3387
3397
  onChange: handleChange,
3388
3398
  backgroundStyle: {
3389
3399
  backgroundColor: theme.scheme === "dark" ? "#0B080F" : "#FFFFFF",
3390
- borderTopLeftRadius: Platform3.OS === "ios" ? 39 : 16,
3391
- borderTopRightRadius: Platform3.OS === "ios" ? 39 : 16
3400
+ borderTopLeftRadius: Platform4.OS === "ios" ? 39 : 16,
3401
+ borderTopRightRadius: Platform4.OS === "ios" ? 39 : 16
3392
3402
  },
3393
3403
  handleIndicatorStyle: { backgroundColor: theme.colors.handleIndicator },
3394
3404
  keyboardBehavior: "interactive",
@@ -3495,7 +3505,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3495
3505
  bottom: 0,
3496
3506
  paddingHorizontal: theme.spacing.lg,
3497
3507
  paddingTop: theme.spacing.sm,
3498
- paddingBottom: Platform3.OS === "ios" ? keyboardVisible ? theme.spacing.lg : insets.bottom : insets.bottom + 10,
3508
+ paddingBottom: Platform4.OS === "ios" ? keyboardVisible ? theme.spacing.lg : insets.bottom : insets.bottom + 10,
3499
3509
  borderTopWidth: 1,
3500
3510
  borderTopColor: withAlpha(theme.colors.border, 0.1),
3501
3511
  backgroundColor: withAlpha(theme.colors.background, 0.8)
@@ -3509,7 +3519,7 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
3509
3519
  useBottomSheetTextInput: true,
3510
3520
  onSend: async (text) => {
3511
3521
  await create(text);
3512
- Keyboard2.dismiss();
3522
+ Keyboard3.dismiss();
3513
3523
  }
3514
3524
  }
3515
3525
  )
@@ -4394,7 +4404,7 @@ import { Animated as Animated7, Pressable as Pressable9, View as View28 } from "
4394
4404
  import { Ban, Check as Check3, CheckCheck, ChevronDown as ChevronDown2 } from "lucide-react-native";
4395
4405
 
4396
4406
  // src/components/primitives/MarkdownText.tsx
4397
- import { Platform as Platform4, View as View27 } from "react-native";
4407
+ import { Platform as Platform5, View as View27 } from "react-native";
4398
4408
  import Markdown from "react-native-markdown-display";
4399
4409
  import { jsx as jsx37 } from "react/jsx-runtime";
4400
4410
  function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
@@ -4420,7 +4430,7 @@ function MarkdownText({ markdown, variant = "chat", bodyColor, style }) {
4420
4430
  paddingHorizontal: variant === "mergeRequest" ? 6 : 4,
4421
4431
  paddingVertical: variant === "mergeRequest" ? 2 : 0,
4422
4432
  borderRadius: variant === "mergeRequest" ? 6 : 4,
4423
- fontFamily: Platform4.OS === "ios" ? "Menlo" : "monospace",
4433
+ fontFamily: Platform5.OS === "ios" ? "Menlo" : "monospace",
4424
4434
  fontSize: 13
4425
4435
  },
4426
4436
  code_block: {
@@ -5433,7 +5443,9 @@ import { ActivityIndicator as ActivityIndicator8, View as View41 } from "react-n
5433
5443
 
5434
5444
  // src/components/chat/ChatPage.tsx
5435
5445
  import * as React33 from "react";
5436
- import { View as View37 } from "react-native";
5446
+ import { Keyboard as Keyboard4, Platform as Platform6, View as View37 } from "react-native";
5447
+ import { useSafeAreaInsets as useSafeAreaInsets4 } from "react-native-safe-area-context";
5448
+ import Animated11, { useAnimatedKeyboard, useAnimatedStyle as useAnimatedStyle2 } from "react-native-reanimated";
5437
5449
 
5438
5450
  // src/components/chat/ChatMessageList.tsx
5439
5451
  import * as React32 from "react";
@@ -5625,7 +5637,34 @@ function ChatPage({
5625
5637
  listRef
5626
5638
  }) {
5627
5639
  const theme = useTheme();
5640
+ const insets = useSafeAreaInsets4();
5628
5641
  const [composerHeight, setComposerHeight] = React33.useState(0);
5642
+ const [keyboardVisible, setKeyboardVisible] = React33.useState(false);
5643
+ const animatedKeyboard = useAnimatedKeyboard();
5644
+ React33.useEffect(() => {
5645
+ if (Platform6.OS !== "ios") return;
5646
+ const show = Keyboard4.addListener("keyboardWillShow", () => setKeyboardVisible(true));
5647
+ const hide = Keyboard4.addListener("keyboardWillHide", () => setKeyboardVisible(false));
5648
+ return () => {
5649
+ show.remove();
5650
+ hide.remove();
5651
+ };
5652
+ }, []);
5653
+ const footerBottomPadding = Platform6.OS === "ios" ? keyboardVisible ? 0 : insets.bottom : insets.bottom + 10;
5654
+ const footerAnimatedStyle = useAnimatedStyle2(() => {
5655
+ if (Platform6.OS !== "ios") return { paddingBottom: insets.bottom + 10 };
5656
+ return { paddingBottom: animatedKeyboard.height.value > 0 ? 0 : insets.bottom };
5657
+ });
5658
+ const overlayBottom = composerHeight + footerBottomPadding + theme.spacing.lg;
5659
+ const resolvedOverlay = React33.useMemo(() => {
5660
+ var _a;
5661
+ if (!overlay) return null;
5662
+ if (!React33.isValidElement(overlay)) return overlay;
5663
+ const prevStyle = (_a = overlay.props) == null ? void 0 : _a.style;
5664
+ return React33.cloneElement(overlay, {
5665
+ style: [prevStyle, { bottom: overlayBottom }]
5666
+ });
5667
+ }, [overlay, overlayBottom]);
5629
5668
  return /* @__PURE__ */ jsxs28(View37, { style: [{ flex: 1 }, style], children: [
5630
5669
  header ? /* @__PURE__ */ jsx47(View37, { children: header }) : null,
5631
5670
  topBanner ? /* @__PURE__ */ jsx47(View37, { style: { paddingHorizontal: theme.spacing.lg, paddingTop: theme.spacing.sm }, children: topBanner }) : null,
@@ -5638,26 +5677,42 @@ function ChatPage({
5638
5677
  showTypingIndicator,
5639
5678
  renderMessageContent,
5640
5679
  onNearBottomChange,
5641
- contentStyle: { paddingBottom: theme.spacing.xl + composerHeight }
5680
+ contentStyle: { paddingBottom: theme.spacing.xl + composerHeight + footerBottomPadding }
5642
5681
  }
5643
5682
  ),
5644
- overlay
5645
- ] }),
5646
- /* @__PURE__ */ jsx47(
5647
- ChatComposer,
5648
- {
5649
- ...composer,
5650
- attachments: composer.attachments ?? [],
5651
- onLayout: ({ height }) => setComposerHeight(height)
5652
- }
5653
- )
5683
+ resolvedOverlay,
5684
+ /* @__PURE__ */ jsx47(
5685
+ Animated11.View,
5686
+ {
5687
+ style: [
5688
+ {
5689
+ position: "absolute",
5690
+ left: 0,
5691
+ right: 0,
5692
+ bottom: 0,
5693
+ paddingHorizontal: theme.spacing.lg,
5694
+ paddingTop: theme.spacing.sm
5695
+ },
5696
+ footerAnimatedStyle
5697
+ ],
5698
+ children: /* @__PURE__ */ jsx47(
5699
+ ChatComposer,
5700
+ {
5701
+ ...composer,
5702
+ attachments: composer.attachments ?? [],
5703
+ onLayout: ({ height }) => setComposerHeight(height)
5704
+ }
5705
+ )
5706
+ }
5707
+ )
5708
+ ] })
5654
5709
  ] });
5655
5710
  }
5656
5711
 
5657
5712
  // src/components/chat/ScrollToBottomButton.tsx
5658
5713
  import * as React34 from "react";
5659
5714
  import { Pressable as Pressable12, View as View38 } from "react-native";
5660
- import Animated11, { Easing as Easing2, useAnimatedStyle as useAnimatedStyle2, useSharedValue as useSharedValue2, withTiming as withTiming2 } from "react-native-reanimated";
5715
+ import Animated12, { Easing as Easing2, useAnimatedStyle as useAnimatedStyle3, useSharedValue as useSharedValue2, withTiming as withTiming2 } from "react-native-reanimated";
5661
5716
  import { jsx as jsx48 } from "react/jsx-runtime";
5662
5717
  function ScrollToBottomButton({ visible, onPress, children, style }) {
5663
5718
  const theme = useTheme();
@@ -5666,14 +5721,14 @@ function ScrollToBottomButton({ visible, onPress, children, style }) {
5666
5721
  React34.useEffect(() => {
5667
5722
  progress.value = withTiming2(visible ? 1 : 0, { duration: 200, easing: Easing2.out(Easing2.ease) });
5668
5723
  }, [progress, visible]);
5669
- const animStyle = useAnimatedStyle2(() => ({
5724
+ const animStyle = useAnimatedStyle3(() => ({
5670
5725
  opacity: progress.value,
5671
5726
  transform: [{ translateY: (1 - progress.value) * 20 }]
5672
5727
  }));
5673
5728
  const bg = theme.scheme === "dark" ? "rgba(39,39,42,0.9)" : "rgba(244,244,245,0.95)";
5674
5729
  const border = theme.scheme === "dark" ? withAlpha("#FFFFFF", 0.12) : withAlpha("#000000", 0.08);
5675
5730
  return /* @__PURE__ */ jsx48(
5676
- Animated11.View,
5731
+ Animated12.View,
5677
5732
  {
5678
5733
  pointerEvents: visible ? "auto" : "none",
5679
5734
  style: [
@@ -6154,7 +6209,7 @@ function StudioOverlay({
6154
6209
  );
6155
6210
  const closeSheet = React37.useCallback(() => {
6156
6211
  setSheetOpen(false);
6157
- Keyboard3.dismiss();
6212
+ Keyboard5.dismiss();
6158
6213
  }, []);
6159
6214
  const openSheet = React37.useCallback(() => setSheetOpen(true), []);
6160
6215
  const goToChat = React37.useCallback(() => {
@@ -6162,8 +6217,22 @@ function StudioOverlay({
6162
6217
  openSheet();
6163
6218
  }, [openSheet]);
6164
6219
  const backToPreview = React37.useCallback(() => {
6165
- Keyboard3.dismiss();
6166
- setActivePage("preview");
6220
+ if (Platform7.OS !== "ios") {
6221
+ Keyboard5.dismiss();
6222
+ setActivePage("preview");
6223
+ return;
6224
+ }
6225
+ let done = false;
6226
+ const finalize = () => {
6227
+ if (done) return;
6228
+ done = true;
6229
+ sub.remove();
6230
+ clearTimeout(t);
6231
+ setActivePage("preview");
6232
+ };
6233
+ const sub = Keyboard5.addListener("keyboardDidHide", finalize);
6234
+ const t = setTimeout(finalize, 350);
6235
+ Keyboard5.dismiss();
6167
6236
  }, []);
6168
6237
  const startDraw = React37.useCallback(() => {
6169
6238
  setDrawing(true);