@comergehq/studio 0.1.16 → 0.1.18
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 +176 -120
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +184 -127
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/icons/StudioIcons.tsx +2 -0
- package/src/studio/hooks/useStudioActions.ts +1 -1
- package/src/studio/hooks/useThreadMessages.ts +7 -4
- package/src/studio/ui/PreviewPanel.tsx +35 -2
- package/src/studio/ui/StudioOverlay.tsx +4 -2
- package/src/studio/ui/preview-panel/PreviewPanelHeader.tsx +22 -2
package/dist/index.mjs
CHANGED
|
@@ -6,7 +6,7 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
|
|
|
6
6
|
});
|
|
7
7
|
|
|
8
8
|
// src/studio/ComergeStudio.tsx
|
|
9
|
-
import * as
|
|
9
|
+
import * as React47 from "react";
|
|
10
10
|
import { Platform as RNPlatform, View as View46 } from "react-native";
|
|
11
11
|
import { BottomSheetModalProvider } from "@gorhom/bottom-sheet";
|
|
12
12
|
|
|
@@ -864,9 +864,8 @@ function useThreadMessages(threadId) {
|
|
|
864
864
|
const activeRequestIdRef = React4.useRef(0);
|
|
865
865
|
const foregroundSignal = useForegroundSignal(Boolean(threadId));
|
|
866
866
|
const upsertSorted = React4.useCallback((prev, m) => {
|
|
867
|
-
const include = !isQueuedHiddenMessage(m);
|
|
868
867
|
const next = prev.filter((x) => x.id !== m.id);
|
|
869
|
-
|
|
868
|
+
next.push(m);
|
|
870
869
|
next.sort(compareMessages);
|
|
871
870
|
return next;
|
|
872
871
|
}, []);
|
|
@@ -881,7 +880,7 @@ function useThreadMessages(threadId) {
|
|
|
881
880
|
try {
|
|
882
881
|
const list = await messagesRepository.list(threadId);
|
|
883
882
|
if (activeRequestIdRef.current !== requestId) return;
|
|
884
|
-
setRaw([...list].
|
|
883
|
+
setRaw([...list].sort(compareMessages));
|
|
885
884
|
} catch (e) {
|
|
886
885
|
if (activeRequestIdRef.current !== requestId) return;
|
|
887
886
|
setError(e instanceof Error ? e : new Error(String(e)));
|
|
@@ -907,7 +906,11 @@ function useThreadMessages(threadId) {
|
|
|
907
906
|
if (foregroundSignal <= 0) return;
|
|
908
907
|
void refetch();
|
|
909
908
|
}, [foregroundSignal, refetch, threadId]);
|
|
910
|
-
const messages = React4.useMemo(() =>
|
|
909
|
+
const messages = React4.useMemo(() => {
|
|
910
|
+
const visible = raw.filter((m) => !isQueuedHiddenMessage(m));
|
|
911
|
+
const resolved = visible.length > 0 ? visible : raw;
|
|
912
|
+
return resolved.map(mapMessageToChatMessage);
|
|
913
|
+
}, [raw]);
|
|
911
914
|
return { raw, messages, loading, error, refetch };
|
|
912
915
|
}
|
|
913
916
|
|
|
@@ -1951,7 +1954,6 @@ function useStudioActions({
|
|
|
1951
1954
|
setSending(true);
|
|
1952
1955
|
setError(null);
|
|
1953
1956
|
try {
|
|
1954
|
-
onEditStart == null ? void 0 : onEditStart();
|
|
1955
1957
|
let targetApp = app;
|
|
1956
1958
|
if (shouldForkOnEdit) {
|
|
1957
1959
|
setForking(true);
|
|
@@ -1963,6 +1965,7 @@ function useStudioActions({
|
|
|
1963
1965
|
setForking(false);
|
|
1964
1966
|
const threadId = targetApp.threadId;
|
|
1965
1967
|
if (!threadId) throw new Error("No thread available for this app.");
|
|
1968
|
+
onEditStart == null ? void 0 : onEditStart();
|
|
1966
1969
|
let attachmentMetas;
|
|
1967
1970
|
if (attachments && attachments.length > 0 && uploadAttachments) {
|
|
1968
1971
|
attachmentMetas = await uploadAttachments({ threadId, appId: targetApp.id, dataUrls: attachments });
|
|
@@ -2029,8 +2032,8 @@ function RuntimeRenderer({
|
|
|
2029
2032
|
}
|
|
2030
2033
|
|
|
2031
2034
|
// src/studio/ui/StudioOverlay.tsx
|
|
2032
|
-
import * as
|
|
2033
|
-
import { Keyboard as Keyboard5, Platform as
|
|
2035
|
+
import * as React44 from "react";
|
|
2036
|
+
import { Keyboard as Keyboard5, Platform as Platform11, View as View45, useWindowDimensions as useWindowDimensions4 } from "react-native";
|
|
2034
2037
|
|
|
2035
2038
|
// src/components/studio-sheet/StudioBottomSheet.tsx
|
|
2036
2039
|
import * as React12 from "react";
|
|
@@ -3227,7 +3230,8 @@ import {
|
|
|
3227
3230
|
Play,
|
|
3228
3231
|
Send,
|
|
3229
3232
|
X as X2,
|
|
3230
|
-
Check as Check2
|
|
3233
|
+
Check as Check2,
|
|
3234
|
+
Share2
|
|
3231
3235
|
} from "lucide-react-native";
|
|
3232
3236
|
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
3233
3237
|
function useResolvedIconColor(token) {
|
|
@@ -3267,6 +3271,7 @@ var IconSend = makeIcon(Send);
|
|
|
3267
3271
|
var IconPlay = makeIcon(Play);
|
|
3268
3272
|
var IconArrowDown = makeIcon(ArrowDown);
|
|
3269
3273
|
var IconApprove = makeIcon(Check2);
|
|
3274
|
+
var IconShare = makeIcon(Share2);
|
|
3270
3275
|
|
|
3271
3276
|
// src/components/chat/ChatComposer.tsx
|
|
3272
3277
|
import { jsx as jsx17, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
@@ -3983,7 +3988,8 @@ function AppCommentsSheet({ appId, onClose, onCountChange, onPlayApp }) {
|
|
|
3983
3988
|
}
|
|
3984
3989
|
|
|
3985
3990
|
// src/studio/ui/PreviewPanel.tsx
|
|
3986
|
-
import
|
|
3991
|
+
import * as React35 from "react";
|
|
3992
|
+
import { ActivityIndicator as ActivityIndicator7, Platform as Platform8, Share, View as View33 } from "react-native";
|
|
3987
3993
|
|
|
3988
3994
|
// src/components/preview/PreviewPage.tsx
|
|
3989
3995
|
import { View as View15 } from "react-native";
|
|
@@ -4133,7 +4139,14 @@ function StudioSheetHeaderIconButton({
|
|
|
4133
4139
|
|
|
4134
4140
|
// src/studio/ui/preview-panel/PreviewPanelHeader.tsx
|
|
4135
4141
|
import { jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
4136
|
-
function PreviewPanelHeader({
|
|
4142
|
+
function PreviewPanelHeader({
|
|
4143
|
+
isOwner,
|
|
4144
|
+
isPublic,
|
|
4145
|
+
onClose,
|
|
4146
|
+
onNavigateHome,
|
|
4147
|
+
onGoToChat,
|
|
4148
|
+
onShare
|
|
4149
|
+
}) {
|
|
4137
4150
|
return /* @__PURE__ */ jsx24(
|
|
4138
4151
|
StudioSheetHeader,
|
|
4139
4152
|
{
|
|
@@ -4151,6 +4164,17 @@ function PreviewPanelHeader({ isOwner, onClose, onNavigateHome, onGoToChat }) {
|
|
|
4151
4164
|
children: /* @__PURE__ */ jsx24(IconChat, { size: 20, colorToken: "onPrimary" })
|
|
4152
4165
|
}
|
|
4153
4166
|
) : null,
|
|
4167
|
+
isPublic && onShare ? /* @__PURE__ */ jsx24(
|
|
4168
|
+
StudioSheetHeaderIconButton,
|
|
4169
|
+
{
|
|
4170
|
+
onPress: onShare,
|
|
4171
|
+
accessibilityLabel: "Share",
|
|
4172
|
+
intent: "primary",
|
|
4173
|
+
appearance: "glass",
|
|
4174
|
+
style: { marginRight: 8 },
|
|
4175
|
+
children: /* @__PURE__ */ jsx24(IconShare, { size: 20, colorToken: "onPrimary" })
|
|
4176
|
+
}
|
|
4177
|
+
) : null,
|
|
4154
4178
|
/* @__PURE__ */ jsx24(StudioSheetHeaderIconButton, { onPress: onClose, accessibilityLabel: "Close", appearance: "glass", intent: "primary", children: /* @__PURE__ */ jsx24(IconClose, { size: 20, colorToken: "onPrimary" }) })
|
|
4155
4179
|
] })
|
|
4156
4180
|
}
|
|
@@ -5823,6 +5847,27 @@ function PreviewPanel({
|
|
|
5823
5847
|
onOpenComments,
|
|
5824
5848
|
commentCountOverride
|
|
5825
5849
|
}) {
|
|
5850
|
+
const handleShare = React35.useCallback(async () => {
|
|
5851
|
+
if (!app || !app.isPublic) return;
|
|
5852
|
+
const shareUrl = `https://comerge.ai/app/${app.id}`;
|
|
5853
|
+
const message = app.name ? `${app.name} on Comerge
|
|
5854
|
+
${shareUrl}` : `Check out this app on Comerge
|
|
5855
|
+
${shareUrl}`;
|
|
5856
|
+
try {
|
|
5857
|
+
const title = app.name ?? "Comerge app";
|
|
5858
|
+
const payload = Platform8.OS === "ios" ? {
|
|
5859
|
+
title,
|
|
5860
|
+
message
|
|
5861
|
+
} : {
|
|
5862
|
+
title,
|
|
5863
|
+
message,
|
|
5864
|
+
url: shareUrl
|
|
5865
|
+
};
|
|
5866
|
+
await Share.share(payload);
|
|
5867
|
+
} catch (error) {
|
|
5868
|
+
log.warn("PreviewPanel share failed", error);
|
|
5869
|
+
}
|
|
5870
|
+
}, [app]);
|
|
5826
5871
|
const { imageUrl, imageLoaded, setImageLoaded, creator, insights, stats, showProcessing, canSubmitMergeRequest } = usePreviewPanelData({
|
|
5827
5872
|
app,
|
|
5828
5873
|
isOwner,
|
|
@@ -5830,7 +5875,17 @@ function PreviewPanel({
|
|
|
5830
5875
|
onOpenComments,
|
|
5831
5876
|
commentCountOverride
|
|
5832
5877
|
});
|
|
5833
|
-
const header = /* @__PURE__ */ jsx45(
|
|
5878
|
+
const header = /* @__PURE__ */ jsx45(
|
|
5879
|
+
PreviewPanelHeader,
|
|
5880
|
+
{
|
|
5881
|
+
isOwner,
|
|
5882
|
+
isPublic: Boolean(app == null ? void 0 : app.isPublic),
|
|
5883
|
+
onClose,
|
|
5884
|
+
onNavigateHome,
|
|
5885
|
+
onGoToChat,
|
|
5886
|
+
onShare: handleShare
|
|
5887
|
+
}
|
|
5888
|
+
);
|
|
5834
5889
|
if (loading || !app) {
|
|
5835
5890
|
return /* @__PURE__ */ jsx45(PreviewPage, { header, children: /* @__PURE__ */ jsxs26(View33, { style: { flex: 1, justifyContent: "center", alignItems: "center", padding: 24 }, children: [
|
|
5836
5891
|
/* @__PURE__ */ jsx45(ActivityIndicator7, {}),
|
|
@@ -5890,16 +5945,16 @@ function PreviewPanel({
|
|
|
5890
5945
|
}
|
|
5891
5946
|
|
|
5892
5947
|
// src/studio/ui/ChatPanel.tsx
|
|
5893
|
-
import * as
|
|
5948
|
+
import * as React41 from "react";
|
|
5894
5949
|
import { ActivityIndicator as ActivityIndicator9, View as View42 } from "react-native";
|
|
5895
5950
|
|
|
5896
5951
|
// src/components/chat/ChatPage.tsx
|
|
5897
|
-
import * as
|
|
5898
|
-
import { Keyboard as Keyboard4, Platform as
|
|
5952
|
+
import * as React38 from "react";
|
|
5953
|
+
import { Keyboard as Keyboard4, Platform as Platform10, View as View37 } from "react-native";
|
|
5899
5954
|
import { useSafeAreaInsets as useSafeAreaInsets4 } from "react-native-safe-area-context";
|
|
5900
5955
|
|
|
5901
5956
|
// src/components/chat/ChatMessageList.tsx
|
|
5902
|
-
import * as
|
|
5957
|
+
import * as React37 from "react";
|
|
5903
5958
|
import { View as View36 } from "react-native";
|
|
5904
5959
|
import { BottomSheetFlatList } from "@gorhom/bottom-sheet";
|
|
5905
5960
|
|
|
@@ -5945,17 +6000,17 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5945
6000
|
}
|
|
5946
6001
|
|
|
5947
6002
|
// src/components/chat/TypingIndicator.tsx
|
|
5948
|
-
import * as
|
|
6003
|
+
import * as React36 from "react";
|
|
5949
6004
|
import { Animated as Animated10, View as View35 } from "react-native";
|
|
5950
6005
|
import { jsx as jsx47 } from "react/jsx-runtime";
|
|
5951
6006
|
function TypingIndicator({ style }) {
|
|
5952
6007
|
const theme = useTheme();
|
|
5953
6008
|
const dotColor = theme.colors.textSubtle;
|
|
5954
|
-
const anims =
|
|
6009
|
+
const anims = React36.useMemo(
|
|
5955
6010
|
() => [new Animated10.Value(0.3), new Animated10.Value(0.3), new Animated10.Value(0.3)],
|
|
5956
6011
|
[]
|
|
5957
6012
|
);
|
|
5958
|
-
|
|
6013
|
+
React36.useEffect(() => {
|
|
5959
6014
|
const loops = [];
|
|
5960
6015
|
anims.forEach((a, idx) => {
|
|
5961
6016
|
const seq = Animated10.sequence([
|
|
@@ -5989,7 +6044,7 @@ function TypingIndicator({ style }) {
|
|
|
5989
6044
|
|
|
5990
6045
|
// src/components/chat/ChatMessageList.tsx
|
|
5991
6046
|
import { jsx as jsx48, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
5992
|
-
var ChatMessageList =
|
|
6047
|
+
var ChatMessageList = React37.forwardRef(
|
|
5993
6048
|
({
|
|
5994
6049
|
messages,
|
|
5995
6050
|
showTypingIndicator = false,
|
|
@@ -6000,20 +6055,20 @@ var ChatMessageList = React36.forwardRef(
|
|
|
6000
6055
|
nearBottomThreshold = 200
|
|
6001
6056
|
}, ref) => {
|
|
6002
6057
|
const theme = useTheme();
|
|
6003
|
-
const listRef =
|
|
6004
|
-
const nearBottomRef =
|
|
6005
|
-
const initialScrollDoneRef =
|
|
6006
|
-
const lastMessageIdRef =
|
|
6007
|
-
const data =
|
|
6058
|
+
const listRef = React37.useRef(null);
|
|
6059
|
+
const nearBottomRef = React37.useRef(true);
|
|
6060
|
+
const initialScrollDoneRef = React37.useRef(false);
|
|
6061
|
+
const lastMessageIdRef = React37.useRef(null);
|
|
6062
|
+
const data = React37.useMemo(() => {
|
|
6008
6063
|
return [...messages].reverse();
|
|
6009
6064
|
}, [messages]);
|
|
6010
|
-
const scrollToBottom =
|
|
6065
|
+
const scrollToBottom = React37.useCallback((options) => {
|
|
6011
6066
|
var _a;
|
|
6012
6067
|
const animated = (options == null ? void 0 : options.animated) ?? true;
|
|
6013
6068
|
(_a = listRef.current) == null ? void 0 : _a.scrollToOffset({ offset: 0, animated });
|
|
6014
6069
|
}, []);
|
|
6015
|
-
|
|
6016
|
-
const handleScroll =
|
|
6070
|
+
React37.useImperativeHandle(ref, () => ({ scrollToBottom }), [scrollToBottom]);
|
|
6071
|
+
const handleScroll = React37.useCallback(
|
|
6017
6072
|
(e) => {
|
|
6018
6073
|
const { contentOffset, contentSize, layoutMeasurement } = e.nativeEvent;
|
|
6019
6074
|
const distanceFromBottom = Math.max(contentOffset.y - Math.max(bottomInset, 0), 0);
|
|
@@ -6025,7 +6080,7 @@ var ChatMessageList = React36.forwardRef(
|
|
|
6025
6080
|
},
|
|
6026
6081
|
[bottomInset, nearBottomThreshold, onNearBottomChange]
|
|
6027
6082
|
);
|
|
6028
|
-
|
|
6083
|
+
React37.useEffect(() => {
|
|
6029
6084
|
if (!initialScrollDoneRef.current) return;
|
|
6030
6085
|
const lastId = messages.length > 0 ? messages[messages.length - 1].id : null;
|
|
6031
6086
|
const prevLastId = lastMessageIdRef.current;
|
|
@@ -6035,7 +6090,7 @@ var ChatMessageList = React36.forwardRef(
|
|
|
6035
6090
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
|
|
6036
6091
|
return () => cancelAnimationFrame(id);
|
|
6037
6092
|
}, [messages, scrollToBottom]);
|
|
6038
|
-
|
|
6093
|
+
React37.useEffect(() => {
|
|
6039
6094
|
if (showTypingIndicator && nearBottomRef.current) {
|
|
6040
6095
|
const id = requestAnimationFrame(() => scrollToBottom({ animated: true }));
|
|
6041
6096
|
return () => cancelAnimationFrame(id);
|
|
@@ -6098,11 +6153,11 @@ function ChatPage({
|
|
|
6098
6153
|
}) {
|
|
6099
6154
|
const theme = useTheme();
|
|
6100
6155
|
const insets = useSafeAreaInsets4();
|
|
6101
|
-
const [composerHeight, setComposerHeight] =
|
|
6102
|
-
const [composerTopHeight, setComposerTopHeight] =
|
|
6103
|
-
const [keyboardVisible, setKeyboardVisible] =
|
|
6104
|
-
|
|
6105
|
-
if (
|
|
6156
|
+
const [composerHeight, setComposerHeight] = React38.useState(0);
|
|
6157
|
+
const [composerTopHeight, setComposerTopHeight] = React38.useState(0);
|
|
6158
|
+
const [keyboardVisible, setKeyboardVisible] = React38.useState(false);
|
|
6159
|
+
React38.useEffect(() => {
|
|
6160
|
+
if (Platform10.OS !== "ios") return;
|
|
6106
6161
|
const show = Keyboard4.addListener("keyboardWillShow", () => setKeyboardVisible(true));
|
|
6107
6162
|
const hide = Keyboard4.addListener("keyboardWillHide", () => setKeyboardVisible(false));
|
|
6108
6163
|
return () => {
|
|
@@ -6110,20 +6165,20 @@ function ChatPage({
|
|
|
6110
6165
|
hide.remove();
|
|
6111
6166
|
};
|
|
6112
6167
|
}, []);
|
|
6113
|
-
const footerBottomPadding =
|
|
6168
|
+
const footerBottomPadding = Platform10.OS === "ios" ? keyboardVisible ? 0 : insets.bottom : insets.bottom + 10;
|
|
6114
6169
|
const totalComposerHeight = composerHeight + composerTopHeight;
|
|
6115
6170
|
const overlayBottom = totalComposerHeight + footerBottomPadding + theme.spacing.lg;
|
|
6116
6171
|
const bottomInset = totalComposerHeight + footerBottomPadding + theme.spacing.xl;
|
|
6117
|
-
const resolvedOverlay =
|
|
6172
|
+
const resolvedOverlay = React38.useMemo(() => {
|
|
6118
6173
|
var _a;
|
|
6119
6174
|
if (!overlay) return null;
|
|
6120
|
-
if (!
|
|
6175
|
+
if (!React38.isValidElement(overlay)) return overlay;
|
|
6121
6176
|
const prevStyle = (_a = overlay.props) == null ? void 0 : _a.style;
|
|
6122
|
-
return
|
|
6177
|
+
return React38.cloneElement(overlay, {
|
|
6123
6178
|
style: [prevStyle, { bottom: overlayBottom }]
|
|
6124
6179
|
});
|
|
6125
6180
|
}, [overlay, overlayBottom]);
|
|
6126
|
-
|
|
6181
|
+
React38.useEffect(() => {
|
|
6127
6182
|
if (composerTop) return;
|
|
6128
6183
|
setComposerTopHeight(0);
|
|
6129
6184
|
}, [composerTop]);
|
|
@@ -6188,15 +6243,15 @@ function ChatPage({
|
|
|
6188
6243
|
}
|
|
6189
6244
|
|
|
6190
6245
|
// src/components/chat/ScrollToBottomButton.tsx
|
|
6191
|
-
import * as
|
|
6246
|
+
import * as React39 from "react";
|
|
6192
6247
|
import { Pressable as Pressable12, View as View38 } from "react-native";
|
|
6193
6248
|
import Animated11, { Easing as Easing2, useAnimatedStyle as useAnimatedStyle2, useSharedValue as useSharedValue2, withTiming as withTiming2 } from "react-native-reanimated";
|
|
6194
6249
|
import { jsx as jsx50 } from "react/jsx-runtime";
|
|
6195
6250
|
function ScrollToBottomButton({ visible, onPress, children, style }) {
|
|
6196
6251
|
const theme = useTheme();
|
|
6197
6252
|
const progress = useSharedValue2(visible ? 1 : 0);
|
|
6198
|
-
const [pressed, setPressed] =
|
|
6199
|
-
|
|
6253
|
+
const [pressed, setPressed] = React39.useState(false);
|
|
6254
|
+
React39.useEffect(() => {
|
|
6200
6255
|
progress.value = withTiming2(visible ? 1 : 0, { duration: 200, easing: Easing2.out(Easing2.ease) });
|
|
6201
6256
|
}, [progress, visible]);
|
|
6202
6257
|
const animStyle = useAnimatedStyle2(() => ({
|
|
@@ -6331,16 +6386,16 @@ function ForkNoticeBanner({ isOwner = true, title, description, style }) {
|
|
|
6331
6386
|
}
|
|
6332
6387
|
|
|
6333
6388
|
// src/components/chat/ChatQueue.tsx
|
|
6334
|
-
import * as
|
|
6389
|
+
import * as React40 from "react";
|
|
6335
6390
|
import { ActivityIndicator as ActivityIndicator8, Pressable as Pressable13, View as View41 } from "react-native";
|
|
6336
6391
|
import { jsx as jsx53, jsxs as jsxs31 } from "react/jsx-runtime";
|
|
6337
6392
|
function ChatQueue({ items, onRemove }) {
|
|
6338
6393
|
const theme = useTheme();
|
|
6339
|
-
const [expanded, setExpanded] =
|
|
6340
|
-
const [canExpand, setCanExpand] =
|
|
6341
|
-
const [collapsedText, setCollapsedText] =
|
|
6342
|
-
const [removing, setRemoving] =
|
|
6343
|
-
const buildCollapsedText =
|
|
6394
|
+
const [expanded, setExpanded] = React40.useState({});
|
|
6395
|
+
const [canExpand, setCanExpand] = React40.useState({});
|
|
6396
|
+
const [collapsedText, setCollapsedText] = React40.useState({});
|
|
6397
|
+
const [removing, setRemoving] = React40.useState({});
|
|
6398
|
+
const buildCollapsedText = React40.useCallback((lines) => {
|
|
6344
6399
|
var _a, _b;
|
|
6345
6400
|
const line1 = ((_a = lines[0]) == null ? void 0 : _a.text) ?? "";
|
|
6346
6401
|
const line2 = ((_b = lines[1]) == null ? void 0 : _b.text) ?? "";
|
|
@@ -6356,7 +6411,7 @@ function ChatQueue({ items, onRemove }) {
|
|
|
6356
6411
|
return `${line1}
|
|
6357
6412
|
${trimmedLine2}\u2026 `;
|
|
6358
6413
|
}, []);
|
|
6359
|
-
|
|
6414
|
+
React40.useEffect(() => {
|
|
6360
6415
|
if (items.length === 0) return;
|
|
6361
6416
|
const ids = new Set(items.map((item) => item.id));
|
|
6362
6417
|
setExpanded((prev) => Object.fromEntries(Object.entries(prev).filter(([id]) => ids.has(id))));
|
|
@@ -6499,9 +6554,9 @@ function ChatPanel({
|
|
|
6499
6554
|
queueItems = [],
|
|
6500
6555
|
onRemoveQueueItem
|
|
6501
6556
|
}) {
|
|
6502
|
-
const listRef =
|
|
6503
|
-
const [nearBottom, setNearBottom] =
|
|
6504
|
-
const handleSend =
|
|
6557
|
+
const listRef = React41.useRef(null);
|
|
6558
|
+
const [nearBottom, setNearBottom] = React41.useState(true);
|
|
6559
|
+
const handleSend = React41.useCallback(
|
|
6505
6560
|
async (text, composerAttachments) => {
|
|
6506
6561
|
const all = composerAttachments ?? attachments;
|
|
6507
6562
|
await onSend(text, all.length > 0 ? all : void 0);
|
|
@@ -6515,7 +6570,7 @@ function ChatPanel({
|
|
|
6515
6570
|
},
|
|
6516
6571
|
[attachments, nearBottom, onClearAttachments, onSend]
|
|
6517
6572
|
);
|
|
6518
|
-
const handleScrollToBottom =
|
|
6573
|
+
const handleScrollToBottom = React41.useCallback(() => {
|
|
6519
6574
|
var _a;
|
|
6520
6575
|
(_a = listRef.current) == null ? void 0 : _a.scrollToBottom({ animated: true });
|
|
6521
6576
|
}, []);
|
|
@@ -6591,7 +6646,7 @@ function ChatPanel({
|
|
|
6591
6646
|
}
|
|
6592
6647
|
|
|
6593
6648
|
// src/components/dialogs/ConfirmMergeRequestDialog.tsx
|
|
6594
|
-
import * as
|
|
6649
|
+
import * as React42 from "react";
|
|
6595
6650
|
import { Pressable as Pressable15, View as View44 } from "react-native";
|
|
6596
6651
|
|
|
6597
6652
|
// src/components/primitives/Modal.tsx
|
|
@@ -6643,14 +6698,14 @@ function ConfirmMergeRequestDialog({
|
|
|
6643
6698
|
onTestFirst
|
|
6644
6699
|
}) {
|
|
6645
6700
|
const theme = useTheme();
|
|
6646
|
-
const close =
|
|
6701
|
+
const close = React42.useCallback(() => onOpenChange(false), [onOpenChange]);
|
|
6647
6702
|
const canConfirm = Boolean(mergeRequest) && !approveDisabled;
|
|
6648
|
-
const handleConfirm =
|
|
6703
|
+
const handleConfirm = React42.useCallback(() => {
|
|
6649
6704
|
if (!mergeRequest) return;
|
|
6650
6705
|
onOpenChange(false);
|
|
6651
6706
|
void onConfirm();
|
|
6652
6707
|
}, [mergeRequest, onConfirm, onOpenChange]);
|
|
6653
|
-
const handleTestFirst =
|
|
6708
|
+
const handleTestFirst = React42.useCallback(() => {
|
|
6654
6709
|
if (!mergeRequest) return;
|
|
6655
6710
|
onOpenChange(false);
|
|
6656
6711
|
void onTestFirst(mergeRequest);
|
|
@@ -6799,7 +6854,7 @@ function ConfirmMergeFlow({
|
|
|
6799
6854
|
}
|
|
6800
6855
|
|
|
6801
6856
|
// src/studio/hooks/useOptimisticChatMessages.ts
|
|
6802
|
-
import * as
|
|
6857
|
+
import * as React43 from "react";
|
|
6803
6858
|
function makeOptimisticId() {
|
|
6804
6859
|
return `optimistic:${Date.now().toString(36)}:${Math.random().toString(36).slice(2, 10)}`;
|
|
6805
6860
|
}
|
|
@@ -6838,11 +6893,11 @@ function useOptimisticChatMessages({
|
|
|
6838
6893
|
chatMessages,
|
|
6839
6894
|
onSendChat
|
|
6840
6895
|
}) {
|
|
6841
|
-
const [optimisticChat, setOptimisticChat] =
|
|
6842
|
-
|
|
6896
|
+
const [optimisticChat, setOptimisticChat] = React43.useState([]);
|
|
6897
|
+
React43.useEffect(() => {
|
|
6843
6898
|
setOptimisticChat([]);
|
|
6844
6899
|
}, [threadId]);
|
|
6845
|
-
const messages =
|
|
6900
|
+
const messages = React43.useMemo(() => {
|
|
6846
6901
|
if (!optimisticChat || optimisticChat.length === 0) return chatMessages;
|
|
6847
6902
|
const unresolved = optimisticChat.filter((o) => !isOptimisticResolvedByServer(chatMessages, o));
|
|
6848
6903
|
if (unresolved.length === 0) return chatMessages;
|
|
@@ -6858,7 +6913,7 @@ function useOptimisticChatMessages({
|
|
|
6858
6913
|
merged.sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt)));
|
|
6859
6914
|
return merged;
|
|
6860
6915
|
}, [chatMessages, optimisticChat]);
|
|
6861
|
-
|
|
6916
|
+
React43.useEffect(() => {
|
|
6862
6917
|
if (optimisticChat.length === 0) return;
|
|
6863
6918
|
setOptimisticChat((prev) => {
|
|
6864
6919
|
if (prev.length === 0) return prev;
|
|
@@ -6866,7 +6921,7 @@ function useOptimisticChatMessages({
|
|
|
6866
6921
|
return next.length === prev.length ? prev : next;
|
|
6867
6922
|
});
|
|
6868
6923
|
}, [chatMessages, optimisticChat.length]);
|
|
6869
|
-
const onSend =
|
|
6924
|
+
const onSend = React43.useCallback(
|
|
6870
6925
|
async (text, attachments) => {
|
|
6871
6926
|
if (shouldForkOnEdit || disableOptimistic) {
|
|
6872
6927
|
await onSendChat(text, attachments);
|
|
@@ -6925,15 +6980,17 @@ function StudioOverlay({
|
|
|
6925
6980
|
}) {
|
|
6926
6981
|
const theme = useTheme();
|
|
6927
6982
|
const { width } = useWindowDimensions4();
|
|
6928
|
-
const [sheetOpen, setSheetOpen] =
|
|
6929
|
-
const sheetOpenRef =
|
|
6930
|
-
const [activePage, setActivePage] =
|
|
6931
|
-
const [drawing, setDrawing] =
|
|
6932
|
-
const [chatAttachments, setChatAttachments] =
|
|
6933
|
-
const [commentsAppId, setCommentsAppId] =
|
|
6934
|
-
const [commentsCount, setCommentsCount] =
|
|
6983
|
+
const [sheetOpen, setSheetOpen] = React44.useState(false);
|
|
6984
|
+
const sheetOpenRef = React44.useRef(sheetOpen);
|
|
6985
|
+
const [activePage, setActivePage] = React44.useState("preview");
|
|
6986
|
+
const [drawing, setDrawing] = React44.useState(false);
|
|
6987
|
+
const [chatAttachments, setChatAttachments] = React44.useState([]);
|
|
6988
|
+
const [commentsAppId, setCommentsAppId] = React44.useState(null);
|
|
6989
|
+
const [commentsCount, setCommentsCount] = React44.useState(null);
|
|
6935
6990
|
const threadId = (app == null ? void 0 : app.threadId) ?? null;
|
|
6936
|
-
const
|
|
6991
|
+
const isForking = chatForking || (app == null ? void 0 : app.status) === "forking";
|
|
6992
|
+
const queueItemsForChat = isForking ? [] : chatQueueItems;
|
|
6993
|
+
const disableOptimistic = Boolean(queueItemsForChat && queueItemsForChat.length > 0) || (app == null ? void 0 : app.status) === "editing";
|
|
6937
6994
|
const optimistic = useOptimisticChatMessages({
|
|
6938
6995
|
threadId,
|
|
6939
6996
|
shouldForkOnEdit,
|
|
@@ -6941,25 +6998,25 @@ function StudioOverlay({
|
|
|
6941
6998
|
chatMessages,
|
|
6942
6999
|
onSendChat
|
|
6943
7000
|
});
|
|
6944
|
-
const [confirmMrId, setConfirmMrId] =
|
|
6945
|
-
const confirmMr =
|
|
7001
|
+
const [confirmMrId, setConfirmMrId] = React44.useState(null);
|
|
7002
|
+
const confirmMr = React44.useMemo(
|
|
6946
7003
|
() => confirmMrId ? incomingMergeRequests.find((m) => m.id === confirmMrId) ?? null : null,
|
|
6947
7004
|
[confirmMrId, incomingMergeRequests]
|
|
6948
7005
|
);
|
|
6949
|
-
const handleSheetOpenChange =
|
|
7006
|
+
const handleSheetOpenChange = React44.useCallback((open) => {
|
|
6950
7007
|
setSheetOpen(open);
|
|
6951
7008
|
if (!open) Keyboard5.dismiss();
|
|
6952
7009
|
}, []);
|
|
6953
|
-
const closeSheet =
|
|
7010
|
+
const closeSheet = React44.useCallback(() => {
|
|
6954
7011
|
handleSheetOpenChange(false);
|
|
6955
7012
|
}, [handleSheetOpenChange]);
|
|
6956
|
-
const openSheet =
|
|
6957
|
-
const goToChat =
|
|
7013
|
+
const openSheet = React44.useCallback(() => setSheetOpen(true), []);
|
|
7014
|
+
const goToChat = React44.useCallback(() => {
|
|
6958
7015
|
setActivePage("chat");
|
|
6959
7016
|
openSheet();
|
|
6960
7017
|
}, [openSheet]);
|
|
6961
|
-
const backToPreview =
|
|
6962
|
-
if (
|
|
7018
|
+
const backToPreview = React44.useCallback(() => {
|
|
7019
|
+
if (Platform11.OS !== "ios") {
|
|
6963
7020
|
Keyboard5.dismiss();
|
|
6964
7021
|
setActivePage("preview");
|
|
6965
7022
|
return;
|
|
@@ -6976,11 +7033,11 @@ function StudioOverlay({
|
|
|
6976
7033
|
const t = setTimeout(finalize, 350);
|
|
6977
7034
|
Keyboard5.dismiss();
|
|
6978
7035
|
}, []);
|
|
6979
|
-
const startDraw =
|
|
7036
|
+
const startDraw = React44.useCallback(() => {
|
|
6980
7037
|
setDrawing(true);
|
|
6981
7038
|
closeSheet();
|
|
6982
7039
|
}, [closeSheet]);
|
|
6983
|
-
const handleDrawCapture =
|
|
7040
|
+
const handleDrawCapture = React44.useCallback(
|
|
6984
7041
|
(dataUrl) => {
|
|
6985
7042
|
setChatAttachments((prev) => [...prev, dataUrl]);
|
|
6986
7043
|
setDrawing(false);
|
|
@@ -6989,7 +7046,7 @@ function StudioOverlay({
|
|
|
6989
7046
|
},
|
|
6990
7047
|
[openSheet]
|
|
6991
7048
|
);
|
|
6992
|
-
const toggleSheet =
|
|
7049
|
+
const toggleSheet = React44.useCallback(async () => {
|
|
6993
7050
|
if (!sheetOpen) {
|
|
6994
7051
|
const shouldExitTest = Boolean(testingMrId) || isTesting;
|
|
6995
7052
|
if (shouldExitTest) {
|
|
@@ -7001,7 +7058,7 @@ function StudioOverlay({
|
|
|
7001
7058
|
closeSheet();
|
|
7002
7059
|
}
|
|
7003
7060
|
}, [closeSheet, isTesting, onRestoreBase, sheetOpen, testingMrId]);
|
|
7004
|
-
const handleTestMr =
|
|
7061
|
+
const handleTestMr = React44.useCallback(
|
|
7005
7062
|
async (mr) => {
|
|
7006
7063
|
if (!onTestMr) return;
|
|
7007
7064
|
await onTestMr(mr);
|
|
@@ -7009,10 +7066,10 @@ function StudioOverlay({
|
|
|
7009
7066
|
},
|
|
7010
7067
|
[closeSheet, onTestMr]
|
|
7011
7068
|
);
|
|
7012
|
-
|
|
7069
|
+
React44.useEffect(() => {
|
|
7013
7070
|
sheetOpenRef.current = sheetOpen;
|
|
7014
7071
|
}, [sheetOpen]);
|
|
7015
|
-
|
|
7072
|
+
React44.useEffect(() => {
|
|
7016
7073
|
const poller = startStudioControlPolling((action) => {
|
|
7017
7074
|
if (action === "show" && !sheetOpenRef.current) openSheet();
|
|
7018
7075
|
if (action === "hide" && sheetOpenRef.current) closeSheet();
|
|
@@ -7020,7 +7077,7 @@ function StudioOverlay({
|
|
|
7020
7077
|
}, studioControlOptions);
|
|
7021
7078
|
return () => poller.stop();
|
|
7022
7079
|
}, [closeSheet, openSheet, studioControlOptions, toggleSheet]);
|
|
7023
|
-
|
|
7080
|
+
React44.useEffect(() => {
|
|
7024
7081
|
void publishComergeStudioUIState(sheetOpen, studioControlOptions);
|
|
7025
7082
|
}, [sheetOpen, studioControlOptions]);
|
|
7026
7083
|
return /* @__PURE__ */ jsxs35(Fragment6, { children: [
|
|
@@ -7075,7 +7132,7 @@ function StudioOverlay({
|
|
|
7075
7132
|
onNavigateHome,
|
|
7076
7133
|
onStartDraw: startDraw,
|
|
7077
7134
|
onSend: optimistic.onSend,
|
|
7078
|
-
queueItems:
|
|
7135
|
+
queueItems: queueItemsForChat,
|
|
7079
7136
|
onRemoveQueueItem
|
|
7080
7137
|
}
|
|
7081
7138
|
)
|
|
@@ -7127,7 +7184,7 @@ function StudioOverlay({
|
|
|
7127
7184
|
}
|
|
7128
7185
|
|
|
7129
7186
|
// src/studio/hooks/useEditQueue.ts
|
|
7130
|
-
import * as
|
|
7187
|
+
import * as React45 from "react";
|
|
7131
7188
|
|
|
7132
7189
|
// src/data/apps/edit-queue/remote.ts
|
|
7133
7190
|
var EditQueueRemoteDataSourceImpl = class extends BaseRemote {
|
|
@@ -7238,17 +7295,17 @@ var editQueueRepository = new EditQueueRepositoryImpl(
|
|
|
7238
7295
|
|
|
7239
7296
|
// src/studio/hooks/useEditQueue.ts
|
|
7240
7297
|
function useEditQueue(appId) {
|
|
7241
|
-
const [items, setItems] =
|
|
7242
|
-
const [loading, setLoading] =
|
|
7243
|
-
const [error, setError] =
|
|
7244
|
-
const activeRequestIdRef =
|
|
7298
|
+
const [items, setItems] = React45.useState([]);
|
|
7299
|
+
const [loading, setLoading] = React45.useState(false);
|
|
7300
|
+
const [error, setError] = React45.useState(null);
|
|
7301
|
+
const activeRequestIdRef = React45.useRef(0);
|
|
7245
7302
|
const foregroundSignal = useForegroundSignal(Boolean(appId));
|
|
7246
|
-
const upsertSorted =
|
|
7303
|
+
const upsertSorted = React45.useCallback((prev, nextItem) => {
|
|
7247
7304
|
const next = prev.some((x) => x.id === nextItem.id) ? prev.map((x) => x.id === nextItem.id ? nextItem : x) : [...prev, nextItem];
|
|
7248
7305
|
next.sort((a, b) => String(a.createdAt).localeCompare(String(b.createdAt)));
|
|
7249
7306
|
return next;
|
|
7250
7307
|
}, []);
|
|
7251
|
-
const refetch =
|
|
7308
|
+
const refetch = React45.useCallback(async () => {
|
|
7252
7309
|
if (!appId) {
|
|
7253
7310
|
setItems([]);
|
|
7254
7311
|
return;
|
|
@@ -7268,10 +7325,10 @@ function useEditQueue(appId) {
|
|
|
7268
7325
|
if (activeRequestIdRef.current === requestId) setLoading(false);
|
|
7269
7326
|
}
|
|
7270
7327
|
}, [appId]);
|
|
7271
|
-
|
|
7328
|
+
React45.useEffect(() => {
|
|
7272
7329
|
void refetch();
|
|
7273
7330
|
}, [refetch]);
|
|
7274
|
-
|
|
7331
|
+
React45.useEffect(() => {
|
|
7275
7332
|
if (!appId) return;
|
|
7276
7333
|
const unsubscribe = editQueueRepository.subscribeEditQueue(appId, {
|
|
7277
7334
|
onInsert: (item) => setItems((prev) => upsertSorted(prev, item)),
|
|
@@ -7280,7 +7337,7 @@ function useEditQueue(appId) {
|
|
|
7280
7337
|
});
|
|
7281
7338
|
return unsubscribe;
|
|
7282
7339
|
}, [appId, upsertSorted, foregroundSignal]);
|
|
7283
|
-
|
|
7340
|
+
React45.useEffect(() => {
|
|
7284
7341
|
if (!appId) return;
|
|
7285
7342
|
if (foregroundSignal <= 0) return;
|
|
7286
7343
|
void refetch();
|
|
@@ -7289,16 +7346,16 @@ function useEditQueue(appId) {
|
|
|
7289
7346
|
}
|
|
7290
7347
|
|
|
7291
7348
|
// src/studio/hooks/useEditQueueActions.ts
|
|
7292
|
-
import * as
|
|
7349
|
+
import * as React46 from "react";
|
|
7293
7350
|
function useEditQueueActions(appId) {
|
|
7294
|
-
const update =
|
|
7351
|
+
const update = React46.useCallback(
|
|
7295
7352
|
async (queueItemId, payload) => {
|
|
7296
7353
|
if (!appId) return;
|
|
7297
7354
|
await editQueueRepository.update(appId, queueItemId, payload);
|
|
7298
7355
|
},
|
|
7299
7356
|
[appId]
|
|
7300
7357
|
);
|
|
7301
|
-
const cancel =
|
|
7358
|
+
const cancel = React46.useCallback(
|
|
7302
7359
|
async (queueItemId) => {
|
|
7303
7360
|
if (!appId) return;
|
|
7304
7361
|
await editQueueRepository.cancel(appId, queueItemId);
|
|
@@ -7320,16 +7377,16 @@ function ComergeStudio({
|
|
|
7320
7377
|
studioControlOptions,
|
|
7321
7378
|
embeddedBaseBundles
|
|
7322
7379
|
}) {
|
|
7323
|
-
const [activeAppId, setActiveAppId] =
|
|
7324
|
-
const [runtimeAppId, setRuntimeAppId] =
|
|
7325
|
-
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] =
|
|
7326
|
-
const platform =
|
|
7327
|
-
|
|
7380
|
+
const [activeAppId, setActiveAppId] = React47.useState(appId);
|
|
7381
|
+
const [runtimeAppId, setRuntimeAppId] = React47.useState(appId);
|
|
7382
|
+
const [pendingRuntimeTargetAppId, setPendingRuntimeTargetAppId] = React47.useState(null);
|
|
7383
|
+
const platform = React47.useMemo(() => RNPlatform.OS === "ios" ? "ios" : "android", []);
|
|
7384
|
+
React47.useEffect(() => {
|
|
7328
7385
|
setActiveAppId(appId);
|
|
7329
7386
|
setRuntimeAppId(appId);
|
|
7330
7387
|
setPendingRuntimeTargetAppId(null);
|
|
7331
7388
|
}, [appId]);
|
|
7332
|
-
const captureTargetRef =
|
|
7389
|
+
const captureTargetRef = React47.useRef(null);
|
|
7333
7390
|
return /* @__PURE__ */ jsx59(StudioBootstrap, { clientKey: clientKey2, fallback: /* @__PURE__ */ jsx59(View46, { style: { flex: 1 } }), children: ({ userId }) => /* @__PURE__ */ jsx59(BottomSheetModalProvider, { children: /* @__PURE__ */ jsx59(LiquidGlassResetProvider, { resetTriggers: [appId, activeAppId, runtimeAppId], children: /* @__PURE__ */ jsx59(
|
|
7334
7391
|
ComergeStudioInner,
|
|
7335
7392
|
{
|
|
@@ -7371,11 +7428,11 @@ function ComergeStudioInner({
|
|
|
7371
7428
|
const { app, loading: appLoading } = useApp(activeAppId);
|
|
7372
7429
|
const { app: runtimeAppFromHook } = useApp(runtimeAppId, { enabled: runtimeAppId !== activeAppId });
|
|
7373
7430
|
const runtimeApp = runtimeAppId === activeAppId ? app : runtimeAppFromHook;
|
|
7374
|
-
const sawEditingOnPendingTargetRef =
|
|
7375
|
-
|
|
7431
|
+
const sawEditingOnPendingTargetRef = React47.useRef(false);
|
|
7432
|
+
React47.useEffect(() => {
|
|
7376
7433
|
sawEditingOnPendingTargetRef.current = false;
|
|
7377
7434
|
}, [pendingRuntimeTargetAppId]);
|
|
7378
|
-
|
|
7435
|
+
React47.useEffect(() => {
|
|
7379
7436
|
if (!pendingRuntimeTargetAppId) return;
|
|
7380
7437
|
if (activeAppId !== pendingRuntimeTargetAppId) return;
|
|
7381
7438
|
if ((app == null ? void 0 : app.status) === "editing") {
|
|
@@ -7393,13 +7450,13 @@ function ComergeStudioInner({
|
|
|
7393
7450
|
canRequestLatest: (runtimeApp == null ? void 0 : runtimeApp.status) === "ready",
|
|
7394
7451
|
embeddedBaseBundles
|
|
7395
7452
|
});
|
|
7396
|
-
const sawEditingOnActiveAppRef =
|
|
7397
|
-
const [showPostEditPreparing, setShowPostEditPreparing] =
|
|
7398
|
-
|
|
7453
|
+
const sawEditingOnActiveAppRef = React47.useRef(false);
|
|
7454
|
+
const [showPostEditPreparing, setShowPostEditPreparing] = React47.useState(false);
|
|
7455
|
+
React47.useEffect(() => {
|
|
7399
7456
|
sawEditingOnActiveAppRef.current = false;
|
|
7400
7457
|
setShowPostEditPreparing(false);
|
|
7401
7458
|
}, [activeAppId]);
|
|
7402
|
-
|
|
7459
|
+
React47.useEffect(() => {
|
|
7403
7460
|
if (!(app == null ? void 0 : app.id)) return;
|
|
7404
7461
|
if (app.status === "editing") {
|
|
7405
7462
|
sawEditingOnActiveAppRef.current = true;
|
|
@@ -7411,7 +7468,7 @@ function ComergeStudioInner({
|
|
|
7411
7468
|
sawEditingOnActiveAppRef.current = false;
|
|
7412
7469
|
}
|
|
7413
7470
|
}, [app == null ? void 0 : app.id, app == null ? void 0 : app.status]);
|
|
7414
|
-
|
|
7471
|
+
React47.useEffect(() => {
|
|
7415
7472
|
if (!showPostEditPreparing) return;
|
|
7416
7473
|
const stillProcessingBaseBundle = bundle.loading && bundle.loadingMode === "base" && !bundle.isTesting;
|
|
7417
7474
|
if (!stillProcessingBaseBundle) {
|
|
@@ -7422,19 +7479,19 @@ function ComergeStudioInner({
|
|
|
7422
7479
|
const thread = useThreadMessages(threadId);
|
|
7423
7480
|
const editQueue = useEditQueue(activeAppId);
|
|
7424
7481
|
const editQueueActions = useEditQueueActions(activeAppId);
|
|
7425
|
-
const [lastEditQueueInfo, setLastEditQueueInfo] =
|
|
7426
|
-
const lastEditQueueInfoRef =
|
|
7427
|
-
const [suppressQueueUntilResponse, setSuppressQueueUntilResponse] =
|
|
7482
|
+
const [lastEditQueueInfo, setLastEditQueueInfo] = React47.useState(null);
|
|
7483
|
+
const lastEditQueueInfoRef = React47.useRef(null);
|
|
7484
|
+
const [suppressQueueUntilResponse, setSuppressQueueUntilResponse] = React47.useState(false);
|
|
7428
7485
|
const mergeRequests = useMergeRequests({ appId: activeAppId });
|
|
7429
|
-
const hasOpenOutgoingMr =
|
|
7486
|
+
const hasOpenOutgoingMr = React47.useMemo(() => {
|
|
7430
7487
|
return mergeRequests.lists.outgoing.some((mr) => mr.status === "open");
|
|
7431
7488
|
}, [mergeRequests.lists.outgoing]);
|
|
7432
|
-
const incomingReviewMrs =
|
|
7489
|
+
const incomingReviewMrs = React47.useMemo(() => {
|
|
7433
7490
|
if (!userId) return mergeRequests.lists.incoming;
|
|
7434
7491
|
return mergeRequests.lists.incoming.filter((mr) => mr.createdBy !== userId);
|
|
7435
7492
|
}, [mergeRequests.lists.incoming, userId]);
|
|
7436
7493
|
const uploader = useAttachmentUpload();
|
|
7437
|
-
const updateLastEditQueueInfo =
|
|
7494
|
+
const updateLastEditQueueInfo = React47.useCallback(
|
|
7438
7495
|
(info) => {
|
|
7439
7496
|
lastEditQueueInfoRef.current = info;
|
|
7440
7497
|
setLastEditQueueInfo(info);
|
|
@@ -7475,20 +7532,20 @@ function ComergeStudioInner({
|
|
|
7475
7532
|
}
|
|
7476
7533
|
});
|
|
7477
7534
|
const chatSendDisabled = false;
|
|
7478
|
-
const [processingMrId, setProcessingMrId] =
|
|
7479
|
-
const [testingMrId, setTestingMrId] =
|
|
7480
|
-
const chatShowTypingIndicator =
|
|
7535
|
+
const [processingMrId, setProcessingMrId] = React47.useState(null);
|
|
7536
|
+
const [testingMrId, setTestingMrId] = React47.useState(null);
|
|
7537
|
+
const chatShowTypingIndicator = React47.useMemo(() => {
|
|
7481
7538
|
var _a;
|
|
7482
7539
|
if (!thread.raw || thread.raw.length === 0) return false;
|
|
7483
7540
|
const last = thread.raw[thread.raw.length - 1];
|
|
7484
7541
|
const payloadType = typeof ((_a = last.payload) == null ? void 0 : _a.type) === "string" ? String(last.payload.type) : void 0;
|
|
7485
7542
|
return payloadType !== "outcome";
|
|
7486
7543
|
}, [thread.raw]);
|
|
7487
|
-
|
|
7544
|
+
React47.useEffect(() => {
|
|
7488
7545
|
updateLastEditQueueInfo(null);
|
|
7489
7546
|
setSuppressQueueUntilResponse(false);
|
|
7490
7547
|
}, [activeAppId, updateLastEditQueueInfo]);
|
|
7491
|
-
|
|
7548
|
+
React47.useEffect(() => {
|
|
7492
7549
|
if (!(lastEditQueueInfo == null ? void 0 : lastEditQueueInfo.queueItemId)) return;
|
|
7493
7550
|
const stillPresent = editQueue.items.some((item) => item.id === lastEditQueueInfo.queueItemId);
|
|
7494
7551
|
if (!stillPresent) {
|
|
@@ -7496,7 +7553,7 @@ function ComergeStudioInner({
|
|
|
7496
7553
|
setSuppressQueueUntilResponse(false);
|
|
7497
7554
|
}
|
|
7498
7555
|
}, [editQueue.items, lastEditQueueInfo == null ? void 0 : lastEditQueueInfo.queueItemId]);
|
|
7499
|
-
const chatQueueItems =
|
|
7556
|
+
const chatQueueItems = React47.useMemo(() => {
|
|
7500
7557
|
var _a;
|
|
7501
7558
|
if (suppressQueueUntilResponse && editQueue.items.length <= 1) {
|
|
7502
7559
|
return [];
|