@comergehq/studio 0.1.19 → 0.1.21
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 +134 -9
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +135 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/chat/ChatMessageBubble.tsx +5 -2
- package/src/data/apps/remote.ts +9 -0
- package/src/data/apps/repository.ts +7 -0
- package/src/data/apps/types.ts +15 -0
- package/src/studio/ComergeStudio.tsx +22 -0
- package/src/studio/ui/PreviewPanel.tsx +24 -4
- package/src/studio/ui/StudioOverlay.tsx +9 -0
- package/src/studio/ui/preview-panel/PreviewCollaborateSection.tsx +95 -3
- package/src/studio/ui/preview-panel/usePreviewPanelData.ts +8 -0
package/dist/index.mjs
CHANGED
|
@@ -519,6 +519,12 @@ var AppsRemoteDataSourceImpl = class extends BaseRemote {
|
|
|
519
519
|
);
|
|
520
520
|
return data;
|
|
521
521
|
}
|
|
522
|
+
async syncUpstream(appId) {
|
|
523
|
+
const { data } = await api.post(
|
|
524
|
+
`/v1/apps/${encodeURIComponent(appId)}/sync-upstream`
|
|
525
|
+
);
|
|
526
|
+
return data;
|
|
527
|
+
}
|
|
522
528
|
};
|
|
523
529
|
var appsRemoteDataSource = new AppsRemoteDataSourceImpl();
|
|
524
530
|
|
|
@@ -597,6 +603,10 @@ var AppsRepositoryImpl = class extends BaseRepository {
|
|
|
597
603
|
const res = await this.remote.importFromGithub(payload);
|
|
598
604
|
return this.unwrapOrThrow(res);
|
|
599
605
|
}
|
|
606
|
+
async syncUpstream(appId) {
|
|
607
|
+
const res = await this.remote.syncUpstream(appId);
|
|
608
|
+
return this.unwrapOrThrow(res);
|
|
609
|
+
}
|
|
600
610
|
subscribeCreatedApps(userId, handlers) {
|
|
601
611
|
if (!userId) return () => {
|
|
602
612
|
};
|
|
@@ -4872,7 +4882,7 @@ function PreviewCustomizeSection({
|
|
|
4872
4882
|
// src/studio/ui/preview-panel/PreviewCollaborateSection.tsx
|
|
4873
4883
|
import * as React32 from "react";
|
|
4874
4884
|
import { ActivityIndicator as ActivityIndicator6, Alert, View as View32 } from "react-native";
|
|
4875
|
-
import { Send as Send2 } from "lucide-react-native";
|
|
4885
|
+
import { RefreshCw, Send as Send2 } from "lucide-react-native";
|
|
4876
4886
|
|
|
4877
4887
|
// src/components/merge-requests/MergeRequestStatusCard.tsx
|
|
4878
4888
|
import * as React28 from "react";
|
|
@@ -5417,6 +5427,9 @@ function ReviewMergeRequestCarousel({
|
|
|
5417
5427
|
import { Fragment as Fragment5, jsx as jsx44, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
5418
5428
|
function PreviewCollaborateSection({
|
|
5419
5429
|
canSubmitMergeRequest,
|
|
5430
|
+
canSyncUpstream,
|
|
5431
|
+
syncingUpstream,
|
|
5432
|
+
upstreamSyncStatus,
|
|
5420
5433
|
incomingMergeRequests,
|
|
5421
5434
|
outgoingMergeRequests,
|
|
5422
5435
|
creatorStatsById,
|
|
@@ -5425,15 +5438,18 @@ function PreviewCollaborateSection({
|
|
|
5425
5438
|
testingMrId,
|
|
5426
5439
|
toMergeRequestSummary,
|
|
5427
5440
|
onSubmitMergeRequest,
|
|
5441
|
+
onSyncUpstream,
|
|
5428
5442
|
onRequestApprove,
|
|
5429
5443
|
onReject,
|
|
5430
5444
|
onTestMr
|
|
5431
5445
|
}) {
|
|
5432
5446
|
const theme = useTheme();
|
|
5433
5447
|
const [submittingMr, setSubmittingMr] = React32.useState(false);
|
|
5434
|
-
const
|
|
5448
|
+
const [syncingLocal, setSyncingLocal] = React32.useState(false);
|
|
5449
|
+
const hasSection = canSubmitMergeRequest || canSyncUpstream || incomingMergeRequests.length > 0 || outgoingMergeRequests.length > 0;
|
|
5435
5450
|
if (!hasSection) return null;
|
|
5436
|
-
const
|
|
5451
|
+
const isSyncing = Boolean(syncingUpstream || syncingLocal);
|
|
5452
|
+
const showActionsSubtitle = canSubmitMergeRequest && onSubmitMergeRequest || canSyncUpstream && onSyncUpstream || onTestMr && incomingMergeRequests.length > 0;
|
|
5437
5453
|
return /* @__PURE__ */ jsxs25(Fragment5, { children: [
|
|
5438
5454
|
/* @__PURE__ */ jsx44(SectionTitle, { marginTop: theme.spacing.xl, children: "Collaborate" }),
|
|
5439
5455
|
showActionsSubtitle ? /* @__PURE__ */ jsx44(
|
|
@@ -5502,6 +5518,64 @@ function PreviewCollaborateSection({
|
|
|
5502
5518
|
right: /* @__PURE__ */ jsx44(Send2, { size: 16, color: "#03DAC6" })
|
|
5503
5519
|
}
|
|
5504
5520
|
) : null,
|
|
5521
|
+
canSyncUpstream && onSyncUpstream ? /* @__PURE__ */ jsx44(
|
|
5522
|
+
PressableCardRow,
|
|
5523
|
+
{
|
|
5524
|
+
accessibilityLabel: "Sync from original",
|
|
5525
|
+
disabled: isSyncing,
|
|
5526
|
+
onPress: () => {
|
|
5527
|
+
Alert.alert(
|
|
5528
|
+
"Sync from Original",
|
|
5529
|
+
"This will pull the latest upstream changes into your remix.",
|
|
5530
|
+
[
|
|
5531
|
+
{ text: "Cancel", style: "cancel" },
|
|
5532
|
+
{
|
|
5533
|
+
text: "Sync",
|
|
5534
|
+
style: "destructive",
|
|
5535
|
+
onPress: () => {
|
|
5536
|
+
setSyncingLocal(true);
|
|
5537
|
+
Promise.resolve(onSyncUpstream()).then((result) => {
|
|
5538
|
+
if ((result == null ? void 0 : result.status) === "up-to-date") {
|
|
5539
|
+
Alert.alert("Up to date", "Your remix already includes the latest upstream changes.");
|
|
5540
|
+
} else {
|
|
5541
|
+
Alert.alert("Sync started", "Upstream changes are being merged into your remix.");
|
|
5542
|
+
}
|
|
5543
|
+
}).catch(() => {
|
|
5544
|
+
Alert.alert("Sync failed", "We could not start the sync. Please try again.");
|
|
5545
|
+
}).finally(() => setSyncingLocal(false));
|
|
5546
|
+
}
|
|
5547
|
+
}
|
|
5548
|
+
]
|
|
5549
|
+
);
|
|
5550
|
+
},
|
|
5551
|
+
style: {
|
|
5552
|
+
padding: theme.spacing.lg,
|
|
5553
|
+
borderRadius: theme.radii.lg,
|
|
5554
|
+
backgroundColor: withAlpha(theme.colors.surfaceRaised, 0.5),
|
|
5555
|
+
borderWidth: 1,
|
|
5556
|
+
borderColor: withAlpha(theme.colors.primary, 0.25),
|
|
5557
|
+
marginBottom: theme.spacing.sm
|
|
5558
|
+
},
|
|
5559
|
+
left: /* @__PURE__ */ jsx44(
|
|
5560
|
+
View32,
|
|
5561
|
+
{
|
|
5562
|
+
style: {
|
|
5563
|
+
width: 40,
|
|
5564
|
+
height: 40,
|
|
5565
|
+
borderRadius: 999,
|
|
5566
|
+
alignItems: "center",
|
|
5567
|
+
justifyContent: "center",
|
|
5568
|
+
backgroundColor: withAlpha(theme.colors.primary, 0.12),
|
|
5569
|
+
marginRight: theme.spacing.lg
|
|
5570
|
+
},
|
|
5571
|
+
children: isSyncing ? /* @__PURE__ */ jsx44(ActivityIndicator6, { color: theme.colors.primary, size: "small" }) : /* @__PURE__ */ jsx44(RefreshCw, { size: 18, color: theme.colors.primary })
|
|
5572
|
+
}
|
|
5573
|
+
),
|
|
5574
|
+
title: /* @__PURE__ */ jsx44(Text, { style: { color: theme.colors.text, fontSize: 16, lineHeight: 20, fontWeight: theme.typography.fontWeight.semibold }, children: "Sync from Original" }),
|
|
5575
|
+
subtitle: /* @__PURE__ */ jsx44(Text, { style: { color: theme.colors.textMuted, fontSize: 12, lineHeight: 16, marginTop: 2 }, children: isSyncing ? "Syncing upstream changes..." : upstreamSyncStatus === "up-to-date" ? "You are already up to date with the original app" : "Pull the latest upstream changes into this remix" }),
|
|
5576
|
+
right: /* @__PURE__ */ jsx44(RefreshCw, { size: 16, color: theme.colors.primary })
|
|
5577
|
+
}
|
|
5578
|
+
) : null,
|
|
5505
5579
|
onTestMr && incomingMergeRequests.length > 0 ? /* @__PURE__ */ jsx44(
|
|
5506
5580
|
ReviewMergeRequestCarousel,
|
|
5507
5581
|
{
|
|
@@ -5809,6 +5883,12 @@ function usePreviewPanelData(params) {
|
|
|
5809
5883
|
if (app.headCommitId && app.forkedFromCommitId && app.headCommitId !== app.forkedFromCommitId) return true;
|
|
5810
5884
|
return false;
|
|
5811
5885
|
}, [app, isOwner, outgoingMergeRequests]);
|
|
5886
|
+
const canSyncUpstream = React34.useMemo(() => {
|
|
5887
|
+
if (!isOwner) return false;
|
|
5888
|
+
if (!app) return false;
|
|
5889
|
+
if (!app.forkedFromAppId) return false;
|
|
5890
|
+
return app.status === "ready";
|
|
5891
|
+
}, [app, isOwner]);
|
|
5812
5892
|
const showProcessing = app ? app.status !== "ready" : false;
|
|
5813
5893
|
return {
|
|
5814
5894
|
imageUrl,
|
|
@@ -5818,7 +5898,8 @@ function usePreviewPanelData(params) {
|
|
|
5818
5898
|
insights,
|
|
5819
5899
|
stats,
|
|
5820
5900
|
showProcessing,
|
|
5821
|
-
canSubmitMergeRequest
|
|
5901
|
+
canSubmitMergeRequest,
|
|
5902
|
+
canSyncUpstream
|
|
5822
5903
|
};
|
|
5823
5904
|
}
|
|
5824
5905
|
|
|
@@ -5841,6 +5922,9 @@ function PreviewPanel({
|
|
|
5841
5922
|
onGoToChat,
|
|
5842
5923
|
onStartDraw,
|
|
5843
5924
|
onSubmitMergeRequest,
|
|
5925
|
+
onSyncUpstream,
|
|
5926
|
+
syncingUpstream,
|
|
5927
|
+
upstreamSyncStatus,
|
|
5844
5928
|
onRequestApprove,
|
|
5845
5929
|
onReject,
|
|
5846
5930
|
onTestMr,
|
|
@@ -5850,11 +5934,11 @@ function PreviewPanel({
|
|
|
5850
5934
|
const handleShare = React35.useCallback(async () => {
|
|
5851
5935
|
if (!app || !app.isPublic) return;
|
|
5852
5936
|
const shareUrl = `https://remix.one/app/${app.id}`;
|
|
5853
|
-
const message = app.name ? `${app.name} on
|
|
5854
|
-
${shareUrl}` : `Check out this app on
|
|
5937
|
+
const message = app.name ? `${app.name} on Remix
|
|
5938
|
+
${shareUrl}` : `Check out this app on Remix
|
|
5855
5939
|
${shareUrl}`;
|
|
5856
5940
|
try {
|
|
5857
|
-
const title = app.name ?? "
|
|
5941
|
+
const title = app.name ?? "Remix app";
|
|
5858
5942
|
const payload = Platform8.OS === "ios" ? {
|
|
5859
5943
|
title,
|
|
5860
5944
|
message
|
|
@@ -5868,7 +5952,17 @@ ${shareUrl}`;
|
|
|
5868
5952
|
log.warn("PreviewPanel share failed", error);
|
|
5869
5953
|
}
|
|
5870
5954
|
}, [app]);
|
|
5871
|
-
const {
|
|
5955
|
+
const {
|
|
5956
|
+
imageUrl,
|
|
5957
|
+
imageLoaded,
|
|
5958
|
+
setImageLoaded,
|
|
5959
|
+
creator,
|
|
5960
|
+
insights,
|
|
5961
|
+
stats,
|
|
5962
|
+
showProcessing,
|
|
5963
|
+
canSubmitMergeRequest,
|
|
5964
|
+
canSyncUpstream
|
|
5965
|
+
} = usePreviewPanelData({
|
|
5872
5966
|
app,
|
|
5873
5967
|
isOwner,
|
|
5874
5968
|
outgoingMergeRequests,
|
|
@@ -5928,6 +6022,9 @@ ${shareUrl}`;
|
|
|
5928
6022
|
PreviewCollaborateSection,
|
|
5929
6023
|
{
|
|
5930
6024
|
canSubmitMergeRequest,
|
|
6025
|
+
canSyncUpstream,
|
|
6026
|
+
syncingUpstream,
|
|
6027
|
+
upstreamSyncStatus,
|
|
5931
6028
|
incomingMergeRequests,
|
|
5932
6029
|
outgoingMergeRequests,
|
|
5933
6030
|
creatorStatsById,
|
|
@@ -5936,6 +6033,7 @@ ${shareUrl}`;
|
|
|
5936
6033
|
testingMrId,
|
|
5937
6034
|
toMergeRequestSummary,
|
|
5938
6035
|
onSubmitMergeRequest,
|
|
6036
|
+
onSyncUpstream,
|
|
5939
6037
|
onRequestApprove,
|
|
5940
6038
|
onReject,
|
|
5941
6039
|
onTestMr
|
|
@@ -5970,6 +6068,8 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5970
6068
|
const isMergeApproved = metaEvent === "merge_request.approved";
|
|
5971
6069
|
const isMergeRejected = metaEvent === "merge_request.rejected";
|
|
5972
6070
|
const isMergeCompleted = metaEvent === "merge.completed";
|
|
6071
|
+
const isSyncStarted = metaEvent === "sync.started";
|
|
6072
|
+
const isSyncCompleted = metaEvent === "sync.completed";
|
|
5973
6073
|
const isHuman = message.author === "human" || isMergeApproved || isMergeRejected;
|
|
5974
6074
|
const align = { alignSelf: isHuman ? "flex-end" : "flex-start" };
|
|
5975
6075
|
const bubbleVariant = isHuman ? "surface" : "surfaceRaised";
|
|
@@ -5991,8 +6091,8 @@ function ChatMessageBubble({ message, renderContent, style }) {
|
|
|
5991
6091
|
cornerStyle
|
|
5992
6092
|
],
|
|
5993
6093
|
children: /* @__PURE__ */ jsxs27(View34, { style: { flexDirection: "row", alignItems: "center" }, children: [
|
|
5994
|
-
isMergeCompleted ? /* @__PURE__ */ jsx46(CheckCheck2, { size: 16, color: theme.colors.success, style: { marginRight: theme.spacing.sm } }) : null,
|
|
5995
|
-
isMergeApproved ? /* @__PURE__ */ jsx46(GitMerge2, { size: 16, color: theme.colors.text, style: { marginRight: theme.spacing.sm } }) : null,
|
|
6094
|
+
isMergeCompleted || isSyncCompleted ? /* @__PURE__ */ jsx46(CheckCheck2, { size: 16, color: theme.colors.success, style: { marginRight: theme.spacing.sm } }) : null,
|
|
6095
|
+
isMergeApproved || isSyncStarted ? /* @__PURE__ */ jsx46(GitMerge2, { size: 16, color: theme.colors.text, style: { marginRight: theme.spacing.sm } }) : null,
|
|
5996
6096
|
/* @__PURE__ */ jsx46(View34, { style: { flexShrink: 1, minWidth: 0 }, children: renderContent ? renderContent(message) : /* @__PURE__ */ jsx46(MarkdownText, { markdown: message.content, variant: "chat", bodyColor }) })
|
|
5997
6097
|
] })
|
|
5998
6098
|
}
|
|
@@ -6962,6 +7062,9 @@ function StudioOverlay({
|
|
|
6962
7062
|
testingMrId,
|
|
6963
7063
|
toMergeRequestSummary,
|
|
6964
7064
|
onSubmitMergeRequest,
|
|
7065
|
+
onSyncUpstream,
|
|
7066
|
+
syncingUpstream,
|
|
7067
|
+
upstreamSyncStatus,
|
|
6965
7068
|
onApprove,
|
|
6966
7069
|
onReject,
|
|
6967
7070
|
onTestMr,
|
|
@@ -7106,6 +7209,9 @@ function StudioOverlay({
|
|
|
7106
7209
|
onGoToChat: goToChat,
|
|
7107
7210
|
onStartDraw: isOwner ? startDraw : void 0,
|
|
7108
7211
|
onSubmitMergeRequest,
|
|
7212
|
+
onSyncUpstream,
|
|
7213
|
+
syncingUpstream,
|
|
7214
|
+
upstreamSyncStatus,
|
|
7109
7215
|
onRequestApprove: (mr) => setConfirmMrId(mr.id),
|
|
7110
7216
|
onReject,
|
|
7111
7217
|
onTestMr: handleTestMr,
|
|
@@ -7534,6 +7640,8 @@ function ComergeStudioInner({
|
|
|
7534
7640
|
const chatSendDisabled = false;
|
|
7535
7641
|
const [processingMrId, setProcessingMrId] = React47.useState(null);
|
|
7536
7642
|
const [testingMrId, setTestingMrId] = React47.useState(null);
|
|
7643
|
+
const [syncingUpstream, setSyncingUpstream] = React47.useState(false);
|
|
7644
|
+
const [upstreamSyncStatus, setUpstreamSyncStatus] = React47.useState(null);
|
|
7537
7645
|
const chatShowTypingIndicator = React47.useMemo(() => {
|
|
7538
7646
|
var _a;
|
|
7539
7647
|
if (!thread.raw || thread.raw.length === 0) return false;
|
|
@@ -7544,7 +7652,21 @@ function ComergeStudioInner({
|
|
|
7544
7652
|
React47.useEffect(() => {
|
|
7545
7653
|
updateLastEditQueueInfo(null);
|
|
7546
7654
|
setSuppressQueueUntilResponse(false);
|
|
7655
|
+
setUpstreamSyncStatus(null);
|
|
7547
7656
|
}, [activeAppId, updateLastEditQueueInfo]);
|
|
7657
|
+
const handleSyncUpstream = React47.useCallback(async () => {
|
|
7658
|
+
if (!(app == null ? void 0 : app.id)) {
|
|
7659
|
+
throw new Error("Missing app");
|
|
7660
|
+
}
|
|
7661
|
+
setSyncingUpstream(true);
|
|
7662
|
+
try {
|
|
7663
|
+
const result = await appsRepository.syncUpstream(activeAppId);
|
|
7664
|
+
setUpstreamSyncStatus(result.status);
|
|
7665
|
+
return result;
|
|
7666
|
+
} finally {
|
|
7667
|
+
setSyncingUpstream(false);
|
|
7668
|
+
}
|
|
7669
|
+
}, [activeAppId, app == null ? void 0 : app.id]);
|
|
7548
7670
|
React47.useEffect(() => {
|
|
7549
7671
|
if (!(lastEditQueueInfo == null ? void 0 : lastEditQueueInfo.queueItemId)) return;
|
|
7550
7672
|
const stillPresent = editQueue.items.some((item) => item.id === lastEditQueueInfo.queueItemId);
|
|
@@ -7600,6 +7722,9 @@ function ComergeStudioInner({
|
|
|
7600
7722
|
onSubmitMergeRequest: (app == null ? void 0 : app.forkedFromAppId) && actions.isOwner && !hasOpenOutgoingMr ? async () => {
|
|
7601
7723
|
await mergeRequests.actions.openMergeRequest(activeAppId);
|
|
7602
7724
|
} : void 0,
|
|
7725
|
+
onSyncUpstream: actions.isOwner && (app == null ? void 0 : app.forkedFromAppId) ? handleSyncUpstream : void 0,
|
|
7726
|
+
syncingUpstream,
|
|
7727
|
+
upstreamSyncStatus,
|
|
7603
7728
|
onApprove: async (mr) => {
|
|
7604
7729
|
if (processingMrId) return;
|
|
7605
7730
|
setProcessingMrId(mr.id);
|